-- ============================================
-- Migration 0043: Migration complète du système de prêts
-- Date: 2026-03-01
-- ============================================
-- Description:
-- 1. Remplir id_source dans RsCalcul (lien direct Pret.Id)
-- 2. Consolider les rubriques 591-597 → 590 dans RsCalcul
-- 3. S'assurer que la rubrique 590 existe
-- 4. Supprimer la colonne Pret.Rubrique
-- 5. Supprimer les rubriques 591-597 obsolètes
-- 6. Recalculer le Reliquat de tous les prêts
-- ============================================

-- Vérifier si les tables paie existent (n'existent que dans les bases paie)
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'RsCalcul')
   OR NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Pret')
BEGIN
    PRINT 'Tables RsCalcul/Pret non trouvées - migration ignorée (base non-paie)';
END
ELSE
BEGIN
    -- ============================================
    -- ÉTAPE 0: Créer la colonne id_source si elle n'existe pas
    -- ============================================
    IF NOT EXISTS (
        SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = 'RsCalcul' AND COLUMN_NAME = 'id_source'
    )
    BEGIN
        EXEC('ALTER TABLE RsCalcul ADD id_source INT NOT NULL DEFAULT 0');
        PRINT 'Colonne id_source créée dans RsCalcul';
    END

    -- ============================================
    -- ÉTAPE 1: Réinitialiser id_source et remplir pour les prêts
    -- ============================================

    -- D'abord, réinitialiser id_source à 0 pour toutes les lignes
    -- (car l'ancienne colonne nlign pouvait avoir des valeurs)
    -- Utiliser SQL dynamique car la colonne peut venir d'être créée
    EXEC('UPDATE RsCalcul SET id_source = 0 WHERE id_source IS NULL OR id_source <> 0');
    PRINT 'id_source réinitialisé à 0 pour toutes les lignes';

    -- Vérifier si RsCalcul a une colonne Rubrique (anciennes bases)
    -- Utiliser SQL dynamique car SQL Server compile tout avant exécution
    IF EXISTS (
        SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = 'RsCalcul' AND COLUMN_NAME = 'Rubrique'
    )
    AND EXISTS (
        SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = 'Pret' AND COLUMN_NAME = 'Rubrique'
    )
    BEGIN
        -- Remplir id_source pour les prêts via SQL dynamique
        EXEC('
            UPDATE rs
            SET rs.id_source = p.Id
            FROM RsCalcul rs
            INNER JOIN (
                SELECT Matricule, Rubrique, MAX(Id) as Id
                FROM Pret
                GROUP BY Matricule, Rubrique
            ) p ON rs.Matricule = p.Matricule AND rs.Rubrique = p.Rubrique
            WHERE rs.Rubrique IN (''590'', ''591'', ''592'', ''593'', ''594'', ''595'', ''596'', ''597'')
        ');
        PRINT 'id_source rempli pour les prêts existants';

        -- Consolider les rubriques 591-597 vers 590
        EXEC('
            UPDATE RsCalcul
            SET Rubrique = ''590''
            WHERE Rubrique IN (''591'', ''592'', ''593'', ''594'', ''595'', ''596'', ''597'')
        ');
        PRINT 'Rubriques 591-597 consolidées vers 590';
    END
    ELSE
    BEGIN
        PRINT 'RsCalcul.Rubrique ou Pret.Rubrique n''existe pas - étapes 1-2 ignorées';
    END

    -- ============================================
    -- ÉTAPE 3: S'assurer que la rubrique 590 existe
    -- ============================================
    IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Rubrique')
    BEGIN
        EXEC('
            IF EXISTS (SELECT 1 FROM Rubrique WHERE Code = ''590'')
            BEGIN
                UPDATE Rubrique SET
                    Libelle = N''Prêt'',
                    Positive = 0,
                    system = 1,
                    pret = 1,
                    Type_Comptable = 2,
                    Libelle_journalC = ''Pret''
                WHERE Code = ''590'';
                PRINT ''Rubrique 590 mise à jour'';
            END
            ELSE
            BEGIN
                INSERT INTO Rubrique (Code, Libelle, Positive, system, pret, Type_Comptable, Libelle_journalC)
                VALUES (''590'', N''Prêt'', 0, 1, 1, 2, ''Pret'');
                PRINT ''Rubrique 590 créée'';
            END
        ')
    END

    -- ============================================
    -- ÉTAPE 4: Supprimer la colonne Pret.Rubrique
    -- ============================================

    -- Supprimer l'index sur Rubrique s'il existe
    IF EXISTS (
        SELECT 1 FROM sys.indexes
        WHERE name = 'nix_Pret_Rubrique' AND object_id = OBJECT_ID('Pret')
    )
    BEGIN
        EXEC('DROP INDEX nix_Pret_Rubrique ON Pret');
        PRINT 'Index nix_Pret_Rubrique supprimé';
    END

    -- Supprimer les contraintes de clé étrangère sur Rubrique
    DECLARE @fk_name NVARCHAR(255)
    DECLARE fk_cursor CURSOR FOR
        SELECT fk.name
        FROM sys.foreign_keys fk
        INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
        INNER JOIN sys.columns c ON fkc.parent_column_id = c.column_id AND fkc.parent_object_id = c.object_id
        WHERE fk.parent_object_id = OBJECT_ID('Pret') AND c.name = 'Rubrique'

    OPEN fk_cursor
    FETCH NEXT FROM fk_cursor INTO @fk_name
    WHILE @@FETCH_STATUS = 0
    BEGIN
        EXEC('ALTER TABLE Pret DROP CONSTRAINT ' + @fk_name)
        PRINT 'Contrainte FK supprimée: ' + @fk_name
        FETCH NEXT FROM fk_cursor INTO @fk_name
    END
    CLOSE fk_cursor
    DEALLOCATE fk_cursor

    -- Supprimer les contraintes par défaut sur Rubrique
    DECLARE @df_name NVARCHAR(255)
    SELECT @df_name = dc.name
    FROM sys.default_constraints dc
    INNER JOIN sys.columns c ON dc.parent_column_id = c.column_id AND dc.parent_object_id = c.object_id
    WHERE dc.parent_object_id = OBJECT_ID('Pret') AND c.name = 'Rubrique'

    IF @df_name IS NOT NULL
    BEGIN
        EXEC('ALTER TABLE Pret DROP CONSTRAINT ' + @df_name)
        PRINT 'Contrainte par défaut supprimée: ' + @df_name
    END

    -- Supprimer la colonne Rubrique si elle existe
    IF EXISTS (
        SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = 'Pret' AND COLUMN_NAME = 'Rubrique'
    )
    BEGIN
        EXEC('ALTER TABLE Pret DROP COLUMN Rubrique');
        PRINT 'Colonne Rubrique supprimée de Pret';
    END

    -- ============================================
    -- ÉTAPE 5: Supprimer les rubriques 591-597 obsolètes
    -- ============================================
    IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Rubrique')
    BEGIN
        EXEC('DELETE FROM Rubrique WHERE Code IN (''591'', ''592'', ''593'', ''594'', ''595'', ''596'', ''597'')');
        PRINT 'Rubriques 591-597 supprimées';
    END

    -- ============================================
    -- ÉTAPE 6: Recalculer le Reliquat de tous les prêts
    -- ============================================
    -- On utilise id_source > 0 pour identifier les lignes liées aux prêts
    -- SQL dynamique car id_source peut venir d'être créée
    EXEC('
        ;WITH cte_retenu AS (
            SELECT rs.id_source, SUM(rs.Retenu) AS retenu_total
            FROM RsCalcul rs
            WHERE rs.id_source > 0
            GROUP BY rs.id_source
        )
        UPDATE Pret
        SET Reliquat = Pret.Montant - ISNULL(cr.retenu_total, 0)
        FROM Pret
        LEFT JOIN cte_retenu cr ON Pret.Id = cr.id_source
    ');
    PRINT 'Reliquat recalculé pour tous les prêts';
END
