import numpy as np
import matplotlib.pyplot as plt
import re
import os

def read_xpm_simple(filename):
    """Lecture simplifiée et robuste des fichiers XPM"""
    try:
        with open(filename, 'r') as f:
            lines = f.readlines()
        
        # Trouver la ligne de dimensions
        dimensions = None
        for i, line in enumerate(lines):
            if line.startswith('"') and 'c ' not in line:
                # Essayer plusieurs patterns pour les dimensions
                patterns = [
                    r'"\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)',
                    r'"\s*(\d+)\s+(\d+)\s+(\d+)',
                    r'"\s*(\d+)\s+(\d+)'
                ]
                for pattern in patterns:
                    match = re.search(pattern, line)
                    if match:
                        groups = match.groups()
                        if len(groups) >= 2:
                            nx, ny = int(groups[0]), int(groups[1])
                            dimensions = (nx, ny)
                            break
                if dimensions:
                    break
        
        if not dimensions:
            print(f"Dimensions non trouvées dans {filename}")
            return None, None, None
        
        nx, ny = dimensions
        print(f"Dimensions détectées: {nx}x{ny}")
        
        # Extraire le mapping des couleurs
        color_map = {}
        for line in lines:
            if '"' in line and 'c ' in line and '/*' in line:
                # Pattern: "A  c #000000 " /* "0" */,
                parts = line.split('/*')
                if len(parts) >= 2:
                    key_part = parts[0].strip().strip('",')
                    value_part = parts[1].strip().strip('",*/')
                    
                    # Extraire la clé (premier caractère)
                    key = key_part.split()[0] if key_part.split() else ''
                    
                    # Extraire la valeur numérique
                    try:
                        # Enlever les guillemets et convertir en float
                        value = float(value_part.strip('"'))
                        color_map[key] = value
                    except ValueError:
                        # Si la conversion échoue, utiliser l'index
                        if key:
                            color_map[key] = ord(key) - ord('A')
        
        # Si le mapping est vide, créer un mapping basé sur l'ordre alphabétique
        if not color_map:
            print("Création d'un mapping de couleur basé sur l'ordre alphabétique")
            for line in lines:
                if '"' in line and 'c ' in line:
                    key = line.split('"')[1].split()[0] if '"' in line else ''
                    if key and key.isalpha():
                        color_map[key] = ord(key) - ord('A')
        
        print(f"Mapping des couleurs: {color_map}")
        
        # Extraire les données - chercher les lignes qui commencent par " et ont la bonne longueur
        data_lines = []
        for line in lines:
            line = line.strip()
            if line.startswith('"') and '/*' not in line and 'c ' not in line:
                data_content = line.split('"')[1] if '"' in line else line
                if len(data_content) >= nx:
                    data_lines.append(data_content[:nx])
        
        print(f"Lignes de données trouvées: {len(data_lines)} (attendu: {ny})")
        
        if len(data_lines) != ny:
            print(f"Ajustement: utilisation des {len(data_lines)} lignes disponibles")
            ny = len(data_lines)
            if ny == 0:
                return None, None, None
        
        # Créer la matrice de données
        data_matrix = np.zeros((ny, nx))
        valid_chars = 0
        for i, line in enumerate(data_lines):
            for j, char in enumerate(line):
                if char in color_map:
                    data_matrix[i, j] = color_map[char]
                    valid_chars += 1
                else:
                    # Caractère non trouvé dans le mapping
                    data_matrix[i, j] = 0
        
        print(f"Caractères valides mappés: {valid_chars}/{ny*nx}")
        print(f"Plage des données: {data_matrix.min():.3f} à {data_matrix.max():.3f}")
        
        return data_matrix, nx, ny
        
    except Exception as e:
        print(f"Erreur lors de la lecture de {filename}: {e}")
        import traceback
        traceback.print_exc()
        return None, None, None

def debug_xpm_content(filename):
    """Debug détaillé du contenu XPM"""
    print(f"\n=== DEBUG {filename} ===")
    with open(filename, 'r') as f:
        content = f.read()
    
    lines = content.split('\n')
    print(f"Total lines: {len(lines)}")
    
    print("\nFirst 20 lines:")
    for i, line in enumerate(lines[:20]):
        print(f"{i:3d}: {repr(line)}")
    
    print("\nLines containing data patterns:")
    data_lines = []
    for i, line in enumerate(lines):
        if '"' in line and len(line.strip()) > 10 and '/*' not in line and 'c ' not in line:
            data_lines.append((i, line.strip()))
    
    for i, line in data_lines[:10]:  # Show first 10 data lines
        print(f"{i:3d}: {line}")

