-- ============================================================================
-- V17 — Catégorisation des rôles + seed rôles fonctionnels et métier
-- Architecture hybride RBAC : PLATEFORME + FONCTIONNEL + METIER
-- ============================================================================

-- 1. Ajouter la colonne categorie
ALTER TABLE roles ADD COLUMN IF NOT EXISTS categorie VARCHAR(30);

-- 2. Taguer les rôles plateforme existants (seedés en V13)
UPDATE roles
SET categorie = 'PLATEFORME'
WHERE code IN ('SUPERADMIN', 'ORGADMIN', 'MODERATOR', 'ACTIVEMEMBER', 'SIMPLEMEMBER', 'VISITOR')
  AND categorie IS NULL;

-- 3. Contrainte NOT NULL après mise à jour (valeur par défaut)
ALTER TABLE roles ALTER COLUMN categorie SET DEFAULT 'FONCTIONNEL';

DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM information_schema.columns
               WHERE table_name = 'roles' AND column_name = 'categorie') THEN
        UPDATE roles SET categorie = 'FONCTIONNEL' WHERE categorie IS NULL;
    END IF;
END $$;

-- 4. Index sur categorie
CREATE INDEX IF NOT EXISTS idx_role_categorie ON roles (categorie);

-- ============================================================================
-- Rôles FONCTIONNELS — communs à toutes les organisations
-- ============================================================================
INSERT INTO roles (id, nom, code, libelle, description, niveau_hierarchique, type_role, categorie, actif, date_creation, date_modification, cree_par, modifie_par, version)
SELECT
    gen_random_uuid(), v.code, v.code, v.libelle, v.description, v.niveau_hierarchique, 'SYSTEME', 'FONCTIONNEL', true,
    NOW(), NOW(), 'system', 'system', 0
FROM (VALUES
    ('PRESIDENT',                'Président',                     'Représentant légal de l''organisation',                   15),
    ('VICE_PRESIDENT',           'Vice-Président',                'Représentant légal adjoint',                              16),
    ('SECRETAIRE',               'Secrétaire',                    'Gestion administrative et des archives',                  25),
    ('SECRETAIRE_ADJOINT',       'Secrétaire Adjoint',            'Assistant du secrétaire',                                 26),
    ('TRESORIER',                'Trésorier',                     'Gestion des finances et de la trésorerie',                25),
    ('TRESORIER_ADJOINT',        'Trésorier Adjoint',             'Assistant du trésorier',                                  26),
    ('COMMISSAIRE_COMPTES',      'Commissaire aux Comptes',       'Contrôle et audit interne des comptes',                   30),
    ('RESPONSABLE_MEMBRES',      'Responsable des Membres',       'Gestion des adhésions et des membres',                    35),
    ('RESPONSABLE_COMMUNICATION','Responsable Communication',     'Communication interne et externe',                        35),
    ('RESPONSABLE_EVENEMENTS',   'Responsable Évènements',        'Organisation des évènements et activités',                35),
    ('RESPONSABLE_TECHNIQUE',    'Responsable Technique',         'Support et outils techniques',                            35),
    ('RESPONSABLE_SOCIAL',       'Responsable Social',            'Activités solidaires et entraide',                        35)
) AS v(code, libelle, description, niveau_hierarchique)
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE roles.code = v.code);

-- ============================================================================
-- Rôles METIER — spécifiques par type d'organisation
-- ============================================================================

-- Tontine
INSERT INTO roles (id, nom, code, libelle, description, niveau_hierarchique, type_role, categorie, actif, date_creation, date_modification, cree_par, modifie_par, version)
SELECT
    gen_random_uuid(), v.code, v.code, v.libelle, v.description, v.niveau_hierarchique, 'SYSTEME', 'METIER', true,
    NOW(), NOW(), 'system', 'system', 0
FROM (VALUES
    ('TONTINE_MANAGER',         'Responsable Tontine',           'Gestion des cycles, cotisations et rotations tontine',    20),
    ('TONTINE_COLLECTOR',       'Collecteur Tontine',            'Collecte des cotisations périodiques de la tontine',      30)
) AS v(code, libelle, description, niveau_hierarchique)
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE roles.code = v.code);

-- Mutuelle / Épargne / Crédit
INSERT INTO roles (id, nom, code, libelle, description, niveau_hierarchique, type_role, categorie, actif, date_creation, date_modification, cree_par, modifie_par, version)
SELECT
    gen_random_uuid(), v.code, v.code, v.libelle, v.description, v.niveau_hierarchique, 'SYSTEME', 'METIER', true,
    NOW(), NOW(), 'system', 'system', 0
FROM (VALUES
    ('MUTUELLE_RESP',           'Responsable Mutuelle',          'Gestion des comptes épargne et demandes de crédit',       20),
    ('CREDIT_ANALYSTE',         'Analyste Crédit',               'Analyse et instruction des dossiers de crédit',           25),
    ('EPARGNE_MANAGER',         'Gestionnaire Épargne',          'Supervision des comptes et transactions épargne',         25)
) AS v(code, libelle, description, niveau_hierarchique)
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE roles.code = v.code);

