<?php

declare(strict_types=1);

namespace App\Tests\Unit\Administration\Application\Query\HasGradesForYear;

use App\Administration\Application\Port\GradeExistenceChecker;
use App\Administration\Application\Query\HasGradesForYear\HasGradesForYearHandler;
use App\Administration\Application\Query\HasGradesForYear\HasGradesForYearQuery;
use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
use App\Administration\Domain\Model\SchoolClass\SchoolId;
use App\Shared\Domain\Tenant\TenantId;
use Override;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class HasGradesForYearHandlerTest extends TestCase
{
    private const string TENANT_ID = '550e8400-e29b-41d4-a716-446655440001';
    private const string SCHOOL_ID = '550e8400-e29b-41d4-a716-446655440002';
    private const string ACADEMIC_YEAR_ID = '550e8400-e29b-41d4-a716-446655440003';

    #[Test]
    public function itReturnsFalseWhenNoGradesExist(): void
    {
        $handler = new HasGradesForYearHandler($this->createChecker(hasGrades: false));

        $result = $handler(new HasGradesForYearQuery(
            tenantId: self::TENANT_ID,
            schoolId: self::SCHOOL_ID,
            academicYearId: self::ACADEMIC_YEAR_ID,
        ));

        self::assertFalse($result);
    }

    #[Test]
    public function itReturnsTrueWhenGradesExist(): void
    {
        $handler = new HasGradesForYearHandler($this->createChecker(hasGrades: true));

        $result = $handler(new HasGradesForYearQuery(
            tenantId: self::TENANT_ID,
            schoolId: self::SCHOOL_ID,
            academicYearId: self::ACADEMIC_YEAR_ID,
        ));

        self::assertTrue($result);
    }

    private function createChecker(bool $hasGrades): GradeExistenceChecker
    {
        return new class($hasGrades) implements GradeExistenceChecker {
            public function __construct(private bool $hasGrades)
            {
            }

            #[Override]
            public function hasGradesInPeriod(TenantId $tenantId, AcademicYearId $academicYearId, int $periodSequence): bool
            {
                return $this->hasGrades;
            }

            #[Override]
            public function hasGradesForYear(TenantId $tenantId, SchoolId $schoolId, AcademicYearId $academicYearId): bool
            {
                return $this->hasGrades;
            }
        };
    }
}
