#!/usr/bin/env python3
"""
Générateur de données de test pour détecter les outliers UNIVARIÉS et MULTIVARIÉS.

Ce script crée un dataset avec :
1. Des outliers univariés évidents (valeurs extrêmes dans une seule colonne)
2. Des outliers multivariés (combinaisons de valeurs normales individuellement mais anormales ensemble)
3. Des données normales pour la majorité
"""

import pandas as pd
import numpy as np
from pathlib import Path

# Configuration
np.random.seed(42)
N_NORMAL = 100  # Nombre de lignes normales

def generate_outlier_dataset():
    """
    Génère un dataset avec des outliers contrôlés pour tester les deux types de détection.
    """
    data = []

    # ========================================================================
    # 1. DONNÉES NORMALES (baseline)
    # ========================================================================
    print("📊 Génération des données normales...")

    for i in range(N_NORMAL):
        data.append({
            "ID": i + 1,
            "Age": np.random.normal(40, 10),  # Moyenne 40, écart-type 10
            "Salaire": np.random.normal(35000, 8000),  # Moyenne 35k, écart-type 8k
            "Experience": np.random.normal(10, 4),  # Moyenne 10 ans, écart-type 4
            "Performance": np.random.normal(75, 10),  # Moyenne 75/100, écart-type 10
            "Heures_Sup": np.random.normal(5, 3),  # Moyenne 5h/mois, écart-type 3
            "Type": "Normal"
        })

    # ========================================================================
    # 2. OUTLIERS UNIVARIÉS (évidents dans UNE colonne)
    # ========================================================================
    print("🔴 Génération des outliers univariés...")

    # Outlier 1: Âge extrême (150 ans - impossible)
    data.append({
        "ID": 101,
        "Age": 150,
        "Salaire": 38000,
        "Experience": 12,
        "Performance": 78,
        "Heures_Sup": 6,
        "Type": "Outlier_Uni_Age"
    })

    # Outlier 2: Salaire extrêmement élevé (500k - 10x la normale)
    data.append({
        "ID": 102,
        "Age": 45,
        "Salaire": 500000,
        "Experience": 15,
        "Performance": 82,
        "Heures_Sup": 8,
        "Type": "Outlier_Uni_Salaire"
    })

    # Outlier 3: Salaire négatif (impossible)
    data.append({
        "ID": 103,
        "Age": 35,
        "Salaire": -5000,
        "Experience": 8,
        "Performance": 72,
        "Heures_Sup": 4,
        "Type": "Outlier_Uni_Salaire_Neg"
    })

    # Outlier 4: Performance > 100 (impossible)
    data.append({
        "ID": 104,
        "Age": 38,
        "Salaire": 42000,
        "Experience": 11,
        "Performance": 150,
        "Heures_Sup": 7,
        "Type": "Outlier_Uni_Perf"
    })

    # Outlier 5: Heures supplémentaires négatives
    data.append({
        "ID": 105,
        "Age": 42,
        "Salaire": 36000,
        "Experience": 13,
        "Performance": 76,
        "Heures_Sup": -20,
        "Type": "Outlier_Uni_Heures"
    })

    # ========================================================================
    # 3. OUTLIERS MULTIVARIÉS (normaux individuellement, anormaux ensemble)
    # ========================================================================
    print("🟣 Génération des outliers multivariés...")

    # Outlier Multivarié 1: Jeune avec BEAUCUP d'expérience (impossible)
    # Age=25 (normal) mais Experience=30 (impossible pour cet âge)
    data.append({
        "ID": 201,
        "Age": 25,
        "Salaire": 32000,
        "Experience": 30,
        "Performance": 70,
        "Heures_Sup": 5,
        "Type": "Outlier_Multi_Age_Exp"
    })

    # Outlier Multivarié 2: Haut salaire avec basse performance (suspect)
    # Salaire=80k (normal possible) mais Performance=40 (anormalement bas pour ce salaire)
    data.append({
        "ID": 202,
        "Age": 45,
        "Salaire": 80000,
        "Experience": 15,
        "Performance": 40,
        "Heures_Sup": 2,
        "Type": "Outlier_Multi_Salaire_Perf"
    })

    # Outlier Multivarié 3: Faible expérience avec très haut salaire (suspect)
    data.append({
        "ID": 203,
        "Age": 28,
        "Salaire": 95000,
        "Experience": 1,
        "Performance": 85,
        "Heures_Sup": 15,
        "Type": "Outlier_Multi_Exp_Salaire"
    })

    # Outlier Multivarié 4: Personne âgée avec junior-level tout
    data.append({
        "ID": 204,
        "Age": 65,
        "Salaire": 25000,
        "Experience": 1,
        "Performance": 60,
        "Heures_Sup": 0,
        "Type": "Outlier_Multi_Senior_Junior"
    })

    # Outlier Multivarié 5: Performance parfaite avec 0 heures supp (rare)
    data.append({
        "ID": 205,
        "Age": 35,
        "Salaire": 40000,
        "Experience": 10,
        "Performance": 100,
        "Heures_Sup": 0,
        "Type": "Outlier_Multi_Perf_Heures"
    })

    # Outlier Multivarié 6: Combinaison impossible - Junior avec salaire senior ET perf max
    data.append({
        "ID": 206,
        "Age": 22,
        "Salaire": 85000,
        "Experience": 0,
        "Performance": 95,
        "Heures_Sup": 0,
        "Type": "Outlier_Multi_Impossible"
    })

    # ========================================================================
    # 4. CAS LIMITES (valeurs frontières)
    # ========================================================================
    print("🎯 Génération des cas limites...")

    # Cas limite 1: Zéro partout (suspect mais pas impossible)
    data.append({
        "ID": 301,
        "Age": 22,
        "Salaire": 0,
        "Experience": 0,
        "Performance": 0,
        "Heures_Sup": 0,
        "Type": "Cas_Limie_Zeros"
    })

    # Cas limite 2: Très âgé avec beaucoup d'expérience (normal)
    data.append({
        "ID": 302,
        "Age": 62,
        "Salaire": 70000,
        "Experience": 40,
        "Performance": 88,
        "Heures_Sup": 3,
        "Type": "Normal_Senior"
    })

    # Cas limite 3: Salaire minimum légal (normal)
    data.append({
        "ID": 303,
        "Age": 25,
        "Salaire": 15000,
        "Experience": 2,
        "Performance": 65,
        "Heures_Sup": 2,
        "Type": "Normal_Salaire_Min"
    })

    # Création du DataFrame
    df = pd.DataFrame(data)

    # Arrondir les valeurs numériques pour plus de clarté
    numeric_cols = ["Age", "Salaire", "Experience", "Performance", "Heures_Sup"]
    for col in numeric_cols:
        df[col] = df[col].round(2)

    # Réordonner les colonnes
    df = df[["ID", "Age", "Experience", "Salaire", "Performance", "Heures_Sup", "Type"]]

    return df

