<?php

declare(strict_types=1);

namespace App\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\ApiResource\EmployeeOvertimeContingent;
use App\Entity\Employee;
use App\Repository\EmployeeRepository;
use App\Repository\EmployeeRttPaymentRepository;
use App\Service\WorkHours\OvertimePaidContingentCalculator;
use App\Service\WorkHours\StructuralOvertimeContingentCalculator;
use DateTimeImmutable;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;

final readonly class EmployeeOvertimeContingentProvider implements ProviderInterface
{
    public function __construct(
        private RequestStack $requestStack,
        private EmployeeRttPaymentRepository $rttPaymentRepository,
        private OvertimePaidContingentCalculator $calculator,
        private StructuralOvertimeContingentCalculator $structuralCalculator,
        private EmployeeRepository $employeeRepository,
    ) {}

    public function provide(Operation $operation, array $uriVariables = [], array $context = []): EmployeeOvertimeContingent
    {
        $employeeId = (int) ($uriVariables['id'] ?? 0);
        if ($employeeId <= 0) {
            throw new UnprocessableEntityHttpException('id must be a positive integer.');
        }

        $employee = $this->employeeRepository->find($employeeId);
        if (!$employee instanceof Employee) {
            throw new NotFoundHttpException('Employee not found.');
        }

        $request = $this->requestStack->getCurrentRequest();
        $year    = (int) $request?->query->get('year', (string) (int) new DateTimeImmutable('now')->format('Y'));
        if ($year < 2000 || $year > 2100) {
            throw new UnprocessableEntityHttpException('year must be between 2000 and 2100.');
        }

        // Année civile Y = exercice Y (mois 1-5) + exercice Y+1 (mois 6-12).
        $payments = array_merge(
            $this->rttPaymentRepository->findByEmployeeAndYear($employee, $year),
            $this->rttPaymentRepository->findByEmployeeAndYear($employee, $year + 1),
        );

        $output              = new EmployeeOvertimeContingent();
        $output->year        = $year;
        $output->paidMinutes = $this->calculator->totalBaseMinutes($payments, $year)
            + $this->structuralCalculator->totalStructuralMinutes($employee, $year);
        $output->isDriver = $employee->getIsDriver();
        $output->capHours = $this->calculator->capHours($output->isDriver);

        return $output;
    }
}
