<?php

declare(strict_types=1);

namespace App\Tests\Service\Contracts;

use App\Entity\Contract;
use App\Entity\Employee;
use App\Enum\ContractNature;
use App\Service\Contracts\EmployeeContractChangeRequestFactory;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;

/**
 * @internal
 */
final class EmployeeContractChangeRequestFactoryTest extends TestCase
{
    public function testCreatesRequestFromEmployeePayload(): void
    {
        $factory  = new EmployeeContractChangeRequestFactory();
        $employee = $this->buildEmployee()
            ->setContractNature('CDD')
            ->setContractStartDate('2026-03-01')
            ->setContractEndDate('2026-03-10')
            ->setContractPaidLeaveSettled(true)
        ;

        $request = $factory->fromEmployee($employee);

        self::assertSame(ContractNature::CDD, $request->contractNature);
        self::assertSame('2026-03-01', $request->contractStartDate?->format('Y-m-d'));
        self::assertSame('2026-03-10', $request->contractEndDate?->format('Y-m-d'));
        self::assertTrue($request->contractPaidLeaveSettled);
        self::assertTrue($request->hasPeriodChangeRequest());
    }

    public function testThrowsOnInvalidContractNature(): void
    {
        $factory  = new EmployeeContractChangeRequestFactory();
        $employee = $this->buildEmployee()->setContractNature('XYZ');

        $this->expectException(UnprocessableEntityHttpException::class);
        $this->expectExceptionMessage('contractNature must be one of CDI, CDD, INTERIM.');
        $factory->fromEmployee($employee);
    }

    public function testThrowsOnInvalidDateFormat(): void
    {
        $factory  = new EmployeeContractChangeRequestFactory();
        $employee = $this->buildEmployee()->setContractStartDate('01/03/2026');

        $this->expectException(UnprocessableEntityHttpException::class);
        $this->expectExceptionMessage('contractStartDate must use Y-m-d format.');
        $factory->fromEmployee($employee);
    }

    private function buildEmployee(): Employee
    {
        $contract = new Contract()
            ->setName('35h')
            ->setTrackingMode(Contract::TRACKING_TIME)
            ->setWeeklyHours(35)
        ;

        return new Employee()
            ->setFirstName('Alice')
            ->setLastName('Martin')
            ->setContract($contract)
        ;
    }
}