-- Coopérative
INSERT INTO roles (id, nom, code, libelle, description, niveau_hierarchique, type_role, categorie, actif, date_creation, date_modification, cree_par, modifie_par, version)
SELECT
    gen_random_uuid(), v.code, v.code, v.libelle, v.description, v.niveau_hierarchique, 'SYSTEME', 'METIER', true,
    NOW(), NOW(), 'system', 'system', 0
FROM (VALUES
    ('COOP_RESP',               'Responsable Coopérative',       'Gestion des campagnes et productions agricoles',          20)
) AS v(code, libelle, description, niveau_hierarchique)
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE roles.code = v.code);

-- ONG / Association
INSERT INTO roles (id, nom, code, libelle, description, niveau_hierarchique, type_role, categorie, actif, date_creation, date_modification, cree_par, modifie_par, version)
SELECT
    gen_random_uuid(), v.code, v.code, v.libelle, v.description, v.niveau_hierarchique, 'SYSTEME', 'METIER', true,
    NOW(), NOW(), 'system', 'system', 0
FROM (VALUES
    ('ONG_RESP',                'Responsable ONG',               'Pilotage des projets et programmes ONG',                  20),
    ('PROJET_MANAGER',          'Chef de Projet',                'Gestion et suivi d''un projet spécifique',               25),
    ('DONATEUR',                'Donateur',                      'Contributeur financier externe à l''ONG',                 50)
) AS v(code, libelle, description, niveau_hierarchique)
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE roles.code = v.code);

-- Culte / Religieux
INSERT INTO roles (id, nom, code, libelle, description, niveau_hierarchique, type_role, categorie, actif, date_creation, date_modification, cree_par, modifie_par, version)
SELECT
    gen_random_uuid(), v.code, v.code, v.libelle, v.description, v.niveau_hierarchique, 'SYSTEME', 'METIER', true,
    NOW(), NOW(), 'system', 'system', 0
FROM (VALUES
    ('CULTE_RESP',              'Responsable Culte',             'Gestion des dons religieux et activités cultuelles',      20),
    ('PASTEUR',                 'Pasteur / Imam / Prêtre',       'Leader spirituel de l''organisation religieuse',          10),
    ('DIACRE',                  'Diacre / Responsable Groupe',   'Responsable d''un groupe ou d''une cellule',              30)
) AS v(code, libelle, description, niveau_hierarchique)
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE roles.code = v.code);

-- Vote / Gouvernance
INSERT INTO roles (id, nom, code, libelle, description, niveau_hierarchique, type_role, categorie, actif, date_creation, date_modification, cree_par, modifie_par, version)
SELECT
    gen_random_uuid(), v.code, v.code, v.libelle, v.description, v.niveau_hierarchique, 'SYSTEME', 'METIER', true,
    NOW(), NOW(), 'system', 'system', 0
FROM (VALUES
    ('VOTE_RESP',               'Responsable Vote',              'Administration des campagnes de vote et élections',       20),
    ('SCRUTATEUR',              'Scrutateur',                    'Dépouillement et comptage des votes',                     30)
) AS v(code, libelle, description, niveau_hierarchique)
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE roles.code = v.code);

-- Collecte de fonds
INSERT INTO roles (id, nom, code, libelle, description, niveau_hierarchique, type_role, categorie, actif, date_creation, date_modification, cree_par, modifie_par, version)
SELECT
    gen_random_uuid(), v.code, v.code, v.libelle, v.description, v.niveau_hierarchique, 'SYSTEME', 'METIER', true,
    NOW(), NOW(), 'system', 'system', 0
FROM (VALUES
    ('COLLECTE_RESP',           'Responsable Collecte',          'Gestion des campagnes de collecte de fonds',              20)
) AS v(code, libelle, description, niveau_hierarchique)
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE roles.code = v.code);

-- Registre / Professionnel
INSERT INTO roles (id, nom, code, libelle, description, niveau_hierarchique, type_role, categorie, actif, date_creation, date_modification, cree_par, modifie_par, version)
SELECT
    gen_random_uuid(), v.code, v.code, v.libelle, v.description, v.niveau_hierarchique, 'SYSTEME', 'METIER', true,
    NOW(), NOW(), 'system', 'system', 0
FROM (VALUES
    ('REGISTRE_RESP',           'Responsable Registre',          'Gestion des agréments et accréditations professionnelles', 20),
    ('CONSULTANT',              'Consultant',                    'Accès lecture étendu pour analyse et conseil',             45),
    ('GESTIONNAIRE_RH',         'Gestionnaire RH',               'Gestion des ressources humaines de l''organisation',      30)
) AS v(code, libelle, description, niveau_hierarchique)
WHERE NOT EXISTS (SELECT 1 FROM roles WHERE roles.code = v.code);
