-- Script de migration vers le schéma le plus récent avec liens courts
-- À exécuter dans votre base de données Supabase

-- ========================================
-- ÉTAPE 1: Ajout des colonnes manquantes
-- ========================================

-- Ajouter la colonne slug aux campagnes si elle n'existe pas
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'campaigns' AND column_name = 'slug'
    ) THEN
        ALTER TABLE campaigns ADD COLUMN slug TEXT UNIQUE;
        RAISE NOTICE 'Colonne slug ajoutée à la table campaigns';
    ELSE
        RAISE NOTICE 'Colonne slug existe déjà dans la table campaigns';
    END IF;
END $$;

-- Ajouter la colonne short_id aux participants si elle n'existe pas
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'participants' AND column_name = 'short_id'
    ) THEN
        ALTER TABLE participants ADD COLUMN short_id TEXT UNIQUE;
        RAISE NOTICE 'Colonne short_id ajoutée à la table participants';
    ELSE
        RAISE NOTICE 'Colonne short_id existe déjà dans la table participants';
    END IF;
END $$;

-- ========================================
-- ÉTAPE 2: Création des fonctions utilitaires
-- ========================================

-- Fonction pour générer un slug à partir d'un titre
CREATE OR REPLACE FUNCTION generate_slug(title TEXT)
RETURNS TEXT AS $$
DECLARE
    generated_slug TEXT;
    counter INTEGER := 0;
    base_slug TEXT;
BEGIN
    -- Convertir en minuscules et remplacer les caractères spéciaux
    base_slug := lower(regexp_replace(title, '[^a-zA-Z0-9\s]', '', 'g'));
    base_slug := regexp_replace(base_slug, '\s+', '-', 'g');
    base_slug := trim(both '-' from base_slug);
    
    -- Si le slug est vide, utiliser 'campagne'
    IF base_slug = '' THEN
        base_slug := 'campagne';
    END IF;
    
    generated_slug := base_slug;
    
    -- Vérifier si le slug existe déjà et ajouter un numéro si nécessaire
    WHILE EXISTS (SELECT 1 FROM campaigns WHERE campaigns.slug = generated_slug) LOOP
        counter := counter + 1;
        generated_slug := base_slug || '-' || counter;
    END LOOP;
    
    RETURN generated_slug;
END;
$$ LANGUAGE plpgsql;

-- Fonction pour générer un short_id unique
CREATE OR REPLACE FUNCTION generate_short_id()
RETURNS TEXT AS $$
DECLARE
    chars TEXT := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    result TEXT := '';
    i INTEGER;
    generated_short_id TEXT;
    counter INTEGER := 0;
BEGIN
    LOOP
        -- Générer un identifiant de 6 caractères
        result := '';
        FOR i IN 1..6 LOOP
            result := result || substr(chars, floor(random() * length(chars))::integer + 1, 1);
        END LOOP;
        
        generated_short_id := result;
        
        -- Vérifier si le short_id existe déjà
        IF NOT EXISTS (SELECT 1 FROM participants WHERE participants.short_id = generated_short_id) THEN
            RETURN generated_short_id;
        END IF;
        
        -- Éviter les boucles infinies
        counter := counter + 1;
        IF counter > 100 THEN
            RAISE EXCEPTION 'Impossible de générer un short_id unique après 100 tentatives';
        END IF;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

-- ========================================
-- ÉTAPE 3: Mise à jour des données existantes
-- ========================================

-- Générer des slugs pour les campagnes qui n'en ont pas
UPDATE campaigns 
SET slug = generate_slug(title)
WHERE slug IS NULL;

-- Générer des short_ids pour les participants qui n'en ont pas
UPDATE participants 
SET short_id = generate_short_id()
WHERE short_id IS NULL;

-- ========================================
-- ÉTAPE 4: Création des index manquants
-- ========================================

-- Index pour les slugs de campagnes
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_indexes 
        WHERE indexname = 'idx_campaigns_slug'
    ) THEN
        CREATE INDEX idx_campaigns_slug ON campaigns(slug);
        RAISE NOTICE 'Index idx_campaigns_slug créé';
    ELSE
        RAISE NOTICE 'Index idx_campaigns_slug existe déjà';
    END IF;
END $$;

-- Index pour les short_ids de participants
DO $$ 
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_indexes 
        WHERE indexname = 'idx_participants_short_id'
    ) THEN
        CREATE INDEX idx_participants_short_id ON participants(short_id);
        RAISE NOTICE 'Index idx_participants_short_id créé';
    ELSE
        RAISE NOTICE 'Index idx_participants_short_id existe déjà';
    END IF;
END $$;

-- ========================================
-- ÉTAPE 5: Fonction pour remplacer les votes
-- ========================================

-- Fonction pour remplacer tous les votes d'un participant de manière atomique
CREATE OR REPLACE FUNCTION replace_participant_votes(
    p_campaign_id UUID,
    p_participant_id UUID,
    p_votes JSONB
)
RETURNS VOID AS $$
DECLARE
    vote_record RECORD;
BEGIN
    -- Commencer une transaction
    BEGIN
        -- Supprimer tous les votes existants pour ce participant dans cette campagne
        DELETE FROM votes 
        WHERE campaign_id = p_campaign_id 
        AND participant_id = p_participant_id;
        
        -- Insérer les nouveaux votes
        FOR vote_record IN 
            SELECT * FROM jsonb_array_elements(p_votes)
        LOOP
            INSERT INTO votes (campaign_id, participant_id, proposition_id, amount)
            VALUES (
                p_campaign_id,
                p_participant_id,
                (vote_record.value->>'proposition_id')::UUID,
                (vote_record.value->>'amount')::INTEGER
            );
        END LOOP;
        
        -- La transaction sera automatiquement commitée si tout va bien
    EXCEPTION
        WHEN OTHERS THEN
            -- En cas d'erreur, la transaction sera automatiquement rollbackée
            RAISE EXCEPTION 'Erreur lors du remplacement des votes: %', SQLERRM;
    END;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- ========================================
-- ÉTAPE 6: Vérification et rapport
-- ========================================

-- Afficher un rapport de la migration
DO $$
DECLARE
    campaign_count INTEGER;
    participant_count INTEGER;
    campaign_with_slug INTEGER;
    participant_with_short_id INTEGER;
BEGIN
    -- Compter les campagnes
    SELECT COUNT(*) INTO campaign_count FROM campaigns;
    SELECT COUNT(*) INTO campaign_with_slug FROM campaigns WHERE slug IS NOT NULL;
    
    -- Compter les participants
    SELECT COUNT(*) INTO participant_count FROM participants;
    SELECT COUNT(*) INTO participant_with_short_id FROM participants WHERE short_id IS NOT NULL;
    
    RAISE NOTICE '=== RAPPORT DE MIGRATION ===';
    RAISE NOTICE 'Campagnes totales: %', campaign_count;
    RAISE NOTICE 'Campagnes avec slug: %', campaign_with_slug;
    RAISE NOTICE 'Participants totaux: %', participant_count;
    RAISE NOTICE 'Participants avec short_id: %', participant_with_short_id;
    
    IF campaign_count = campaign_with_slug AND participant_count = participant_with_short_id THEN
        RAISE NOTICE '✅ Migration réussie ! Toutes les données ont été migrées.';
    ELSE
        RAISE NOTICE '⚠️  Attention: Certaines données n''ont pas été migrées.';
    END IF;
END $$;
