<?php

namespace App\Libs\Services;

use App\Models\Meeting;
use Illuminate\Support\Facades\Auth;

class MeetingService {
    public function list(array $searchData): array {
        $orderDir = $searchData['orderDir'] ? $searchData['orderDir'] : 'asc';
        $userData = Auth::user();

        $query = Meeting::full()
            ->where('status', 'published');

        if ((!empty($searchData['userFlag']) && $searchData['userFlag'])) {
            $query->where(function ($query) use ($userData) {
                $query->where('type', 'general_meeting');

                if ($userData->committees) {
                    $query->orWhereIn('committee_id', $userData->committees->pluck('id'));
                }

                if ($userData->workGroups) {
                    $query->orWhereIn('work_group_id', $userData->workGroups->pluck('id'));
                }
            });
        }

        if((!empty($searchData['nextMeetings']) && $searchData['nextMeetings'])
            || (!empty($searchData['pastMeetings']) && $searchData['pastMeetings'])
        ) {
            if (!empty($searchData['nextMeetings']) && $searchData['nextMeetings']) {
                $query->where(function ($query) { // next meetings and ongoing
                    $query->where('start_date', '>=', now())
                        ->orWhere('end_date', '>=', now());
                });
            } else if (!empty($searchData['pastMeetings']) && $searchData['pastMeetings']) {
                $query->where(function ($query) { // past meetings
                    $query->where('start_date', '<', now())
                        ->orWhere('end_date', '<', now());
                });
            }
        } else {
            if ($searchData['committeeId']) {
                $query->where('committee_id', $searchData['committeeId']);
            } else if ($searchData['workGroupId']) {
                $query->where('work_group_id', $searchData['workGroupId']);
            }
        }

        if (!empty($searchData['nextMeetings']) && $searchData['nextMeetings']) {
            $query->orderBy('start_date', 'asc');
        } else if (!empty($searchData['pastMeetings']) && $searchData['pastMeetings']) {
                $query->orderBy('start_date', 'desc');
        } else {
            switch ($searchData['orderBy']) {
                case 'date':
                    $query->orderBy('start_date', $orderDir);
                    break;
                default:
                    # title
                    $query->orderBy('title', $orderDir);
                    break;
            }
        }

        $perPage = $searchData['perPage'] ?? 12;
        $page = $searchData['page'] ?? 1;

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

        $hasFinanceSubCommitteePermission = $userData->finance_sub_committee_permission;

        $query->with([
            'agenda',
            'documentLists' => function ($query) use ($userData, $hasLegalOpinionsPermission, $hasFinanceSubCommitteePermission) {
                $query
                    ->full()
                    ->with(['documents' => function ($query) use ($userData, $hasLegalOpinionsPermission, $hasFinanceSubCommitteePermission) {
                        $query->full()
                            ->where('status', 'published')
                            ->where(function ($query) {
                                $query->whereNull('publish_date')
                                    ->orWhere('publish_date', '<=', now()->tz('Europe/Berlin'));
                            })->where(function ($query) {
                                $query->whereNull('expiration_date')
                                    ->orWhere('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');
                                }
                            })
                            ->orderBy('publish_date', 'desc');
                    }])
                    ->orderBy('pivot_position', 'asc');
            }
        ]);

        $meetings = $query->paginate($perPage, ['*'], 'page', $page);

        $paginationData = [
            'currentPage' =>  intval($meetings->currentPage()),
            'lastPage' => intval($meetings->lastPage()),
            'perPage' =>  intval($meetings->perPage()),
            'total' =>  intval($meetings->total()),
            'count' =>  intval($meetings->count()),
            'hasMorePages' => $meetings->hasMorePages(),
            'nextPageUrl' => $meetings->nextPageUrl(),
            'prevPageUrl' => $meetings->previousPageUrl(),
        ];

        return [
            'meetings' => $meetings,
            'pagination' => $paginationData,
        ];
    }

    public function findBySlug(string $slug): ?Meeting {
        $query = Meeting::full()
            ->where('status', 'published')
            ->where('lang_slug', $slug);

        $userData = Auth::user();

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

        $hasFinanceSubCommitteePermission = $userData->finance_sub_committee_permission;

        $query->with([
            'agenda',
            'documentLists' => function ($query) use ($userData, $hasLegalOpinionsPermission, $hasFinanceSubCommitteePermission) {
                $query
                    ->full()
                    ->where('status', 'published')
                    ->with(['documents' => function ($query) use ($userData, $hasLegalOpinionsPermission, $hasFinanceSubCommitteePermission) {
                        $query->full()
                            ->where('status', 'published')
                            ->where(function ($query) {
                                $query->whereNull('publish_date')
                                    ->orWhere('publish_date', '<=', now()->tz('Europe/Berlin'));
                            })->where(function ($query) {
                                $query->whereNull('expiration_date')
                                    ->orWhere('expiration_date', '>', now()->tz('Europe/Berlin'));
                            })
                            ->join('committees', 'committees.id', 'documents.committee_id')
                            ->where(function ($query) use ($userData, $hasLegalOpinionsPermission, $hasFinanceSubCommitteePermission) {
                                if ($userData->member->member_type !== 'noType') {
                                    $query->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');
                                        }
                                    });
                                } else {
                                    $query->where('committees.type', 'legalOpinions');
                                }
                            })
                            ->orderBy('publish_date', 'desc');
                    }])
                    ->orderBy('pivot_position', 'asc');
            }
        ]);

        return $query->first();
    }
}
