#!/usr/bin/env python3
"""
Script simplifié pour reconstruire l'index FAISS sans dépendances lourdes.

IMPORTANT: Utiliser le Python du venv !
Usage: geniusia2/venv/bin/python rebuild_faiss_simple.py
"""

import pickle
import json
import numpy as np
from pathlib import Path


def rebuild_index():
    """Reconstruit l'index FAISS à partir des tâches existantes."""
    print("="*60)
    print("🔨 RECONSTRUCTION DE L'INDEX FAISS")
    print("="*60)
    
    try:
        import faiss
    except ImportError:
        print("\n❌ FAISS n'est pas installé")
        print("   Installation: pip install faiss-cpu")
        return
    
    profiles_dir = Path("geniusia2/data/user_profiles")
    task_dirs = [d for d in profiles_dir.iterdir() if d.is_dir() and d.name.startswith("task_")]
    
    print(f"\n📁 Nombre de tâches trouvées: {len(task_dirs)}")
    
    # Collecter tous les embeddings et métadonnées
    all_embeddings = []
    all_metadata = []
    
    total_actions = 0
    
    # Parcourir toutes les tâches
    for i, task_dir in enumerate(task_dirs, 1):
        signatures_file = task_dir / "signatures.pkl"
        metadata_file = task_dir / "metadata.json"
        
        if not signatures_file.exists():
            continue
        
        # Charger les métadonnées
        task_name = "Unknown"
        if metadata_file.exists():
            with open(metadata_file, 'r') as f:
                metadata = json.load(f)
                task_name = metadata.get('task_name', 'Unknown')
        
        # Charger les signatures
        with open(signatures_file, 'rb') as f:
            signatures = pickle.load(f)
        
        total_actions += len(signatures)
        
        # Ajouter les embeddings
        for j, signature in enumerate(signatures):
            embedding = signature.get('embedding')
            
            if embedding is not None:
                # Convertir en numpy array si nécessaire
                if not isinstance(embedding, np.ndarray):
                    embedding = np.array(embedding)
                
                # S'assurer que c'est float32
                embedding = embedding.astype(np.float32)
                
                all_embeddings.append(embedding)
                
                # Créer les métadonnées
                meta = {
                    "task_id": task_dir.name,
                    "task_name": task_name,
                    "action_index": j,
                    "action_type": signature.get('action_type', 'unknown'),
                    "element_type": signature.get('element_type', ''),
                    "window": signature.get('window', ''),
                    "position": signature.get('position', None)
                }
                
                all_metadata.append(meta)
        
        if i % 10 == 0:
            print(f"   Traité {i}/{len(task_dirs)} tâches...")
    
    print(f"\n✅ Traitement terminé:")
    print(f"   - Tâches traitées: {len(task_dirs)}")
    print(f"   - Actions totales: {total_actions}")
    print(f"   - Embeddings collectés: {len(all_embeddings)}")
    
    if len(all_embeddings) == 0:
        print("\n❌ Aucun embedding trouvé")
        return
    
    # Créer l'index FAISS
    print(f"\n🔨 Création de l'index FAISS...")
    
    # Convertir en matrice numpy
    embeddings_matrix = np.vstack(all_embeddings)
    dimension = embeddings_matrix.shape[1]
    
    print(f"   Dimension des embeddings: {dimension}")
    print(f"   Nombre d'embeddings: {embeddings_matrix.shape[0]}")
    
    # Créer l'index (IndexFlatL2 pour recherche exacte)
    index = faiss.IndexFlatL2(dimension)
    
    # Ajouter les embeddings
    index.add(embeddings_matrix)
    
    print(f"   Index créé avec {index.ntotal} vecteurs")
    
    # Sauvegarder l'index
    faiss_dir = Path("geniusia2/data/faiss_index")
    faiss_dir.mkdir(parents=True, exist_ok=True)
    
    index_file = faiss_dir / "embeddings.index"
    metadata_file = faiss_dir / "metadata.pkl"
    
    print(f"\n💾 Sauvegarde de l'index...")
    
    # Sauvegarder l'index FAISS
    faiss.write_index(index, str(index_file))
    
    # Sauvegarder les métadonnées
    with open(metadata_file, 'wb') as f:
        pickle.dump(all_metadata, f)
    
    # Vérifier la sauvegarde
    if index_file.exists() and metadata_file.exists():
        index_size = index_file.stat().st_size
        meta_size = metadata_file.stat().st_size
        
        print(f"\n✅ Index FAISS créé avec succès!")
        print(f"   - embeddings.index: {index_size:,} bytes ({index_size/1024:.1f} KB)")
        print(f"   - metadata.pkl: {meta_size:,} bytes ({meta_size/1024:.1f} KB)")
        
        # Tester la recherche
        print(f"\n🔍 Test de recherche...")
        
        # Prendre le premier embedding pour tester
        test_embedding = embeddings_matrix[0:1]
        
        # Rechercher les 3 plus proches
        distances, indices = index.search(test_embedding, 3)
        
        print(f"   Résultats de recherche:")
        for i, (dist, idx) in enumerate(zip(distances[0], indices[0])):
            meta = all_metadata[idx]
            similarity = 1 / (1 + dist)  # Convertir distance en similarité
            print(f"   {i+1}. Similarité: {similarity:.3f} | {meta.get('task_name', 'N/A')} - {meta.get('action_type', 'N/A')}")
    else:
        print(f"\n❌ Erreur: Index non créé")


def main():
    """Fonction principale."""
    print("\n🔧 RECONSTRUCTION DE L'INDEX FAISS\n")
    
    try:
        rebuild_index()
        
        print("\n" + "="*60)
        print("✅ RECONSTRUCTION TERMINÉE")
        print("="*60)
        
        print("\n💡 L'index FAISS est maintenant disponible pour:")
        print("   - Recherche de similarité")
        print("   - Suggestions d'actions")
        print("   - Rejeu intelligent")
    
    except Exception as e:
        print(f"\n❌ Erreur: {e}")
        import traceback
        traceback.print_exc()


if __name__ == "__main__":
    main()
