<?php

namespace App\Providers;

use App\Enumerations\EatingHabit;
use App\Enumerations\InvoiceType;
use App\Enumerations\UserRole;
use App\Models\AvailablePaymentMethod;
use App\Models\Tenant;
use App\Models\User;
use App\Repositories\EventRepository;
use App\Repositories\PageTextRepository;
use App\Resources\AvailablePaymentMethodResource;
use App\Resources\UserResource;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class GlobalDataProvider {
    private ?User $user;

    public function __invoke() {
        $this->user = auth()->user();

        $canAccessAdmin = false;
        if (null !== $this->user) {
            $authCheck = new AuthCheckProvider();
            $effectiveRole = $authCheck->getUserRole();
            $canAccessAdmin = in_array($effectiveRole, [UserRole::USER_ROLE_ADMIN, UserRole::USER_ROLE_GROUP_LEADER], true);
        }

        return response()->json([
            'user' => null !== $this->user ? new UserResource($this->user)->toArray(request()) : null,
            'navbar' => $this->generateNavbar(),
            'tenant' => app('tenant'),
            'activeUsers' => $this->getActiveUsers(),
            'version' => config('app.version'),
            'currentEvent' => $this->getCurrentEventData(),
            'canAccessAdmin' => $canAccessAdmin,
        ]);
    }

    public function getInvoiceTypes() : JsonResponse {
        $invoiceTypes = [];
        foreach (InvoiceType::orderBy('sort_order')->get() as $invoiceType) {
            if (
                $invoiceType->slug === InvoiceType::INVOICE_TYPE_TRAVELLING
            ) {
                continue;
            }

            $invoiceTypes[] = [
                'slug' => $invoiceType->slug,
                'name' => $invoiceType->name
            ];
        }

        return response()->json([
            'invoiceTypes' => $invoiceTypes
        ]);
    }

    public function getMessages() : JsonResponse {
        $messageContainer = [
            'message' => '',
            'type' => ''
        ];

        $message = session()->get('message');

        if (null !== $message) {
            $message = session()->get('message');
            session()->forget('message');

            if('' !== $message ) {
                $messageContainer = unserialize($message);
            }
        }

        return response()->json($messageContainer);
    }

    public function getTextResourceText(string $textResource) : JsonResponse {
        $pageTextRepository = new PageTextRepository();

        return response()->json([
            'content' => $pageTextRepository->getPageText( $textResource)
        ]);
    }

    private function getCurrentEventData() : ?array {
        if (null === $this->user) {
            return null;
        }

        $currentEvent = new EventRepository()->getMyCurrentEvent();
        if (null === $currentEvent) {
            return null;
        }

        return [
            'identifier' => $currentEvent->identifier,
            'name' => $currentEvent->name,
        ];
    }

    public function getAllInvoiceTypes() : JsonResponse {
        $invoiceTypes = [];
        foreach (InvoiceType::orderBy('sort_order')->get() as $invoiceType) {
            if (
                $invoiceType->slug === InvoiceType::INVOICE_TYPE_OTHER
            ) {
                continue;
            }

            $invoiceTypes[] = [
                'slug' => $invoiceType->slug,
                'name' => $invoiceType->name
            ];
        }

        $invoiceTypes[] = ['slug' => InvoiceType::INVOICE_TYPE_OTHER, 'name' => 'Sonstige Kosten'];

        return response()->json([
            'invoiceTypes' => $invoiceTypes
        ]);
    }

    private function generateNavbar() : array {
        $eventRepository = new EventRepository();

        $navigation = [
            'personal' => [],
            'common' => [],
            'costunits' => [],
            'events' => [],
            'eventControl' => [],
        ];

        $navigation['personal'][] = ['url' => '/', 'display' => 'Home'];
        if (null !== $this->user) {
            $navigation['personal'][] = ['url' => '/personal-data', 'display' => 'Meine Daten'];
            $navigation['personal'][] = ['url' => '/messages', 'display' => 'Meine Nachrichten'];

            $authCheck = new AuthCheckProvider();
            $effectiveRole = $authCheck->getUserRole();

            if (
                in_array($effectiveRole, [UserRole::USER_ROLE_ADMIN, UserRole::USER_ROLE_GROUP_LEADER], true)
            ) {
                $navigation['costunits'][] = ['url' => '/cost-unit/list', 'display' => 'Kostenstellen'];
                $navigation['costunits'][] = ['url' => '/cost-unit/create', 'display' => 'Neue laufende Tätigkeit'];


                foreach ($eventRepository->listAll() as $event) {
                    $navigation['events'][] = ['url' => '/event/details/' . $event->identifier, 'display' => $event->name];
                }

                $navigation['eventControl'][] = ['url' => '/archived-events', 'display' => 'Archivierte Veranstaltungen'];
                $navigation['eventControl'][] = ['url' => '/create-event', 'display' => 'Neue Veranstaltung'];

            }
        }

        $navigation['common'][] = ['url' => '/invoice/new', 'display' => 'Neue Abrechnung'];
        $navigation['common'][] = ['url' => '/event/available-events', 'display' => 'Verfügbare Veranstaltungen'];

        return $navigation;
    }

    private function getActiveUsers() : array {
        $activeUsers = [];
        $conditions = ['active' => true];

        if (app('tenant')->slug !== 'lv') {
            $conditions['local_group'] = app('tenant')->slug;
        }

        foreach ($rawUsers = User::where($conditions)->get() as $user) {
            $userResource = new UserResource($user);
            $activeUsers[] = $userResource->getReducedData();
        }

        return $activeUsers;
    }

    public function getEventSettingData(Request $request) : JsonResponse {
        return response()->json(
            [
                'localGroups' => Tenant::where(['is_active_local_group' => true])->get(),
                'eatingHabits' => EatingHabit::all(),
                'paymentMethods' => AvailablePaymentMethod::where('active', true)->get()
                    ->map(fn (AvailablePaymentMethod $method) => new AvailablePaymentMethodResource($method)->toArray($request)),
            ]);
    }


}