def main():
    print("=" * 70)
    print("🧪 GÉNÉRATEUR DE DONNÉES DE TEST - OUTLIERS UNIVARIÉS & MULTIVARIÉS")
    print("=" * 70)
    print()

    # Générer le dataset
    df = generate_outlier_dataset()

    # Sauvegarder en CSV
    output_dir = Path("/home/sepehr/dev/Data_analysis/backend/test_data")
    output_dir.mkdir(exist_ok=True)

    csv_path = output_dir / "test_outliers_complete.csv"
    df.to_csv(csv_path, index=False)

    excel_path = output_dir / "test_outliers_complete.xlsx"
    df.to_excel(excel_path, index=False)

    # Afficher les statistiques
    print()
    print("=" * 70)
    print("📊 STATISTIQUES DU DATASET")
    print("=" * 70)
    print(f"✅ Total lignes : {len(df)}")
    print(f"📈 Colonnes : {len(df.columns)}")
    print()
    print("🔴 Outliers univariés attendus : 5")
    print("   - ID 101: Âge = 150 ans")
    print("   - ID 102: Salaire = 500,000€")
    print("   - ID 103: Salaire = -5,000€ (négatif)")
    print("   - ID 104: Performance = 150 (>100)")
    print("   - ID 105: Heures_Sup = -20 (négatif)")
    print()
    print("🟣 Outliers multivariés attendus : 6")
    print("   - ID 201: Âge=25 avec Exp=30 (impossible)")
    print("   - ID 202: Salaire=80k avec Perf=40 (incohérent)")
    print("   - ID 203: Exp=1 avec Salaire=95k (suspect)")
    print("   - ID 204: Âge=65 avec Exp=1 (incohérent)")
    print("   - ID 205: Perf=100 avec Heures_Sup=0 (rare)")
    print("   - ID 206: Âge=22, Exp=0, Salaire=85k (impossible)")
    print()
    print("=" * 70)
    print("💾 FICHIERS GÉNÉRÉS")
    print("=" * 70)
    print(f"📄 CSV : {csv_path}")
    print(f"📊 Excel : {excel_path}")
    print()
    print("=" * 70)
    print("🎯 COMMENT TESTER")
    print("=" * 70)
    print("1. Importez le fichier 'test_outliers_complete.csv' dans l'application")
    print("2. Vérifiez que les colonnes sont bien détectées comme numériques")
    print("3. Les cercles ROUGES doivent apparaître sur les colonnes avec outliers univariés")
    print("4. Le cercle VIOLET doit apparaître (indicateur global multivarié)")
    print("5. Cliquez sur chaque indicateur pour voir les détails")
    print("6. Vérifiez la cohérence des outliers détectés")
    print()
    print("✨ Bon testing !")
    print("=" * 70)

    # Afficher un aperçu des outliers
    print()
    print("📋 APERÇU DES OUTLIERS DANS LE DATASET :")
    print("-" * 70)
    outliers_df = df[df["Type"].str.contains("Outlier", case=False, na=False)]
    print(outliers_df[["ID", "Type", "Age", "Experience", "Salaire", "Performance", "Heures_Sup"]].to_string(index=False))

if __name__ == "__main__":
    main()
