-- ============================================================
-- 05_triggers.sql — Triggers métier et maintenance
-- ============================================================

-- ===========================================
-- 1. Mettre à jour automatiquement modifie_le
-- ===========================================
CREATE OR REPLACE FUNCTION set_modifie_le()
RETURNS TRIGGER AS $$
BEGIN
    NEW.modifie_le := now();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Appliquer sur les tables qui ont modifie_le
CREATE TRIGGER trg_update_modifie_le_utilisateurs
BEFORE UPDATE ON utilisateurs
FOR EACH ROW
EXECUTE FUNCTION set_modifie_le();

CREATE TRIGGER trg_update_modifie_le_dossiers
BEFORE UPDATE ON dossiers
FOR EACH ROW
EXECUTE FUNCTION set_modifie_le();

CREATE TRIGGER trg_update_modifie_le_contrats
BEFORE UPDATE ON contrats
FOR EACH ROW
EXECUTE FUNCTION set_modifie_le();

CREATE TRIGGER trg_update_modifie_le_avenants
BEFORE UPDATE ON avenants_contrats
FOR EACH ROW
EXECUTE FUNCTION set_modifie_le();

CREATE TRIGGER trg_update_modifie_le_evenements
BEFORE UPDATE ON evenements
FOR EACH ROW
EXECUTE FUNCTION set_modifie_le();

CREATE TRIGGER trg_update_modifie_le_validations
BEFORE UPDATE ON validations
FOR EACH ROW
EXECUTE FUNCTION set_modifie_le();

-- ===========================================
-- 2. Empêcher plusieurs contrats actifs par dossier
-- ===========================================
CREATE OR REPLACE FUNCTION prevent_multiple_active_contrats()
RETURNS TRIGGER AS $$
DECLARE
    nb_actifs INT;
BEGIN
    IF NEW.statut IN ('en_attente_signature','valide') THEN
        SELECT COUNT(*) INTO nb_actifs
        FROM contrats
        WHERE id_dossier = NEW.id_dossier
          AND statut IN ('en_attente_signature','valide')
          AND id <> COALESCE(NEW.id, gen_random_uuid());

        IF nb_actifs > 0 THEN
            RAISE EXCEPTION 'Un contrat actif existe déjà pour ce dossier (%).', NEW.id_dossier;
        END IF;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_one_active_contrat_per_dossier
BEFORE INSERT OR UPDATE ON contrats
FOR EACH ROW
EXECUTE FUNCTION prevent_multiple_active_contrats();

-- ===========================================
-- 3. Empêcher événements incohérents
--    - Pas de chevauchement de congés pour le même AM
-- ===========================================
CREATE OR REPLACE FUNCTION prevent_overlapping_events()
RETURNS TRIGGER AS $$
DECLARE
    nb_overlap INT;
BEGIN
    IF NEW.id_am IS NOT NULL AND NEW.date_debut IS NOT NULL AND NEW.date_fin IS NOT NULL THEN
        SELECT COUNT(*) INTO nb_overlap
        FROM evenements ev
        WHERE ev.id_am = NEW.id_am
          AND ev.id <> COALESCE(NEW.id, gen_random_uuid())
          AND ev.date_fin >= NEW.date_debut
          AND ev.date_debut <= NEW.date_fin;

        IF nb_overlap > 0 THEN
            RAISE EXCEPTION 'Conflit d''événements : chevauchement détecté pour AM %', NEW.id_am;
        END IF;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_no_overlapping_am_events
BEFORE INSERT OR UPDATE ON evenements
FOR EACH ROW
EXECUTE FUNCTION prevent_overlapping_events();