def plot_fel_for_all_systems(base_dir, output_dir):
    """Génère les FEL individuels pour tous les systèmes"""
    
    systems = [
        {'folder': 'CNP0075206.3', 'xpm_file': 'FEL_PCA_CNP007.xpm', 'label': 'CNP007'},
        {'folder': 'CNP0188167.1', 'xpm_file': 'FEL_PCA_CNP018.xpm', 'label': 'CNP018'},
        {'folder': 'CNP0196376.4', 'xpm_file': 'FEL_PCA_CNP019.xpm', 'label': 'CNP019'}
    ]
    
    os.makedirs(output_dir, exist_ok=True)
    
    success_count = 0
    
    for system_info in systems:
        folder = system_info['folder']
        xpm_file = system_info['xpm_file']
        label = system_info['label']
        full_path = os.path.join(base_dir, folder, xpm_file)
        
        if not os.path.exists(full_path):
            print(f"Fichier non trouvé: {full_path}")
            continue
        
        print(f"\n{'='*50}")
        print(f"Traitement: {label}")
        print(f"Fichier: {full_path}")
        print(f"{'='*50}")
        
        # Debug du contenu d'abord
        debug_xpm_content(full_path)
        
        # Lecture des données
        data, nx, ny = read_xpm_simple(full_path)
        
        if data is not None:
            plot_individual_fel(data, nx, ny, label, output_dir)
            success_count += 1
        else:
            print(f"ÉCHEC: Impossible de lire {full_path}")
    
    return success_count

def plot_individual_fel(data, nx, ny, label, output_dir):
    """Plot individuel pour chaque système"""
    plt.figure(figsize=(10, 8))
    
    # Créer les coordonnées
    x = np.linspace(-10, 10, nx)
    y = np.linspace(-10, 10, ny)
    
    # Inverser les données si nécessaire pour l'affichage
    data_display = data
    
    # Créer le contour plot
    contour = plt.contourf(x, y, data_display, levels=20, cmap='viridis')
    
    # Ajouter les lignes de contour
    contour_lines = plt.contour(x, y, data_display, levels=10, colors='black', linewidths=0.5, alpha=0.5)
    plt.clabel(contour_lines, inline=True, fontsize=8, fmt='%1.1f')
    
    plt.colorbar(contour, label='Free Energy (kJ/mol)')
    plt.xlabel('Principal Component 1')
    plt.ylabel('Principal Component 2')
    plt.title(f'Free Energy Landscape - {label}')
    
    # Sauvegarder
    png_file = os.path.join(output_dir, f'FEL_{label}.png')
    svg_file = os.path.join(output_dir, f'FEL_{label}.svg')
    
    plt.savefig(png_file, dpi=300, bbox_inches='tight')
    plt.savefig(svg_file, bbox_inches='tight')
    plt.close()
    
    print(f"✓ FEL sauvegardé: {png_file}")

# SOLUTION ALTERNATIVE: Utiliser gmx xpm2ps si disponible
def convert_xpm_with_gmx(base_dir, output_dir):
    """Essaie de convertir XPM en PS avec GROMACS"""
    systems = ['CNP0075206.3', 'CNP0188167.1', 'CNP0196376.4']
    
    for system in systems:
        xpm_file = os.path.join(base_dir, system, f'FEL_PCA_{system.split(".")[0]}.xpm')
        if os.path.exists(xpm_file):
            try:
                # Essayer la conversion avec gmx xpm2ps
                output_ps = os.path.join(output_dir, f'FEL_{system.split(".")[0]}.ps')
                cmd = f'gmx xpm2ps -f {xpm_file} -o {output_ps}'
                print(f"Exécution: {cmd}")
                os.system(cmd)
                
                # Convertir PS en PNG (si convert est disponible)
                if os.path.exists(output_ps):
                    output_png = os.path.join(output_dir, f'FEL_{system.split(".")[0]}.png')
                    cmd = f'convert {output_ps} {output_png}'
                    os.system(cmd)
                    print(f"✓ Conversion réussie pour {system}")
                    
            except Exception as e:
                print(f"Échec conversion pour {system}: {e}")

if __name__ == "__main__":
    BASE_DIR = "/media/sf_TAWWORI/AR1_IL18R/Dynamic_Results"
    OUTPUT_DIR = "/media/sf_TAWWORI/AR1_IL18R/Dynamic_Results/FEL_Results"
    
    print("Génération des Free Energy Landscapes individuels...")
    print(f"Répertoire: {BASE_DIR}")
    
    # Méthode Python pour plots individuels uniquement
    success_count = plot_fel_for_all_systems(BASE_DIR, OUTPUT_DIR)
    
    if success_count == 0:
        print("\n" + "="*60)
        print("METHODE PYTHON ÉCHOUÉE - ESSAI AVEC GROMACS")
        print("="*60)
        # Essayer la méthode GROMACS
        convert_xpm_with_gmx(BASE_DIR, OUTPUT_DIR)
    
    print("\n" + "="*50)
    if success_count > 0:
        print(f"SUCCÈS: {success_count} FEL individuels générés dans {OUTPUT_DIR}")
    else:
        print("ÉCHEC: Aucun FEL généré")
        print("Considérations:")
        print("1. Vérifiez que les fichiers XPM sont valides")
        print("2. Essayez: gmx xpm2ps -f fichier.xpm -o output.ps")
        print("3. Contactez le support si le problème persiste")
    print("="*50)
