-- ============================================================================
-- V28 — Messagerie temps réel entre membres
--
-- Crée les tables nécessaires pour la messagerie instantanée :
--   - contact_policies   : politique de communication par organisation
--   - member_blocks      : blocages unilatéraux entre membres
--   - conversations      : fil de discussion (directe ou canal-rôle)
--   - conversation_participants : membres d'une conversation
--   - messages           : messages texte, vocal ou image
--
-- Les notes vocales sont stockées comme messages de type VOCAL avec
-- url_fichier + duree_audio. Aucune transcription en V1.
--
-- Auteur : UnionFlow Team
-- Version : 4.0
-- Date : 2026-04-13
-- ============================================================================

-- ── Politique de communication par organisation ───────────────────────────────
CREATE TABLE IF NOT EXISTS contact_policies (
    id                          UUID        NOT NULL PRIMARY KEY,
    date_creation               TIMESTAMP   NOT NULL,
    date_modification           TIMESTAMP,
    cree_par                    VARCHAR(255),
    modifie_par                 VARCHAR(255),
    version                     BIGINT,
    actif                       BOOLEAN     NOT NULL DEFAULT TRUE,

    organisation_id             UUID        NOT NULL REFERENCES organisations(id),
    type_politique              VARCHAR(30) NOT NULL DEFAULT 'OUVERT',
    autoriser_membre_vers_membre BOOLEAN    NOT NULL DEFAULT TRUE,
    autoriser_membre_vers_role   BOOLEAN    NOT NULL DEFAULT TRUE,
    autoriser_notes_vocales      BOOLEAN    NOT NULL DEFAULT TRUE,

    CONSTRAINT uk_contact_policy_org UNIQUE (organisation_id)
);

-- ── Blocages unilatéraux ──────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS member_blocks (
    id                  UUID        NOT NULL PRIMARY KEY,
    date_creation       TIMESTAMP   NOT NULL,
    date_modification   TIMESTAMP,
    cree_par            VARCHAR(255),
    modifie_par         VARCHAR(255),
    version             BIGINT,
    actif               BOOLEAN     NOT NULL DEFAULT TRUE,

    bloqueur_id         UUID        NOT NULL REFERENCES utilisateurs(id),
    bloque_id           UUID        NOT NULL REFERENCES utilisateurs(id),
    organisation_id     UUID        NOT NULL REFERENCES organisations(id),

    CONSTRAINT uk_member_block UNIQUE (bloqueur_id, bloque_id, organisation_id),
    CONSTRAINT chk_block_self CHECK (bloqueur_id <> bloque_id)
);

-- ── Conversations ─────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS conversations (
    id                  UUID        NOT NULL PRIMARY KEY,
    date_creation       TIMESTAMP   NOT NULL,
    date_modification   TIMESTAMP,
    cree_par            VARCHAR(255),
    modifie_par         VARCHAR(255),
    version             BIGINT,
    actif               BOOLEAN     NOT NULL DEFAULT TRUE,

    organisation_id     UUID        NOT NULL REFERENCES organisations(id),
    -- DIRECTE | ROLE_CANAL | GROUPE
    type_conversation   VARCHAR(30) NOT NULL,
    -- Pour ROLE_CANAL : PRESIDENT, TRESORIER, SECRETAIRE, etc.
    role_cible          VARCHAR(50),
    -- Titre affiché (nom du rôle ou du groupe)
    titre               VARCHAR(200),
    -- ACTIVE | ARCHIVEE
    statut              VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
    dernier_message_at  TIMESTAMP,
    nombre_messages     INTEGER     NOT NULL DEFAULT 0
);

-- ── Participants aux conversations ────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS conversation_participants (
    id                      UUID        NOT NULL PRIMARY KEY,
    date_creation           TIMESTAMP   NOT NULL,
    date_modification       TIMESTAMP,
    cree_par                VARCHAR(255),
    modifie_par             VARCHAR(255),
    version                 BIGINT,
    actif                   BOOLEAN     NOT NULL DEFAULT TRUE,

    conversation_id         UUID        NOT NULL REFERENCES conversations(id),
    membre_id               UUID        NOT NULL REFERENCES utilisateurs(id),
    -- INITIATEUR | PARTICIPANT | MODERATEUR
    role_dans_conversation  VARCHAR(50) DEFAULT 'PARTICIPANT',
    -- Dernier message lu par ce participant
    lu_jusqu_a              TIMESTAMP,
    notifier                BOOLEAN     NOT NULL DEFAULT TRUE,

    CONSTRAINT uk_conv_participant UNIQUE (conversation_id, membre_id)
);

-- ── Messages ──────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS messages (
    id                  UUID        NOT NULL PRIMARY KEY,
    date_creation       TIMESTAMP   NOT NULL,
    date_modification   TIMESTAMP,
    cree_par            VARCHAR(255),
    modifie_par         VARCHAR(255),
    version             BIGINT,
    actif               BOOLEAN     NOT NULL DEFAULT TRUE,

    conversation_id     UUID        NOT NULL REFERENCES conversations(id),
    expediteur_id       UUID        NOT NULL REFERENCES utilisateurs(id),
    -- TEXTE | VOCAL | IMAGE | SYSTEME
    type_message        VARCHAR(20) NOT NULL DEFAULT 'TEXTE',
    -- Contenu textuel (null pour les vocaux/images)
    contenu             TEXT,
    -- URL du fichier audio ou image (stocké sur object storage)
    url_fichier         VARCHAR(500),
    -- Durée en secondes pour les notes vocales
    duree_audio         INTEGER,
    -- Transcription automatique V2 (null en V1)
    transcription       TEXT,
    -- Réponse à un message (threading léger)
    message_parent_id   UUID        REFERENCES messages(id),
    -- Suppression douce (null = non supprimé)
    supprime_le         TIMESTAMP
);

