<?php

declare(strict_types=1);

namespace App\Administration\Domain\Repository;

use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
use App\Administration\Domain\Model\SchoolClass\ClassId;
use App\Administration\Domain\Model\Subject\SubjectId;
use App\Administration\Domain\Model\TeacherAssignment\TeacherAssignment;
use App\Administration\Domain\Model\TeacherAssignment\TeacherAssignmentId;
use App\Administration\Domain\Model\User\UserId;
use App\Shared\Domain\Tenant\TenantId;

interface TeacherAssignmentRepository
{
    public function save(TeacherAssignment $assignment): void;

    /**
     * @throws \App\Administration\Domain\Exception\AffectationNotFoundException
     */
    public function get(TeacherAssignmentId $id, TenantId $tenantId): TeacherAssignment;

    public function findById(TeacherAssignmentId $id, TenantId $tenantId): ?TeacherAssignment;

    /**
     * Vérifie si une affectation active existe déjà pour ce triplet enseignant × classe × matière.
     */
    public function findByTeacherClassSubject(
        UserId $teacherId,
        ClassId $classId,
        SubjectId $subjectId,
        AcademicYearId $academicYearId,
        TenantId $tenantId,
    ): ?TeacherAssignment;

    /**
     * Recherche une affectation retirée pour ce triplet enseignant × classe × matière.
     *
     * Utilisé pour réactiver une affectation au lieu d'en créer une nouvelle,
     * évitant ainsi une violation de la contrainte d'unicité.
     */
    public function findRemovedByTeacherClassSubject(
        UserId $teacherId,
        ClassId $classId,
        SubjectId $subjectId,
        AcademicYearId $academicYearId,
        TenantId $tenantId,
    ): ?TeacherAssignment;

    /**
     * Retourne toutes les affectations actives d'un enseignant.
     *
     * @return TeacherAssignment[]
     */
    public function findActiveByTeacher(
        UserId $teacherId,
        TenantId $tenantId,
    ): array;

    /**
     * Retourne tous les enseignants affectés à une classe.
     *
     * @return TeacherAssignment[]
     */
    public function findActiveByClass(
        ClassId $classId,
        TenantId $tenantId,
    ): array;

    /**
     * Retourne toutes les affectations actives d'un tenant.
     *
     * @return TeacherAssignment[]
     */
    public function findAllActiveByTenant(TenantId $tenantId): array;
}
