<?php
declare(strict_types=1);
namespace App\Models;

use App\Core\Database;
use RuntimeException;
use Throwable;

final class EnrollmentRenewal
{
    public static function context(int $organisationId,int $clientId): array
    {
        $pdo=Database::connection();
        $active=$pdo->prepare("SELECT id,libelle,date_debut,date_fin,inscriptions_ouvertes FROM annees_scolaires WHERE organisation_id=? AND active=1 ORDER BY id DESC LIMIT 1");
        $active->execute([$organisationId]);
        $year=$active->fetch()?:null;
        if(!$year)return ['year'=>null,'items'=>[]];

        $q=$pdo->prepare(
            "SELECT ic.id inscription_id,ic.participant_id membre_id,m.nom,m.prenom,
                    oldy.id source_year_id,oldy.libelle source_year,
                    a.discipline_id,d.libelle discipline_libelle,d.code discipline_code,
                    EXISTS(SELECT 1 FROM disciplines d2 WHERE d2.id=a.discipline_id AND d2.organisation_id=? AND d2.actif=1 AND d2.deleted_at IS NULL) discipline_active,
                    EXISTS(SELECT 1 FROM demandes_inscription di WHERE di.organisation_id=? AND di.membre_id=ic.participant_id AND di.discipline_id=a.discipline_id AND di.annee_scolaire_id=? AND di.statut IN('file_attente','a_etudier','creneau_propose','validee') AND di.deleted_at IS NULL) already_requested
             FROM inscriptions_cours ic
             INNER JOIN ateliers a ON a.id=ic.atelier_id
             INNER JOIN annees_scolaires oldy ON oldy.id=a.annee_scolaire_id
             INNER JOIN disciplines d ON d.id=a.discipline_id
             INNER JOIN membres_famille m ON m.id=ic.participant_id AND ic.participant_source IN('membres_famille','family_members','membre')
             INNER JOIN familles f ON f.id=m.famille_id
             WHERE ic.organisation_id=? AND f.organisation_id=? AND f.client_id=?
               AND ic.statut IN('validee','terminee') AND ic.deleted_at IS NULL AND m.deleted_at IS NULL AND f.deleted_at IS NULL
               AND oldy.id<>?
             ORDER BY oldy.date_debut DESC,m.prenom,m.nom,d.libelle"
        );
        $q->execute([$organisationId,$organisationId,(int)$year['id'],$organisationId,$organisationId,$clientId,(int)$year['id']]);
        $rows=$q->fetchAll()?:[];
        $seen=[];$items=[];
        foreach($rows as $row){
            $key=$row['membre_id'].'-'.$row['discipline_id'];
            if(isset($seen[$key]))continue;
            $seen[$key]=true;$items[]=$row;
        }
        return ['year'=>$year,'items'=>$items];
    }

    public static function submit(int $organisationId,int $clientId,array $choices,string $availability,?string $comment,int $userId): array
    {
        $ctx=self::context($organisationId,$clientId);$year=$ctx['year'];
        if(!$year)throw new RuntimeException('Aucune année scolaire active.');
        if(!(int)$year['inscriptions_ouvertes'])throw new RuntimeException('Les réinscriptions ne sont pas ouvertes pour '.$year['libelle'].'.');
        if(!$choices)throw new RuntimeException('Sélectionnez au moins une discipline à renouveler.');
        $allowed=[];foreach($ctx['items'] as $item)$allowed[(int)$item['inscription_id']]=$item;
        $pdo=Database::connection();$pdo->beginTransaction();$created=0;$skipped=0;
        try{
            foreach(array_unique(array_map('intval',$choices)) as $sourceId){
                $item=$allowed[$sourceId]??null;
                if(!$item||(int)$item['discipline_active']!==1||(int)$item['already_requested']===1){$skipped++;continue;}
                $lock=$pdo->prepare("SELECT COUNT(*) FROM demandes_inscription WHERE organisation_id=? AND membre_id=? AND discipline_id=? AND annee_scolaire_id=? AND statut IN('file_attente','a_etudier','creneau_propose','validee') AND deleted_at IS NULL FOR UPDATE");
                $lock->execute([$organisationId,(int)$item['membre_id'],(int)$item['discipline_id'],(int)$year['id']]);
                if((int)$lock->fetchColumn()>0){$skipped++;continue;}
                $text='Réinscription depuis '.$item['source_year'].'.'.($comment?' '.$comment:'');
                $ins=$pdo->prepare("INSERT INTO demandes_inscription(organisation_id,membre_id,atelier_id,discipline_id,annee_scolaire_id,adherent_id,disponibilites,commentaire_famille,instrument_loan_type,statut,created_by) VALUES(?,?,NULL,?,?,?,?,?,'none','file_attente',?)");
                $ins->execute([$organisationId,(int)$item['membre_id'],(int)$item['discipline_id'],(int)$year['id'],$clientId,$availability?:null,$text,$userId?:null]);
                $created++;
            }
            if($created===0)throw new RuntimeException('Aucune nouvelle demande créée : les disciplines sélectionnées sont déjà demandées ou indisponibles.');
            $pdo->commit();return ['created'=>$created,'skipped'=>$skipped,'year'=>$year['libelle']];
        }catch(Throwable $e){if($pdo->inTransaction())$pdo->rollBack();throw $e;}
    }
}
