import numpy as np
import os

# Idenitification des points singuliers
# 1. Chargement de la matrice et des IDs réels
matrice = np.load("application/sym/sym_data/matrice_distances.npy")
ids_originaux = np.load("application/sym/sym_data/liste_ids.npy")

# 2. Identification des lignes/colonnes contenant des infinis
# On regarde pour chaque sommet s'il a au moins une distance infinie vers un autre
masque_inf = np.isinf(matrice)
nb_inf_total = np.sum(masque_inf)

# Calcul du nombre d'infinis par sommet (ligne)
inf_par_sommet = np.sum(masque_inf, axis=1)
indices_probleme = np.where(inf_par_sommet > 0)[0]

print("--- ANALYSE DE LA CONNECTIVITÉ ---")
print(f"Nombre total de paires (i, j) déconnectées : {nb_inf_total}")
print(f"# sommets avec au moins une déconnexion : {len(indices_probleme)} sur {len(ids_originaux)}")

if len(indices_probleme) > 0:
    print("\n--- SOMMETS POSANT PROBLÈME (Top 20) ---")
    print(f"{'Indice':<10} | {'ID Original':<15} | {'Nb de points inaccessibles'}")
    print("-" * 50)

    # On trie par le nombre de déconnexions pour voir les points les plus isolés
    indices_tries = indices_probleme[np.argsort(inf_par_sommet[indices_probleme])[::-1]]

    for idx in indices_tries[:20]:
        id_orig = ids_originaux[idx]
        nb_inaccessibles = inf_par_sommet[idx]
        print(f"{idx:<10} | {id_orig:<15} | {nb_inaccessibles}")

# 3. Vérification de la "Giant Component" (Composante Géante)
# Si un sommet est déconnecté de presque tout le monde, il est probablement sur une île.
# Si un sommet est déconnecté de seulement 2-3 points, c'est une impasse isolée.


# Fichiers à modifier
MAT_FILE = "matrice_distances.npy"
IDS_FILE = "liste_ids.npy"

if not os.path.exists(MAT_FILE) or not os.path.exists(IDS_FILE):
    print("Erreur : Fichiers .npy introuvables.")
else:
    # 1. Chargement initial
    matrice = np.load(MAT_FILE)
    ids = np.load(IDS_FILE)

    n_initial = len(ids)
    print(f"État initial : {n_initial} sommets.")

    # 2. Boucle de suppression itérative
    # Tant qu'il reste au moins une valeur infinie dans la matrice
    supprimés = 0
    while np.isinf(matrice).any():
        # Compter le nombre d'infinis par ligne
        inf_counts = np.isinf(matrice).sum(axis=1)

        # Trouver l'indice du sommet qui a le PLUS de déconnexions (le plus "isolé")
        idx_to_remove = np.argmax(inf_counts)
        id_supprimé = ids[idx_to_remove]

        # Suppression de la ligne et de la colonne dans la matrice
        matrice = np.delete(matrice, idx_to_remove, axis=0)
        matrice = np.delete(matrice, idx_to_remove, axis=1)

        # Suppression dans la liste des IDs
        ids = np.delete(ids, idx_to_remove)

        supprimés += 1
        if supprimés % 5 == 0:
            print(f" > {supprimés} points retirés... (Sommet actuel le plus isolé : {id_supprimé})")

    # 3. Sauvegarde (Écrasement des fichiers originaux)
    np.save(MAT_FILE, matrice)
    np.save(IDS_FILE, ids)

    print("\n--- NETTOYAGE TERMINÉ ---")
    print(f"Sommets supprimés : {supprimés}")
    print(f"Sommets conservés (Composante Géante) : {len(ids)}")
    print(f"Les fichiers {MAT_FILE} et {IDS_FILE} ont été mis à jour.")

    # Vérification finale de sécurité
    if not np.isinf(matrice).any():
        print("STATUT : La matrice est désormais 100% finie. Prête pour les k-médoïdes.")