-- ── Ajout colonnes v4 manquantes sur tables existantes ───────────────────────
-- (les tables ont pu être créées par une migration antérieure avec le schéma v1)
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversations' AND column_name = 'type_conversation') THEN
        ALTER TABLE conversations ADD COLUMN type_conversation VARCHAR(30) NOT NULL DEFAULT 'DIRECTE';
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversations' AND column_name = 'role_cible') THEN
        ALTER TABLE conversations ADD COLUMN role_cible VARCHAR(50);
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversations' AND column_name = 'titre') THEN
        ALTER TABLE conversations ADD COLUMN titre VARCHAR(200);
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversations' AND column_name = 'statut') THEN
        ALTER TABLE conversations ADD COLUMN statut VARCHAR(20) NOT NULL DEFAULT 'ACTIVE';
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversations' AND column_name = 'dernier_message_at') THEN
        ALTER TABLE conversations ADD COLUMN dernier_message_at TIMESTAMP;
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversations' AND column_name = 'nombre_messages') THEN
        ALTER TABLE conversations ADD COLUMN nombre_messages INTEGER NOT NULL DEFAULT 0;
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversations' AND column_name = 'organisation_id') THEN
        ALTER TABLE conversations ADD COLUMN organisation_id UUID REFERENCES organisations(id);
    END IF;
    -- Messages : colonnes FK v4 (nécessaires pour les index)
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'messages' AND column_name = 'conversation_id') THEN
        ALTER TABLE messages ADD COLUMN conversation_id UUID REFERENCES conversations(id);
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'messages' AND column_name = 'expediteur_id') THEN
        ALTER TABLE messages ADD COLUMN expediteur_id UUID REFERENCES utilisateurs(id);
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'messages' AND column_name = 'message_parent_id') THEN
        ALTER TABLE messages ADD COLUMN message_parent_id UUID REFERENCES messages(id);
    END IF;
    -- Messages : colonnes métier v4
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'messages' AND column_name = 'type_message') THEN
        ALTER TABLE messages ADD COLUMN type_message VARCHAR(20) NOT NULL DEFAULT 'TEXTE';
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'messages' AND column_name = 'contenu') THEN
        ALTER TABLE messages ADD COLUMN contenu TEXT;
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'messages' AND column_name = 'url_fichier') THEN
        ALTER TABLE messages ADD COLUMN url_fichier VARCHAR(500);
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'messages' AND column_name = 'duree_audio') THEN
        ALTER TABLE messages ADD COLUMN duree_audio INTEGER;
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'messages' AND column_name = 'transcription') THEN
        ALTER TABLE messages ADD COLUMN transcription TEXT;
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'messages' AND column_name = 'supprime_le') THEN
        ALTER TABLE messages ADD COLUMN supprime_le TIMESTAMP;
    END IF;
    -- ConversationParticipants : colonnes FK v4
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversation_participants' AND column_name = 'conversation_id') THEN
        ALTER TABLE conversation_participants ADD COLUMN conversation_id UUID REFERENCES conversations(id);
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversation_participants' AND column_name = 'membre_id') THEN
        ALTER TABLE conversation_participants ADD COLUMN membre_id UUID REFERENCES utilisateurs(id);
    END IF;
    -- ConversationParticipants : colonnes métier v4
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversation_participants' AND column_name = 'role_dans_conversation') THEN
        ALTER TABLE conversation_participants ADD COLUMN role_dans_conversation VARCHAR(50) DEFAULT 'PARTICIPANT';
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversation_participants' AND column_name = 'lu_jusqu_a') THEN
        ALTER TABLE conversation_participants ADD COLUMN lu_jusqu_a TIMESTAMP;
    END IF;
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_name = 'conversation_participants' AND column_name = 'notifier') THEN
        ALTER TABLE conversation_participants ADD COLUMN notifier BOOLEAN NOT NULL DEFAULT TRUE;
    END IF;
END $$;

-- ── Index de performance ──────────────────────────────────────────────────────
CREATE INDEX IF NOT EXISTS idx_conversations_organisation ON conversations(organisation_id);
CREATE INDEX IF NOT EXISTS idx_conversations_statut       ON conversations(statut);
CREATE INDEX IF NOT EXISTS idx_conversations_dernier_msg  ON conversations(dernier_message_at DESC NULLS LAST);

CREATE INDEX IF NOT EXISTS idx_conv_part_conversation ON conversation_participants(conversation_id);
CREATE INDEX IF NOT EXISTS idx_conv_part_membre       ON conversation_participants(membre_id);

CREATE INDEX IF NOT EXISTS idx_messages_conversation ON messages(conversation_id);
CREATE INDEX IF NOT EXISTS idx_messages_expediteur   ON messages(expediteur_id);
CREATE INDEX IF NOT EXISTS idx_messages_date_creation ON messages(date_creation DESC);
CREATE INDEX IF NOT EXISTS idx_messages_parent       ON messages(message_parent_id);

CREATE INDEX IF NOT EXISTS idx_contact_policies_org  ON contact_policies(organisation_id);
CREATE INDEX IF NOT EXISTS idx_member_blocks_bloqueur ON member_blocks(bloqueur_id);
CREATE INDEX IF NOT EXISTS idx_member_blocks_bloque   ON member_blocks(bloque_id, organisation_id);
