<?php

declare(strict_types=1);

namespace App\Tests\Unit\Scolarite\Domain\Model\HomeworkSubmission;

use App\Scolarite\Domain\Exception\PieceJointeInvalideException;
use App\Scolarite\Domain\Model\HomeworkSubmission\SubmissionAttachment;
use App\Scolarite\Domain\Model\HomeworkSubmission\SubmissionAttachmentId;
use DateTimeImmutable;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class SubmissionAttachmentTest extends TestCase
{
    #[Test]
    #[DataProvider('validMimeTypes')]
    public function acceptsAllowedMimeTypes(string $mimeType): void
    {
        $attachment = new SubmissionAttachment(
            id: SubmissionAttachmentId::generate(),
            filename: 'test.pdf',
            filePath: 'submissions/tenant/hw/sub/test.pdf',
            fileSize: 1024,
            mimeType: $mimeType,
            uploadedAt: new DateTimeImmutable(),
        );

        self::assertSame($mimeType, $attachment->mimeType);
    }

    /** @return iterable<string, array{string}> */
    public static function validMimeTypes(): iterable
    {
        yield 'pdf' => ['application/pdf'];
        yield 'jpeg' => ['image/jpeg'];
        yield 'png' => ['image/png'];
        yield 'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
    }

    #[Test]
    public function rejectsInvalidMimeType(): void
    {
        $this->expectException(PieceJointeInvalideException::class);

        new SubmissionAttachment(
            id: SubmissionAttachmentId::generate(),
            filename: 'test.exe',
            filePath: 'submissions/tenant/hw/sub/test.exe',
            fileSize: 1024,
            mimeType: 'application/x-msdownload',
            uploadedAt: new DateTimeImmutable(),
        );
    }

    #[Test]
    public function rejectsFileTooLarge(): void
    {
        $this->expectException(PieceJointeInvalideException::class);

        new SubmissionAttachment(
            id: SubmissionAttachmentId::generate(),
            filename: 'large.pdf',
            filePath: 'submissions/tenant/hw/sub/large.pdf',
            fileSize: 11 * 1024 * 1024, // 11 Mo
            mimeType: 'application/pdf',
            uploadedAt: new DateTimeImmutable(),
        );
    }

    #[Test]
    public function acceptsFileAtMaxSize(): void
    {
        $attachment = new SubmissionAttachment(
            id: SubmissionAttachmentId::generate(),
            filename: 'max.pdf',
            filePath: 'submissions/tenant/hw/sub/max.pdf',
            fileSize: 10 * 1024 * 1024, // exactly 10 Mo
            mimeType: 'application/pdf',
            uploadedAt: new DateTimeImmutable(),
        );

        self::assertSame(10 * 1024 * 1024, $attachment->fileSize);
    }
}
