<?php

declare(strict_types=1);

namespace App\Tests\State;

use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Post;
use ApiPlatform\State\ProcessorInterface;
use App\Entity\Employee;
use App\Entity\EmployeeWeekComment;
use App\Service\AuditLogger;
use App\State\EmployeeWeekCommentWriteProcessor;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\UnitOfWork;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;

/**
 * @internal
 */
final class EmployeeWeekCommentWriteProcessorTest extends TestCase
{
    public function testRejectsNonMondayWeekStart(): void
    {
        $processor = new EmployeeWeekCommentWriteProcessor(
            $this->createStub(ProcessorInterface::class),
            $this->createStub(ProcessorInterface::class),
            $this->createStub(EntityManagerInterface::class),
            $this->createStub(AuditLogger::class),
        );

        $comment = new EmployeeWeekComment()
            ->setEmployee(new Employee()->setFirstName('A')->setLastName('B'))
            ->setWeekStartDate(new DateTimeImmutable('2026-04-14'))
            ->setContent('test')
        ;

        $this->expectException(UnprocessableEntityHttpException::class);
        $processor->process($comment, new Post());
    }

    public function testAcceptsMondayAndAuditsCreate(): void
    {
        $persist = $this->createMock(ProcessorInterface::class);
        $persist->expects(self::once())->method('process');
        $em = $this->createMock(EntityManagerInterface::class);
        $em->method('getUnitOfWork')->willReturn($this->createStub(UnitOfWork::class));
        $em->expects(self::once())->method('flush');
        $auditor = $this->createMock(AuditLogger::class);
        $auditor->expects(self::once())->method('log')->with(self::anything(), 'create', 'week_comment');

        $processor = new EmployeeWeekCommentWriteProcessor($persist, $this->createStub(ProcessorInterface::class), $em, $auditor);
        $processor->process(
            new EmployeeWeekComment()->setEmployee(new Employee()->setFirstName('A')->setLastName('B'))->setWeekStartDate(new DateTimeImmutable('2026-04-13'))->setContent('x'),
            new Post()
        );
    }

    public function testDeleteAudits(): void
    {
        $remove = $this->createMock(ProcessorInterface::class);
        $remove->expects(self::once())->method('process');
        $em = $this->createMock(EntityManagerInterface::class);
        $em->expects(self::once())->method('flush');
        $auditor = $this->createMock(AuditLogger::class);
        $auditor->expects(self::once())->method('log')->with(self::anything(), 'delete', 'week_comment');

        $processor = new EmployeeWeekCommentWriteProcessor($this->createStub(ProcessorInterface::class), $remove, $em, $auditor);
        $processor->process(
            new EmployeeWeekComment()->setEmployee(new Employee()->setFirstName('A')->setLastName('B'))->setWeekStartDate(new DateTimeImmutable('2026-04-13'))->setContent('x'),
            new Delete()
        );
    }
}
