<?php

declare(strict_types=1);

namespace App\Scolarite\Domain\Model\Schedule;

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

/**
 * Représentation résolue d'un créneau pour une date donnée.
 *
 * Combine le créneau template (récurrent) avec ses éventuelles exceptions
 * pour donner l'état réel du cours à une date précise.
 */
final readonly class ResolvedScheduleSlot
{
    public function __construct(
        public ScheduleSlotId $slotId,
        public TenantId $tenantId,
        public ClassId $classId,
        public SubjectId $subjectId,
        public UserId $teacherId,
        public DayOfWeek $dayOfWeek,
        public TimeSlot $timeSlot,
        public ?string $room,
        public DateTimeImmutable $date,
        public bool $isModified,
        public ?ScheduleExceptionId $exceptionId,
    ) {
    }

    /**
     * Crée un créneau résolu à partir du template (pas d'exception).
     */
    public static function fromSlot(ScheduleSlot $slot, DateTimeImmutable $date): self
    {
        return new self(
            slotId: $slot->id,
            tenantId: $slot->tenantId,
            classId: $slot->classId,
            subjectId: $slot->subjectId,
            teacherId: $slot->teacherId,
            dayOfWeek: $slot->dayOfWeek,
            timeSlot: $slot->timeSlot,
            room: $slot->room,
            date: $date,
            isModified: false,
            exceptionId: null,
        );
    }

    /**
     * Crée un créneau résolu avec une exception (modification ponctuelle).
     */
    public static function fromSlotWithException(
        ScheduleSlot $slot,
        ScheduleException $exception,
    ): self {
        return new self(
            slotId: $slot->id,
            tenantId: $slot->tenantId,
            classId: $slot->classId,
            subjectId: $slot->subjectId,
            teacherId: $exception->newTeacherId ?? $slot->teacherId,
            dayOfWeek: $slot->dayOfWeek,
            timeSlot: $exception->newTimeSlot ?? $slot->timeSlot,
            room: $exception->newRoom ?? $slot->room,
            date: $exception->exceptionDate,
            isModified: true,
            exceptionId: $exception->id,
        );
    }
}
