<?php

declare(strict_types=1);

namespace App\Scolarite\Domain\Service;

use App\Scolarite\Domain\Model\GradingMode;
use InvalidArgumentException;

/**
 * Value Object contenant les pondérations du Score Sérénité adaptées au mode de notation.
 *
 * Standard : Notes×0.4 + Absences×0.3 + Devoirs×0.3
 * Sans notes : Absences×0.5 + Devoirs×0.5 (composante notes exclue)
 * Compétences : même pondération, mais les notes sont converties via le mapping Acquis→100, En cours→50, Non acquis→0
 */
final readonly class SerenityScoreWeights
{
    private const array COMPETENCY_MAPPING = [
        'acquired' => 100,
        'in_progress' => 50,
        'not_acquired' => 0,
    ];

    private function __construct(
        public float $notesWeight,
        public float $absencesWeight,
        public float $devoirsWeight,
        private bool $usesCompetencyMapping,
    ) {
    }

    public static function forMode(GradingMode $mode): self
    {
        return match ($mode) {
            GradingMode::NO_GRADES => new self(
                notesWeight: 0.0,
                absencesWeight: 0.5,
                devoirsWeight: 0.5,
                usesCompetencyMapping: false,
            ),
            GradingMode::COMPETENCIES => new self(
                notesWeight: 0.4,
                absencesWeight: 0.3,
                devoirsWeight: 0.3,
                usesCompetencyMapping: true,
            ),
            default => new self(
                notesWeight: 0.4,
                absencesWeight: 0.3,
                devoirsWeight: 0.3,
                usesCompetencyMapping: false,
            ),
        };
    }

    /**
     * Convertit un niveau de compétence en score numérique (0-100).
     *
     * @return int|null Score numérique, ou null si le mode n'utilise pas le mapping compétences
     */
    public function competencyToScore(string $competencyLevel): ?int
    {
        if (!$this->usesCompetencyMapping) {
            return null;
        }

        return self::COMPETENCY_MAPPING[$competencyLevel]
            ?? throw new InvalidArgumentException("Niveau de compétence inconnu : '{$competencyLevel}'");
    }
}
