<?php

namespace App\Http\Controllers\Cartograhie\Filters;

use App\Helpers\Normalizer\DateNormalizer;
use CARTOGRAPHIE;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use ROLE;

class FilterController
{
    public const LIBELLE_DIRECTION = 'libelle_direction';
    public const LIBELLE_SERVICE = 'libelle_service';
    public const DOMAINE = 'domaine';
    public const DATE_DEBUT = 'date_debut';
    public const DATE_FIN = 'date_fin';

    /**
     * Vérifie si les en-têtes du client existent dans la base de données.
     *
     * @param int $id L'ID de la structure du client.
     * @return bool
     */
    public function checkIfHeadersCustomerExists($id): bool
    {
        return DB::table(CARTOGRAPHIE::CSV_CLIENT_ENTETES)
            ->where(CARTOGRAPHIE::STRUCTURE_ID, $id)
            ->exists();
    }

    /**
     * Récupère le statut des rôles de l'utilisateur actuellement authentifié.
     *
     * @return array Un tableau contenant le statut des rôles de l'utilisateur.
     */
    public function getRoleStatus(): array
    {
        $isSuperAdmin = Auth::user()->hasRole(ROLE::SUPER_ADMINISTRATEUR);
        $isAdminStructure = Auth::user()->hasRole(ROLE::ADMINISTRATEUR_STRUCTURE);

        return compact('isSuperAdmin', 'isAdminStructure');
    }

    /**
     * Récupère le statut des en-têtes du client pour l'utilisateur actuellement authentifié.
     *
     * @return array Un tableau contenant le statut des en-têtes du client.
     */
    public function getHeaderStatus(): array
    {
        $isHeadersCustomerExists = $this->checkIfHeadersCustomerExists(Auth::user()->structure_id);

        return compact('isHeadersCustomerExists');
    }

    /**
     * Fusionne et renvoie le statut des rôles et des en-têtes du client pour l'utilisateur actuellement authentifié.
     *
     * @return array Un tableau contenant le statut des rôles et des en-têtes du client.
     */
    public function getRoleAndHeaderStatus(): array
    {
        return array_merge($this->getRoleStatus(), $this->getHeaderStatus());
    }

    /**
     * Applique les filtres à une requête Eloquent en fonction des paramètres de la requête.
     *
     * @param \Illuminate\Database\Query\Builder $query La requête Eloquent à laquelle appliquer les filtres.
     * @param Request $request La requête contenant les paramètres de filtre.
     * @return \Illuminate\Database\Query\Builder La requête Eloquent avec les filtres appliqués.
     */
    public function applyFilters($query, Request $request)
    {
        $filters = $this->getFilters($request);

        $filterMap = [
            'directionSelected' => self::LIBELLE_DIRECTION,
            'serviceSelected' => self::LIBELLE_SERVICE,
            'domainSelected' => self::DOMAINE,
            'startDate' => self::DATE_DEBUT,
            'endDate' => self::DATE_FIN,
        ];

        foreach ($filterMap as $filterKey => $column) {
            if ($filterValue = $filters[$filterKey]) {
                $query = $filterKey === 'startDate' ? $query->where($column, '>=', $filterValue) : $query->where($column, '<=', $filterValue);
            }
        }

        return $query;
    }

    /**
     * Récupère les filtres à partir des paramètres de la requête et renvoie un tableau contenant ces filtres ainsi que le statut des rôles et des en-têtes du client.
     *
     * @param Request $request La requête contenant les paramètres de filtre.
     * @return array Un tableau contenant les filtres et le statut des rôles et des en-têtes du client.
     */
    public function getFilters(Request $request): array
    {
        $directionSelected = $request->input('direction_selected');
        $serviceSelected = $request->input('service_selected');
        $domainSelected = $request->input('domain_selected');
        $startDate = $request->input('start_date');
        $endDate = $request->input('end_date');

        !empty($startDate) ? $startDate = DateNormalizer::normalizeDate($startDate) : $startDate = null;

        !empty($endDate) ? $endDate = DateNormalizer::normalizeDate($endDate) : $endDate = null;

        return array_merge(
            ['directionSelected' => $directionSelected],
            ['serviceSelected' => $serviceSelected],
            ['domainSelected' => $domainSelected],
            ['startDate' => $startDate],
            ['endDate' => $endDate],
            $this->getRoleAndHeaderStatus()
        );
    }

}
