-- Migration: 070_fix_users_user_roles_uuid.sql
-- Description: Finalisation de la migration UUID pour users et user_roles + Création federated_identities
-- Context: Lab Environment (Destructive changes authorized)

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";

-- =================================================================
-- 1. NETTOYAGE ET MIGRATION TABLE USERS
-- =================================================================

-- On commence par supprimer la PK 'users_pkey' en CASCADE.
-- Cela va supprimer toutes les Foreign Keys (FK) qui pointaient vers l'ancien users.id (bigint).
-- C'est la méthode "Clean Slate" pour le lab.
ALTER TABLE users DROP CONSTRAINT IF EXISTS users_pkey CASCADE;

-- Si la colonne id_uuid n'existe pas (cas où migration rejouée ou etat bizarre), on s'assure d'en avoir une
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'id_uuid') THEN
        ALTER TABLE users ADD COLUMN id_uuid UUID DEFAULT gen_random_uuid();
    END IF;
END $$;

-- On s'assure que tout le monde a un UUID
UPDATE users SET id_uuid = gen_random_uuid() WHERE id_uuid IS NULL;

-- Suppression de l'ancien ID (BigInt)
ALTER TABLE users DROP COLUMN IF EXISTS id;

-- Renommage id_uuid -> id
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'id_uuid') THEN
        ALTER TABLE users RENAME COLUMN id_uuid TO id;
    END IF;
END $$;

-- Définition de la nouvelle Primary Key UUID
ALTER TABLE users ADD PRIMARY KEY (id);

-- =================================================================
-- 2. RÉPARATION DES TABLES ENFANTS (Int -> UUID)
-- =================================================================
-- Pour ces tables, on supprime l'ancienne colonne user_id (int) et on la recrée en UUID.
-- Comme c'est un lab sans data, on ne cherche pas à migrer la valeur int.

DO $$
DECLARE
    tables_to_fix text[] := ARRAY[
        'email_verification_tokens',
        'password_reset_tokens',
        'sessions',
        'user_sessions',
        'track_plays',
        'track_history',
        'bitrate_adaptation_logs',
        'playback_analytics'
    ];
    tbl text;
BEGIN
    FOREACH tbl IN ARRAY tables_to_fix LOOP
        IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = tbl) THEN
            -- Supprimer l'ancienne colonne (et ses contraintes résiduelles si cascade a raté)
            EXECUTE 'ALTER TABLE ' || quote_ident(tbl) || ' DROP COLUMN IF EXISTS user_id CASCADE';
            
            -- Créer la nouvelle colonne
            EXECUTE 'ALTER TABLE ' || quote_ident(tbl) || ' ADD COLUMN user_id UUID NOT NULL';
            
            -- Ajouter la FK
            EXECUTE 'ALTER TABLE ' || quote_ident(tbl) || ' ADD CONSTRAINT fk_' || tbl || '_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE';
            
            RAISE NOTICE 'Table % : user_id migré en UUID', tbl;
        END IF;
    END LOOP;
END $$;

-- Cas spécifique : Rooms (creator_id ou owner_id selon versions)
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'rooms' AND column_name = 'creator_id') THEN
        ALTER TABLE rooms DROP COLUMN creator_id CASCADE;
        ALTER TABLE rooms ADD COLUMN creator_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE;
    END IF;
    
    IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'rooms' AND column_name = 'owner_id') THEN
        ALTER TABLE rooms DROP COLUMN owner_id CASCADE;
        ALTER TABLE rooms ADD COLUMN owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE;
    END IF;
END $$;


-- =================================================================
-- 3. MIGRATION TABLE USER_ROLES
-- =================================================================
-- id (pk bigint -> uuid)
-- assigned_by (bigint -> uuid)
-- user_id (déjà uuid mais FK à vérifier)

-- Drop PK
ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_pkey CASCADE;

-- Fix ID (PK)
ALTER TABLE user_roles DROP COLUMN IF EXISTS id;
ALTER TABLE user_roles ADD COLUMN id UUID PRIMARY KEY DEFAULT gen_random_uuid();

-- Fix Assigned By
ALTER TABLE user_roles DROP COLUMN IF EXISTS assigned_by;
ALTER TABLE user_roles ADD COLUMN assigned_by UUID REFERENCES users(id) ON DELETE SET NULL;

-- Fix User ID (S'assurer que la FK pointe bien vers le nouvel ID UUID de users)
-- Note: La colonne user_id est déjà UUID d'après le prompt, on recrée juste la FK pour être sûr.
ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_user_id_fkey; -- nom standard probable
ALTER TABLE user_roles ADD CONSTRAINT fk_user_roles_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;

-- =================================================================
-- 4. CRÉATION TABLE FEDERATED_IDENTITIES
-- =================================================================
-- Attendue par oauth_service.go

CREATE TABLE IF NOT EXISTS federated_identities (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    provider TEXT NOT NULL,
    provider_id TEXT NOT NULL,
    email TEXT,
    display_name TEXT,
    avatar_url TEXT,
    access_token TEXT,
    refresh_token TEXT,
    expires_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Indexs utiles
CREATE INDEX IF NOT EXISTS idx_federated_identities_user_id ON federated_identities(user_id);
CREATE INDEX IF NOT EXISTS idx_federated_identities_provider_id ON federated_identities(provider, provider_id);

-- =================================================================
-- 5. VÉRIFICATION FINALE (Tracks & Playlists)
-- =================================================================
-- On s'assure que les tables critiques Tracks et Playlists ont bien leurs FKs attachées
-- (Au cas où le CASCADE du début aurait sauté leurs FKs)

DO $$
BEGIN
    -- Tracks
    IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'tracks' AND constraint_type = 'FOREIGN KEY') THEN
        ALTER TABLE tracks ADD CONSTRAINT fk_tracks_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
    END IF;

    -- Playlists
    IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'playlists' AND constraint_type = 'FOREIGN KEY') THEN
        ALTER TABLE playlists ADD CONSTRAINT fk_playlists_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
    END IF;
END $$;
