-- ================================================================
-- MISE À JOUR DES transfer_id POUR TOUS LES VIREMENTS EXISTANTS
-- ================================================================
-- Ce script corrige les transfer_id pour qu'ils pointent vers
-- les IDs de comptes bancaires au lieu des IDs d'opérations
-- ================================================================

-- ================================================================
-- ÉTAPE 1 : DIAGNOSTIC - Identifier le type de corruption
-- ================================================================

-- Vérifier combien de virements existent
SELECT 
    COUNT(*) AS 'Total virements (transfer_id non NULL)',
    COUNT(DISTINCT id_copro) AS 'Nombre de copropriétés concernées'
FROM bank 
WHERE transfer_id IS NOT NULL;

-- Vérifier si transfer_id pointe vers des opérations (ancien système)
SELECT 
    COUNT(*) AS 'Virements avec transfer_id pointant vers une opération (À CORRIGER)'
FROM bank b1
WHERE b1.transfer_id IS NOT NULL
  AND EXISTS (SELECT 1 FROM bank b2 WHERE b2.id = b1.transfer_id);

-- Vérifier si transfer_id pointe vers des comptes bancaires (nouveau système)
SELECT 
    COUNT(*) AS 'Virements avec transfer_id pointant vers un compte (DÉJÀ CORRECT)'
FROM bank b1
WHERE b1.transfer_id IS NOT NULL
  AND EXISTS (SELECT 1 FROM bank_account ba WHERE ba.id = b1.transfer_id);

-- Afficher les virements problématiques
SELECT 
    b1.id,
    b1.id_bank AS compte_source,
    b1.transfer_id AS transfer_id_actuel,
    'opération' AS pointe_vers,
    b2.id_bank AS compte_trouve,
    b1.date,
    b1.description,
    b1.debit,
    b1.credit
FROM bank b1
LEFT JOIN bank b2 ON b2.id = b1.transfer_id
WHERE b1.transfer_id IS NOT NULL
  AND EXISTS (SELECT 1 FROM bank WHERE id = b1.transfer_id)
ORDER BY b1.date DESC, b1.id
LIMIT 20;

-- ================================================================
-- ÉTAPE 2 : SAUVEGARDE - Créer une table de backup
-- ================================================================

-- Créer une table de sauvegarde avant modification

CREATE TABLE bank_transfer_backup AS
SELECT 
    id,
    id_bank,
    transfer_id AS old_transfer_id,
    date,
    description,
    debit,
    credit,
    NOW() AS backup_date
FROM bank
WHERE transfer_id IS NOT NULL;

SELECT COUNT(*) AS 'Lignes sauvegardées dans bank_transfer_backup' FROM bank_transfer_backup;

-- ================================================================
-- ÉTAPE 3 : CORRECTION MÉTHODE 1 - Si transfer_id pointe vers opération
-- ================================================================
-- Cette méthode fonctionne si l'ancien système créait des liens entre opérations

-- Compter combien de lignes seront affectées
SELECT COUNT(*) AS 'Lignes qui seront corrigées (Méthode 1)'
FROM bank b1
JOIN bank b2 ON b2.id = b1.transfer_id
WHERE b1.transfer_id IS NOT NULL
  AND b1.transfer_id != b2.id_bank
  AND EXISTS (SELECT 1 FROM bank WHERE id = b1.transfer_id);

-- Afficher un aperçu des modifications avant de les appliquer
SELECT 
    b1.id,
    b1.id_bank AS compte_source,
    b1.transfer_id AS ancien_transfer_id,
    b2.id_bank AS nouveau_transfer_id,
    b1.date,
    b1.description,
    'SERA MODIFIÉ' AS action
FROM bank b1
JOIN bank b2 ON b2.id = b1.transfer_id
WHERE b1.transfer_id IS NOT NULL
  AND b1.transfer_id != b2.id_bank
  AND EXISTS (SELECT 1 FROM bank WHERE id = b1.transfer_id)
