<?php

declare(strict_types=1);

namespace App\Administration\Infrastructure\Persistence\InMemory;

use App\Administration\Domain\Model\ClassAssignment\ClassAssignment;
use App\Administration\Domain\Model\ClassAssignment\ClassAssignmentId;
use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
use App\Administration\Domain\Model\SchoolClass\ClassId;
use App\Administration\Domain\Model\User\UserId;
use App\Administration\Domain\Repository\ClassAssignmentRepository;
use App\Shared\Domain\Tenant\TenantId;
use Override;

final class InMemoryClassAssignmentRepository implements ClassAssignmentRepository
{
    /** @var array<string, ClassAssignment> */
    private array $byId = [];

    #[Override]
    public function save(ClassAssignment $assignment): void
    {
        $this->byId[(string) $assignment->id] = $assignment;
    }

    #[Override]
    public function findById(ClassAssignmentId $id, TenantId $tenantId): ?ClassAssignment
    {
        $assignment = $this->byId[(string) $id] ?? null;

        if ($assignment !== null && !$assignment->tenantId->equals($tenantId)) {
            return null;
        }

        return $assignment;
    }

    #[Override]
    public function findByStudent(UserId $studentId, AcademicYearId $academicYearId, TenantId $tenantId): ?ClassAssignment
    {
        foreach ($this->byId as $assignment) {
            if (
                $assignment->studentId->equals($studentId)
                && $assignment->academicYearId->equals($academicYearId)
                && $assignment->tenantId->equals($tenantId)
            ) {
                return $assignment;
            }
        }

        return null;
    }

    #[Override]
    public function countByClass(ClassId $classId): int
    {
        $count = 0;

        foreach ($this->byId as $assignment) {
            if ($assignment->classId->equals($classId)) {
                ++$count;
            }
        }

        return $count;
    }

    #[Override]
    public function findByClass(ClassId $classId, TenantId $tenantId): array
    {
        $result = [];

        foreach ($this->byId as $assignment) {
            if ($assignment->classId->equals($classId) && $assignment->tenantId->equals($tenantId)) {
                $result[] = $assignment;
            }
        }

        return $result;
    }
}
