<?php

declare(strict_types=1);

namespace App\Administration\Domain\Model\SchoolCalendar;

use App\Administration\Domain\Exception\CalendrierDatesInvalidesException;
use App\Administration\Domain\Exception\CalendrierLabelInvalideException;

use function assert;

use DateTimeImmutable;

use function mb_strlen;
use function trim;

/**
 * Value Object représentant une entrée dans le calendrier scolaire.
 *
 * Chaque entrée couvre une période (jour unique ou plage) et indique
 * un type (férié, vacances, journée pédagogique, etc.).
 */
final readonly class CalendarEntry
{
    private const int MIN_LABEL_LENGTH = 2;
    private const int MAX_LABEL_LENGTH = 100;

    /** @var non-empty-string */
    public string $label;

    public function __construct(
        public CalendarEntryId $id,
        public CalendarEntryType $type,
        public DateTimeImmutable $startDate,
        public DateTimeImmutable $endDate,
        string $label,
        public ?string $description = null,
    ) {
        if ($this->endDate < $this->startDate) {
            throw CalendrierDatesInvalidesException::finAvantDebut($this->startDate, $this->endDate);
        }

        $trimmed = trim($label);
        $length = mb_strlen($trimmed);

        if ($length < self::MIN_LABEL_LENGTH || $length > self::MAX_LABEL_LENGTH) {
            throw CalendrierLabelInvalideException::pourLongueur($label, self::MIN_LABEL_LENGTH, self::MAX_LABEL_LENGTH);
        }

        assert($trimmed !== '');
        $this->label = $trimmed;
    }

    /**
     * Vérifie si cette entrée couvre une date donnée.
     */
    public function couvre(DateTimeImmutable $date): bool
    {
        $dateStr = $date->format('Y-m-d');

        return $dateStr >= $this->startDate->format('Y-m-d')
            && $dateStr <= $this->endDate->format('Y-m-d');
    }
}
