<?php

namespace App\Libs\Services;

use App\Models\Document;
use App\Models\GenericBackoffice\WebsiteObject;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;

class SearchService
{
    public function search(string $q, string $lang, int $page = 1, int $perPage = 7, array $filters = []) {
        $escapedQuery = fulltext_search_term($q, false, false);

        $query = WebsiteObject::join('website_objects_search', 'website_objects_search.website_object_id', '=', 'website_objects.website_object_id')
            ->join('website_objects_lang', 'website_objects_lang.website_object_id', '=', 'website_objects.website_object_id')
            ->whereRaw("MATCH(website_objects_search.search_content) AGAINST (? IN BOOLEAN MODE)", [$escapedQuery])
            ->where('website_objects_search.language_id', $lang)
            ->where('website_objects_lang.wo_language_id', $lang)
            ->where('website_objects.status', 'published')
            ->select('website_objects.*', 'website_objects_search.id', 'website_objects_search.title', 'website_objects_search.search_content', 'website_objects_lang.lang_uri', 'website_objects_lang.lang_slug')
            ->orderByRaw("MATCH(website_objects_search.search_content) AGAINST (? IN BOOLEAN MODE) desc", [$escapedQuery]);

        $query->where('website_objects.content_type', 'documents');

        $this->_addDocumentFilters($query, $filters);

        // return $query->paginate($perPage, ['*'], 'page', $page);
        return $query->limit($perPage)->get();
    }

    protected function _addDocumentFilters(Builder $query, array $filters)
    {
        $userData = Auth::user();

        $hasLegalOpinionsPermission = $userData->member->user_permission_level
            ? $userData->legal_opinion_permission
            : $userData->member->legal_opinions;

        $hasFinanceSubCommitteePermission = $userData->finance_sub_committee_permission;

        $query->whereHasMorph(
            'objectable',
            [Document::class],
            function (Builder $query) use ($userData, $filters, $hasLegalOpinionsPermission, $hasFinanceSubCommitteePermission) {
                $query->where(function ($query) {
                        $query->whereNull('publish_date')
                            ->orWhereDate('publish_date', '<=', now()->tz('Europe/Berlin'));
                    })->where(function ($query) {
                        $query->whereNull('expiration_date')
                            ->orWhereDate('expiration_date', '>', now()->tz('Europe/Berlin'));
                    })
                    ->join('committees', 'committees.id', 'documents.committee_id')
                    ->where(function ($query) use ($userData, $hasLegalOpinionsPermission, $hasFinanceSubCommitteePermission) {
                        $query->where('committees.type', 'standard');

                        if ($userData->member->legal_committee) {
                            $query->orWhere('committees.type', 'legalCommittee');
                        }

                        if ($hasLegalOpinionsPermission) {
                            $query->orWhere('committees.type', 'legalOpinions');
                        }

                        if ($hasFinanceSubCommitteePermission) {
                            $query->orWhere('committees.type', 'financeSubCommittee');
                        }
                    });

                if (!empty($filters['dateStart'])) {
                    $query->where(function($query) use ($filters) {
                        $query->whereDate('publish_date', '>=', $filters['dateStart'])
                            ->orWhereNull('publish_date');
                    });
                }

                if (!empty($filters['dateEnd'])) {
                    $query->where(function($query) use ($filters) {
                        $query->whereDate('publish_date', '<', $filters['dateEnd'])
                            ->orWhereNull('publish_date');
                    });
                }
            }
        );
    }

    public function searchAutoComplete(string $q, string $lang, int $perPage = 7) {
        $escapedQuery = fulltext_search_term($q, false, true);

        $query = WebsiteObject::join('website_objects_search', 'website_objects_search.website_object_id', '=', 'website_objects.website_object_id')
            ->join('website_objects_lang', 'website_objects_lang.website_object_id', '=', 'website_objects.website_object_id')
            ->whereRaw("MATCH(website_objects_search.search_content) AGAINST (? IN BOOLEAN MODE)", [$escapedQuery])
            ->where('website_objects_search.language_id', $lang)
            ->where('website_objects_lang.wo_language_id', $lang)
            ->where('website_objects.status', 'published')
            ->select('website_objects.*', 'website_objects_search.id', 'website_objects_search.title', 'website_objects_search.search_content', 'website_objects_lang.lang_uri', 'website_objects_lang.lang_slug')
            ->orderByRaw("MATCH(website_objects_search.search_content) AGAINST (? IN BOOLEAN MODE) desc", [$escapedQuery]);

            $query->where('website_objects.content_type', 'documents');
            $this->_addDocumentFilters($query, []);

        return $query->limit($perPage)->get();
    }
}
