<?php

declare(strict_types=1);

namespace App\Service\WorkHours;

use App\Dto\WorkHours\OvertimeContingentRow;
use App\Entity\Employee;
use App\Repository\EmployeeRttPaymentRepository;

/**
 * Construit, par employé, les heures supp payées (base, hors bonus) ventilées
 * par mois civil pour l'année civile demandée, le total et le plafond légal.
 */
final readonly class OvertimeContingentExportBuilder
{
    public function __construct(
        private EmployeeRttPaymentRepository $rttPaymentRepository,
        private OvertimePaidContingentCalculator $calculator,
        private StructuralOvertimeContingentCalculator $structuralCalculator,
    ) {}

    /**
     * @param list<Employee> $employees
     *
     * @return list<OvertimeContingentRow>
     */
    public function buildRows(array $employees, int $civilYear): array
    {
        // Année civile Y = exercice Y (mois 1-5) + exercice Y+1 (mois 6-12).
        $payments = $this->rttPaymentRepository->findByEmployeesAndYears(
            $employees,
            [$civilYear, $civilYear + 1],
        );

        $byEmployee = [];
        foreach ($payments as $payment) {
            $employeeId = $payment->getEmployee()?->getId();
            if (null === $employeeId) {
                continue;
            }
            $byEmployee[$employeeId][] = $payment;
        }

        $rows = [];
        foreach ($employees as $employee) {
            $employeeId = $employee->getId();
            if (null === $employeeId) {
                continue;
            }

            $employeePayments = $byEmployee[$employeeId] ?? [];
            $paidMonths       = $this->calculator->monthlyBaseMinutes($employeePayments, $civilYear);
            $structuralMonths = $this->structuralCalculator->monthlyStructuralMinutes($employee, $civilYear);

            $months = [];
            for ($m = 1; $m <= 12; ++$m) {
                $months[$m] = $paidMonths[$m] + $structuralMonths[$m];
            }

            $rows[] = new OvertimeContingentRow(
                employeeId: $employeeId,
                employeeName: trim($employee->getLastName().' '.$employee->getFirstName()),
                months: $months,
                totalMinutes: array_sum($months),
                capHours: $this->calculator->capHours($employee->getIsDriver()),
            );
        }

        return $rows;
    }
}
