<?php

namespace App\Models;

use App\Libs\Facades\Localization;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use App\Models\Entry;
use App\Models\Language;

class Website extends BaseModel
{
    public function languages()
    {
        return $this->belongsToMany(Language::class, 'website_language')->withPivot(array("is_default", 'is_active', 'position', 'generate_translation'));
    }

    public function backendUsers()
    {
        return $this->belongsToMany(BackendUser::class)->withPivot("is_default")->withTimestamps();
    }


    public function menus()
    {
        return $this->hasMany(Menu::class);
    }

    public function visitors()
    {
        return $this->hasMany(Visitor::class);
    }

    public function objects()
    {
        return $this->hasMany(WebsiteObject::class);
    }

    public function getDefaultLanguage()
    {
        $this->languages;
        $language = $this->languages->filter(function ($languageData) {
            return $languageData->pivot->is_default == 1;
        })->first();
        return $language;
    }


    public function getEntry($entryId)
    {
        $website = $this;
        return Entry::whereHas('websites', function ($query) use ($website, $entryId) {
            $query->where('website_id', $website->id)
                ->where('object_id', $entryId)
                ->where('object_type', "Entry");
        })->first();
    }

    public function getVisitorByToken($token)
    {
        $visitor = Visitor::where('website_id', $this->id)
            ->whereExists(function ($query) use ($token) {
                $query->select(DB::raw(1))
                    ->from('visitor_tokens')
                    ->whereRaw('visitor_tokens.visitor_id = visitors.id')
                    ->where('token', $token);
            })->first();

        return $visitor;
    }

    public function hasSlug($slug, $langId)
    {
        $count = WebsiteObjectLanguage::where('lang_slug', $slug)
            ->where('wo_website_id', $this->id)
            ->where('wo_language_id', $langId)
            ->count();

        return $count > 0;
    }

    public function hasLanguage($lang)
    {
        foreach ($this->languages as $language) {
            if ($language->id == $lang) {
                return true;
            }
        }
        return false;
    }

    public function languageIsActive($lang)
    {
        foreach ($this->languages as $language) {
            if ($language->id == $lang) {
                return $language->pivot->is_active;
            }
        }
        return false;
    }

    public function searchCount($phrase, $languageId = false, $groups = false)
    {
        if (empty($languageId)) {
            $languageId = Localization::getActiveLocale();
        }

        $searchTerms = fulltext_search_term($phrase, false);

        $query = DB::table("website_object_search")
            ->whereRaw("MATCH(primary_search, secondary_search)
                        AGAINST (? IN BOOLEAN MODE)", array($searchTerms))
            ->where("website_id", $this->id)
            ->where("language_id", $languageId);

        if ($groups) {
            if (!is_array($groups)) {
                $groups = array($groups);
            }
            $query->whereIn("content_type", $groups);
        }
        return $query->count();
    }

    public function getSearchGroups($groupName)
    {
        switch ($groupName) {
            case 'resources':
                return array('page', 'publication', 'client');
            case 'news':
                return array('news', 'event_item', 'press_release', 'blog_post');
            case 'clients':
                return array('case_study', 'sector');
            case 'solutions':
                return array('solution');
            case 'projects':
                return array('project');
        }
        return false;
    }

    public function search(
        $phrase,
        $languageId = false,
        $groups = null,
        $grouping = false,
        $numberRows = 20,
        $page = null
    ) {
        if (empty($languageId)) {
            $languageId = Localization::getActiveLocale();
        }

        $searchTerms = fulltext_search_term($phrase, false);

        $query = DB::table("website_object_search")
            ->whereRaw("MATCH(primary_search, secondary_search)
                    AGAINST (? IN BOOLEAN MODE)", array($searchTerms))
            ->where("website_id", $this->id)
            ->where("language_id", $languageId)
            ->orderByRaw("MATCH (primary_search)
                    AGAINST (? IN BOOLEAN MODE) * 2 +
                    MATCH (secondary_search)
                    AGAINST (? IN BOOLEAN MODE) desc", array($searchTerms, $searchTerms))
            ->select("title", "content", "group_label", "uri", "content_type", "image_id");

        if ($groups) {
            if (!is_array($groups)) {
                $groups = array($groups);
            }
            $query->whereIn("content_type", $groups);
        }

        if (!empty($numberRows)) {
            $query->take($numberRows);
        }

        if (!empty($page) && !empty($numberRows)) {
            $skip = ($page - 1) * $numberRows;
            $query->skip($skip);
        }


        $records = $query->get()->toArray();


        $imageIds = array_map(function ($value) {
            return $value->image_id;
        }, $records);
        $imageIds = array_unique($imageIds);
        $imageIds = Arr::where($imageIds, function ($value, $key) {
            return !is_null($value);
        });

        $mediaItems = array();

        if (!empty($imageIds)) {
            $mediaItems = MediaItem::whereIn("id", $imageIds)->pluck("filename", "id")->all();
        }

        foreach ($records as $record) {
            if (!empty($record->image_id) && isset($mediaItems[$record->image_id])) {
                $record->image = getMediaUrl($mediaItems[$record->image_id], "200x200");
            }
            unset($record->image_id);
        }

        $results = array();

        if ($grouping) {
            foreach ($records as $record) {
                if (!isset($results[$record->content_type])) {
                    $results[$record->content_type] = array(
                        "label" => $record->group_label,
                        "list" => array()
                    );
                }
                $results[$record->content_type]["list"][] = $record;
            }
        } else {
            $results = $records;
        }

        if (!empty($page) && !empty($numberRows)) {
            $totalRecords = DB::table("website_object_search")
                ->whereRaw("MATCH(primary_search, secondary_search)
                        AGAINST (? IN BOOLEAN MODE)", array($searchTerms))
                ->where("website_id", $this->id)
                ->where("language_id", $languageId)
                ->count();

            return array(
                "totalRecords" => $totalRecords,
                "records" => $results
            );
        } else {
            return $results;
        }


    }

}