ORDER BY b1.date DESC
LIMIT 10;

-- APPLIQUER LA CORRECTION (décommenter pour exécuter)
/*
UPDATE bank b1
JOIN bank b2 ON b2.id = b1.transfer_id
SET b1.transfer_id = b2.id_bank
WHERE b1.transfer_id IS NOT NULL
  AND b1.transfer_id != b2.id_bank
  AND EXISTS (SELECT 1 FROM bank WHERE id = b1.transfer_id);

SELECT ROW_COUNT() AS 'Lignes corrigées';
*/

-- ================================================================
-- ÉTAPE 4 : CORRECTION MÉTHODE 2 - Reconstruction par paires
-- ================================================================
-- À utiliser si les données sont très corrompues ou si la Méthode 1 échoue
-- Cette méthode trouve les paires de virements par critères métier

-- Étape 4.1 : Identifier les paires potentielles
SELECT 
    b1.id AS op1_id,
    b1.id_bank AS op1_compte,
    b1.debit AS op1_debit,
    b1.credit AS op1_credit,
    b2.id AS op2_id,
    b2.id_bank AS op2_compte,
    b2.debit AS op2_debit,
    b2.credit AS op2_credit,
    b1.date,
    b1.description,
    'PAIRE DÉTECTÉE' AS statut
FROM bank b1
JOIN bank b2 ON b1.id_bank != b2.id_bank
    AND b1.id_copro = b2.id_copro
    AND DATE(b1.date) = DATE(b2.date)
    AND b1.description = b2.description
    AND ABS(COALESCE(b1.debit, 0) - COALESCE(b2.credit, 0)) < 0.01
    AND ABS(COALESCE(b1.credit, 0) - COALESCE(b2.debit, 0)) < 0.01
    AND b1.id < b2.id
WHERE b1.transfer_id IS NOT NULL OR b2.transfer_id IS NOT NULL
ORDER BY b1.date DESC
LIMIT 20;

-- Étape 4.2 : RECONSTRUCTION COMPLÈTE (décommenter pour exécuter)
/*
-- Réinitialiser tous les transfer_id
UPDATE bank 
SET transfer_id = NULL 
WHERE transfer_id IS NOT NULL;

-- Reconstruire les liens
UPDATE bank b1
JOIN bank b2 ON b1.id_bank != b2.id_bank
    AND b1.id_copro = b2.id_copro
    AND DATE(b1.date) = DATE(b2.date)
    AND b1.description = b2.description
    AND ABS(COALESCE(b1.debit, 0) - COALESCE(b2.credit, 0)) < 0.01
    AND ABS(COALESCE(b1.credit, 0) - COALESCE(b2.debit, 0)) < 0.01
    AND b1.id < b2.id
    AND (
        (b1.debit IS NOT NULL AND b1.debit > 0 AND b2.credit IS NOT NULL AND b2.credit > 0)
        OR
        (b1.credit IS NOT NULL AND b1.credit > 0 AND b2.debit IS NOT NULL AND b2.debit > 0)
    )
SET 
    b1.transfer_id = b2.id_bank,
    b2.transfer_id = b1.id_bank
WHERE b1.transfer_id IS NULL 
  AND b2.transfer_id IS NULL;

SELECT COUNT(*) / 2 AS 'Paires reconstruites' 
FROM bank 
WHERE transfer_id IS NOT NULL;
*/

-- ================================================================
-- ÉTAPE 5 : VÉRIFICATION POST-CORRECTION
-- ================================================================

-- Vérifier que tous les transfer_id pointent maintenant vers des comptes bancaires
SELECT 
    b.id,
    b.id_bank AS compte_source,
    ba_source.nom_banque AS nom_source,
    b.transfer_id AS compte_dest,
    ba_dest.nom_banque AS nom_dest,
    b.date,
    b.description,
    b.debit,
    b.credit,
    CASE 
        WHEN ba_dest.id IS NULL THEN '❌ ERREUR : Compte destination introuvable'
        ELSE '✅ OK'
    END AS validation
