-- ====================================================================
-- V46 — Sprint 2 P1 (2026-04-25)
-- ====================================================================
-- P1-NEW-2 : Module PV OHADA (AG/CA)
-- P1-NEW-3 : Workflow demande d'aide v2 (5 étapes + plafonds)
-- P1-NEW-5 : Délégation temporaire de rôles
-- P1-NEW-13 : Registre donateurs SYCEBNL
-- P1-NEW-14 : Membres honoraires/bienfaiteurs
-- ====================================================================

-- 1. PV OHADA — table proces_verbaux
CREATE TABLE IF NOT EXISTS proces_verbaux (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID NOT NULL,

    -- Type
    type_seance VARCHAR(20) NOT NULL CHECK (type_seance IN ('AG_CONSTITUTIVE', 'AG_ORDINAIRE', 'AG_EXTRAORDINAIRE', 'CA', 'BUREAU')),
    titre VARCHAR(255) NOT NULL,
    numero_seance VARCHAR(50),

    -- Convocation
    date_convocation TIMESTAMP NOT NULL,
    mode_convocation VARCHAR(50),  -- EMAIL, COURRIER, AFFICHAGE, etc.

    -- Tenue
    date_seance TIMESTAMP NOT NULL,
    lieu VARCHAR(255),
    heure_ouverture TIME,
    heure_cloture TIME,

    -- Quorum
    nombre_convoques INTEGER NOT NULL DEFAULT 0,
    nombre_presents INTEGER NOT NULL DEFAULT 0,
    nombre_representes INTEGER NOT NULL DEFAULT 0,
    quorum_atteint BOOLEAN NOT NULL DEFAULT FALSE,
    quorum_requis_pct NUMERIC(5,2),
    quorum_calcule_pct NUMERIC(5,2),

    -- Présidence
    president_seance_id UUID,
    secretaire_seance_id UUID,
    scrutateurs_ids JSONB,  -- liste UUID

    -- Contenu
    ordre_du_jour JSONB NOT NULL,    -- liste de points: [{numero, intitule, type}]
    resolutions JSONB NOT NULL,      -- liste {numero, intitule, votesPour, votesContre, votesAbstention, adoptee}
    deliberations TEXT,              -- texte libre

    -- Signature/archivage
    statut VARCHAR(30) NOT NULL DEFAULT 'BROUILLON' CHECK (statut IN ('BROUILLON', 'ADOPTE', 'SIGNE', 'ARCHIVE')),
    hash_sha256 VARCHAR(64),         -- hash SHA-256 du contenu signé (immuabilité)
    date_signature TIMESTAMP,
    signature_president VARCHAR(500),  -- signature électronique base64
    signature_secretaire VARCHAR(500),

    -- BaseEntity
    cree_le TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    cree_par UUID,
    modifie_le TIMESTAMP,
    modifie_par UUID,
    version BIGINT NOT NULL DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

CREATE INDEX IF NOT EXISTS idx_pv_organisation ON proces_verbaux (organisation_id);
CREATE INDEX IF NOT EXISTS idx_pv_type_date ON proces_verbaux (type_seance, date_seance DESC);
CREATE INDEX IF NOT EXISTS idx_pv_statut ON proces_verbaux (statut);

COMMENT ON TABLE proces_verbaux IS
    'Procès-verbaux AG/CA conformes OHADA AUDSCGIE. '
    'Quorum auto-calculé, ordre du jour structuré, résolutions votées, signatures électroniques, '
    'archivage immuable via hash SHA-256.';

-- 2. Workflow demande d'aide v2 — extension table demandes_aide existante
-- Ajouter colonnes pour les 5 étapes : DEPOSE → ENQUETE → AVIS_COMITE → DECISION_CA → PAIE → CLOTURE
ALTER TABLE demandes_aide
    ADD COLUMN IF NOT EXISTS etape VARCHAR(30) NOT NULL DEFAULT 'DEPOSE'
        CHECK (etape IN ('DEPOSE', 'ENQUETE', 'AVIS_COMITE', 'DECISION_CA', 'PAYE', 'CLOTURE', 'REJETE'));

ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS animateur_zone_id UUID;
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS rapport_enquete_sociale TEXT;
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS date_enquete TIMESTAMP;
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS gps_enquete_lat NUMERIC(10,7);
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS gps_enquete_lon NUMERIC(10,7);
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS avis_comite_social TEXT;
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS date_avis_comite TIMESTAMP;
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS decision_ca_id UUID;       -- lien vers PV CA
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS date_decision_ca TIMESTAMP;
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS date_paie TIMESTAMP;
ALTER TABLE demandes_aide ADD COLUMN IF NOT EXISTS reference_paiement VARCHAR(100);

CREATE INDEX IF NOT EXISTS idx_demande_aide_etape ON demandes_aide (etape);
CREATE INDEX IF NOT EXISTS idx_demande_aide_animateur ON demandes_aide (animateur_zone_id) WHERE animateur_zone_id IS NOT NULL;

-- Plafonds : table types_aide (n'existait pas avant V46 — type_aide était inline VARCHAR dans demandes_aide)
CREATE TABLE IF NOT EXISTS types_aide (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID,               -- null = type global plateforme
    code VARCHAR(50) NOT NULL UNIQUE,
    libelle VARCHAR(200) NOT NULL,
    description TEXT,

    -- Plafonds (P1-NEW-3)
    plafond_annuel_membre NUMERIC(15,2),
    plafond_enveloppe_annuelle NUMERIC(15,2),
    delai_max_traitement_jours INTEGER NOT NULL DEFAULT 30,
    justificatifs_requis JSONB,         -- liste de strings

    cree_le TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    cree_par UUID,
    modifie_le TIMESTAMP,
    modifie_par UUID,
    version BIGINT NOT NULL DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

CREATE INDEX IF NOT EXISTS idx_types_aide_org ON types_aide (organisation_id) WHERE organisation_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_types_aide_code ON types_aide (code);

COMMENT ON COLUMN demandes_aide.etape IS
    '5 étapes du workflow v2 : DEPOSE → ENQUETE (animateur zone) → AVIS_COMITE (commission solidarité) '
    '→ DECISION_CA (vote PV CA) → PAYE → CLOTURE. REJETE possible à toute étape.';

-- 3. Délégation temporaire de rôles
CREATE TABLE IF NOT EXISTS role_delegations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID NOT NULL,

    delegant_user_id UUID NOT NULL,
    delegataire_user_id UUID NOT NULL,
    role_delegue VARCHAR(50) NOT NULL,

    date_debut TIMESTAMP NOT NULL,
    date_fin TIMESTAMP NOT NULL,
    motif VARCHAR(500),

    statut VARCHAR(20) NOT NULL DEFAULT 'ACTIVE'
        CHECK (statut IN ('ACTIVE', 'EXPIREE', 'REVOQUEE')),
    date_revocation TIMESTAMP,

    -- BaseEntity
    cree_le TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    cree_par UUID,
    modifie_le TIMESTAMP,
    modifie_par UUID,
    version BIGINT NOT NULL DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE,

    CHECK (date_fin > date_debut)
);

CREATE INDEX IF NOT EXISTS idx_delegation_org ON role_delegations (organisation_id);
CREATE INDEX IF NOT EXISTS idx_delegation_active
    ON role_delegations (statut, date_fin) WHERE statut = 'ACTIVE';
CREATE INDEX IF NOT EXISTS idx_delegation_delegataire ON role_delegations (delegataire_user_id);

COMMENT ON TABLE role_delegations IS
    'Délégation temporaire de rôle (ex: trésorier en congé → suppléant). '
    'Vérifié à l''exécution dans PermissionChecker (rôle effectif = rôles directs ∪ rôles délégués actifs).';

-- 4. Registre donateurs SYCEBNL (P1-NEW-13)
CREATE TABLE IF NOT EXISTS donateurs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID NOT NULL,

    type_donateur VARCHAR(20) NOT NULL
        CHECK (type_donateur IN ('PERSONNE_PHYSIQUE', 'PERSONNE_MORALE', 'ANONYME')),
    nom_prenoms VARCHAR(255),
    raison_sociale VARCHAR(255),
    pays VARCHAR(3),
    email VARCHAR(255),
    telephone VARCHAR(20),

    cree_le TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    cree_par UUID,
    modifie_le TIMESTAMP,
    modifie_par UUID,
    version BIGINT NOT NULL DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

CREATE INDEX IF NOT EXISTS idx_donateur_org ON donateurs (organisation_id);
CREATE INDEX IF NOT EXISTS idx_donateur_type ON donateurs (type_donateur);

CREATE TABLE IF NOT EXISTS dons_recus (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID NOT NULL,
    donateur_id UUID,

    type_don VARCHAR(20) NOT NULL CHECK (type_don IN ('NUMERAIRE', 'NATURE', 'BENEVOLAT', 'LEGS')),
    montant_xof NUMERIC(15,2),         -- pour NUMERAIRE
    valorisation_xof NUMERIC(15,2),    -- pour NATURE / BENEVOLAT
    description TEXT,
    date_don DATE NOT NULL,

    affectation VARCHAR(50) NOT NULL DEFAULT 'LIBRE'
        CHECK (affectation IN ('LIBRE', 'FONDS_DEDIE', 'PROJET_SPECIFIQUE')),
    fonds_dedie_id UUID,
    projet_id UUID,

    -- Reçu fiscal
    recu_emis BOOLEAN NOT NULL DEFAULT FALSE,
    numero_recu VARCHAR(50),
    date_emission_recu DATE,

    cree_le TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    cree_par UUID,
    modifie_le TIMESTAMP,
    modifie_par UUID,
    version BIGINT NOT NULL DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE,

    CONSTRAINT fk_don_donateur FOREIGN KEY (donateur_id) REFERENCES donateurs(id)
);

CREATE INDEX IF NOT EXISTS idx_don_org ON dons_recus (organisation_id);
CREATE INDEX IF NOT EXISTS idx_don_donateur ON dons_recus (donateur_id);
CREATE INDEX IF NOT EXISTS idx_don_date ON dons_recus (date_don DESC);
CREATE INDEX IF NOT EXISTS idx_don_affectation ON dons_recus (affectation);

COMMENT ON TABLE donateurs IS
    'Registre des donateurs (obligatoire SYCEBNL pour entités but non lucratif). '
    'Conservé tant que l''organisation existe + 10 ans.';

COMMENT ON TABLE dons_recus IS
    'Dons reçus (numéraire, nature, bénévolat, legs). Valorisation obligatoire pour NATURE/BENEVOLAT. '
    'Fonds dédiés (affectation = FONDS_DEDIE) tracés en classe 19 SYCEBNL.';

-- 5. Membres honoraires / bienfaiteurs (P1-NEW-14)
ALTER TABLE membres_organisations
    ADD COLUMN IF NOT EXISTS qualite_speciale VARCHAR(30)
        CHECK (qualite_speciale IS NULL OR qualite_speciale IN ('HONORAIRE', 'BIENFAITEUR', 'FONDATEUR'));

COMMENT ON COLUMN membres_organisations.qualite_speciale IS
    'Qualité spéciale du membre : HONORAIRE (droits limités, pas de vote AG), '
    'BIENFAITEUR (cotisation libre/dons), FONDATEUR (membre originel des statuts).';
