<?php

declare(strict_types=1);

namespace App\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Entity\User;
use App\Repository\EmployeeRepository;
use App\Service\WorkHours\YearlyHoursExportBuilder;
use DateTimeImmutable;
use Dompdf\Dompdf;
use Dompdf\Options;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use Twig\Environment;

class WorkHourDayExportProvider implements ProviderInterface
{
    public function __construct(
        private Environment $twig,
        private readonly RequestStack $requestStack,
        private EmployeeRepository $employeeRepository,
        private YearlyHoursExportBuilder $exportBuilder,
        private readonly Security $security,
    ) {}

    public function provide(Operation $operation, array $uriVariables = [], array $context = []): Response
    {
        $user = $this->security->getUser();
        if (!$user instanceof User) {
            throw new AccessDeniedHttpException('Authentication required.');
        }

        $request = $this->requestStack->getCurrentRequest();
        if (!$request) {
            return new Response('Missing request.', Response::HTTP_BAD_REQUEST);
        }

        $workDateRaw = (string) $request->query->get('workDate');
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $workDateRaw)) {
            throw new UnprocessableEntityHttpException('workDate must use YYYY-MM-DD format.');
        }
        $date = new DateTimeImmutable($workDateRaw);

        $siteIdsRaw = (string) $request->query->get('siteIds', '');
        $siteIds    = array_values(array_filter(array_map(
            static fn (string $value): int => (int) trim($value),
            explode(',', $siteIdsRaw),
        ), static fn (int $id): bool => $id > 0));
        if ([] === $siteIds) {
            throw new UnprocessableEntityHttpException('siteIds is required.');
        }

        // Périmètre selon le profil : admin → tous, chef de site → ses sites uniquement.
        // Les siteIds demandés ne peuvent donc pas déborder du scope de l'utilisateur.
        $employees = $this->employeeRepository->findScoped($user);

        // Regroupement par site (ordre displayOrder), non-conducteurs uniquement.
        $bySite   = [];
        $siteMeta = [];
        foreach ($employees as $employee) {
            if (true === $employee->getIsDriver()) {
                continue;
            }
            $site = $employee->getSite();
            if (null === $site || !in_array($site->getId(), $siteIds, true)) {
                continue;
            }
            $siteId            = $site->getId();
            $bySite[$siteId][] = $employee;
            $siteMeta[$siteId] ??= [
                'name'  => $site->getName(),
                'order' => $site->getDisplayOrder(),
                'color' => $site->getColor(),
            ];
        }

        uasort($siteMeta, static function (array $a, array $b): int {
            return [$a['order'], $a['name']] <=> [$b['order'], $b['name']];
        });

        $groups = [];
        $legend = [];
        foreach ($siteMeta as $siteId => $meta) {
            $siteEmployees = $bySite[$siteId];
            // Même tri que le calendrier : ordre manuel (displayOrder) puis nom, puis prénom.
            usort($siteEmployees, static function ($a, $b): int {
                return [$a->getDisplayOrder(), $a->getLastName(), $a->getFirstName()]
                    <=> [$b->getDisplayOrder(), $b->getLastName(), $b->getFirstName()];
            });

            $rows = $this->exportBuilder->buildDayRowsForEmployees($siteEmployees, $date);
            if ([] === $rows) {
                continue;
            }
            $groups[] = ['siteName' => $meta['name'], 'siteColor' => $meta['color'], 'rows' => $rows];

            // Légende : codes d'absence présents (hors férié), dédupliqués par code.
            foreach ($rows as $row) {
                if ($row['isHoliday'] || null === $row['statut'] || null === $row['statutLabel']) {
                    continue;
                }
                $legend[$row['statut']] ??= [
                    'code'  => $row['statut'],
                    'label' => $row['statutLabel'],
                    'color' => $row['statutColor'] ?? '#e8e8e8',
                ];
            }
        }
        ksort($legend);
        $legend = array_values($legend);

        $options = new Options();
        $options->set('isRemoteEnabled', true);
        $dompdf = new Dompdf($options);

        $html = $this->twig->render('work-hour-day-export/print.html.twig', [
            'groups'     => $groups,
            'legend'     => $legend,
            'dateLabel'  => $date->format('d/m/Y'),
            'exportedAt' => new DateTimeImmutable('now')->format('d/m/Y H:i'),
        ]);

        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4', 'portrait');
        $dompdf->render();

        $filename = sprintf('heures_jour_%s.pdf', $date->format('Y-m-d'));

        return new Response($dompdf->output(), Response::HTTP_OK, [
            'Content-Type'        => 'application/pdf',
            'Content-Disposition' => sprintf('attachment; filename="%s"', $filename),
        ]);
    }
}