FROM bank b
JOIN bank_account ba_source ON ba_source.id = b.id_bank
LEFT JOIN bank_account ba_dest ON ba_dest.id = b.transfer_id
WHERE b.transfer_id IS NOT NULL
ORDER BY validation DESC, b.date DESC
LIMIT 50;

-- Compter les erreurs restantes
SELECT 
    COUNT(*) AS 'Virements avec transfer_id invalide (ERREUR)'
FROM bank b
WHERE b.transfer_id IS NOT NULL
  AND NOT EXISTS (SELECT 1 FROM bank_account ba WHERE ba.id = b.transfer_id);

-- Compter les succès
SELECT 
    COUNT(*) AS 'Virements avec transfer_id valide (OK)'
FROM bank b
WHERE b.transfer_id IS NOT NULL
  AND EXISTS (SELECT 1 FROM bank_account ba WHERE ba.id = b.transfer_id);

-- ================================================================
-- ÉTAPE 6 : ROLLBACK SI NÉCESSAIRE
-- ================================================================

-- En cas de problème, restaurer depuis le backup
/*
UPDATE bank b
JOIN bank_transfer_backup backup ON backup.id = b.id
SET b.transfer_id = backup.old_transfer_id;

SELECT 'Données restaurées depuis le backup' AS resultat;
*/

-- ================================================================
-- RÉSUMÉ FINAL
-- ================================================================

SELECT 
    'RÉSUMÉ DE LA CORRECTION' AS titre,
    (SELECT COUNT(*) FROM bank WHERE transfer_id IS NOT NULL) AS total_virements,
    (SELECT COUNT(*) FROM bank b WHERE b.transfer_id IS NOT NULL AND EXISTS (SELECT 1 FROM bank_account ba WHERE ba.id = b.transfer_id)) AS virements_corrects,
    (SELECT COUNT(*) FROM bank b WHERE b.transfer_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM bank_account ba WHERE ba.id = b.transfer_id)) AS virements_erreur,
    (SELECT COUNT(*) FROM bank_transfer_backup) AS backup_lignes;

-- ================================================================
-- NETTOYAGE (après validation)
-- ================================================================

-- Une fois la correction validée, supprimer la table de backup
-- DROP TABLE IF EXISTS bank_transfer_backup;

-- ================================================================
-- NOTES D'UTILISATION
-- ================================================================

/*
PROCÉDURE RECOMMANDÉE :

1. Exécuter les requêtes de DIAGNOSTIC (Étape 1)
   → Comprendre l'état actuel des données

2. Créer le BACKUP (Étape 2)
   → Sécurité : pouvoir revenir en arrière

3. Tester d'abord la MÉTHODE 1 (Étape 3)
   → Plus simple et rapide si les données sont cohérentes
   → Décommenter le UPDATE pour appliquer

4. Si nécessaire, utiliser la MÉTHODE 2 (Étape 4)
   → Reconstruction complète par critères métier
   → Plus lent mais plus robuste

5. VÉRIFIER les résultats (Étape 5)
   → S'assurer qu'aucun transfer_id invalide ne subsiste

6. En cas d'erreur, ROLLBACK (Étape 6)
   → Restaurer depuis le backup

7. Une fois validé, NETTOYAGE
   → Supprimer la table de backup

TEMPS D'EXÉCUTION ESTIMÉ :
- Diagnostic : < 1 seconde
- Backup : 1-5 secondes
- Méthode 1 : 1-10 secondes
- Méthode 2 : 10-60 secondes (selon volume)
- Vérification : < 1 seconde

IMPORTANT :
- Toujours exécuter dans un environnement de test d'abord
- Vérifier les résultats avant de valider en production
- Garder le backup jusqu'à validation complète
*/
