import os
import re
from pathlib import Path
from collections import defaultdict

from .config import (
    CORPUS_DIR
)

def composant_match(nom_composant, nom_dossier):
    """
    Vérifie si le nom du composant correspond approximativement à un nom de dossier (lettres et chiffres dans le même ordre).
    """
    def clean(s):
        return ''.join(c.lower() for c in s if c.isalnum())

    cleaned_comp = clean(nom_composant)
    cleaned_dir = clean(nom_dossier)

    # Vérifie que chaque caractère de cleaned_comp est présent dans cleaned_dir dans le bon ordre
    it = iter(cleaned_dir)
    return all(c in it for c in cleaned_comp)

def trouver_dossier_composant(nom_composant, base_path, prefixe):
    """
    Parcourt les sous-répertoires de base_path et retourne celui qui correspond au composant.
    """
    search_path = os.path.join(CORPUS_DIR, base_path)
    if not os.path.exists(search_path):
        return None

    for d in os.listdir(search_path):
        if os.path.isdir(os.path.join(search_path, d)):
            if composant_match(f"{prefixe}{nom_composant}", d):
                return os.path.join(base_path, d)
    return None

def extraire_sections_par_mot_cle(fichier_markdown: Path) -> dict:
    """
    Extrait les sections de niveau 3 uniquement dans la section
    '## Chaînes avec risque critique' du fichier Markdown,
    et les regroupe par mot-clé (ce qui se trouve entre '### ' et ' →').
    Réduit chaque titre d’un niveau (#).
    """
    with fichier_markdown.open(encoding="utf-8") as f:
        contenu = f.read()

    # Extraire uniquement la section '## Chaînes avec risque critique'
    match_section = re.search(
        r"## Chaînes avec risque critique(.*?)(?=\n## |\Z)", contenu, re.DOTALL
    )
    if not match_section:
        return {}

    section_critique = match_section.group(1)

    # Extraire les mots-clés entre '### ' et ' →'
    mots_cles = set(re.findall(r"^### (.+?) →", section_critique, re.MULTILINE))

    # Extraire tous les blocs de niveau 3 dans cette section uniquement
    blocs_sections = re.findall(r"(### .+?)(?=\n### |\n## |\Z)", section_critique, re.DOTALL)

    # Regrouper les blocs par mot-clé
    regroupement = defaultdict(list)
    for bloc in blocs_sections:
        match = re.match(r"### (.+?) →", bloc)
        if match:
            mot = match.group(1)
            if mot in mots_cles:
                # Réduction du niveau des titres
                bloc_modifie = re.sub(r"^###", "##", bloc, flags=re.MULTILINE)
                bloc_modifie = re.sub(r"^###", "##", bloc_modifie, flags=re.MULTILINE)
                regroupement[mot].append(bloc_modifie)

    return {mot: "\n\n".join(blocs) for mot, blocs in regroupement.items()}

def nettoyer_texte_fr(texte: str) -> str:
    # Apostrophes droites -> typographiques
    texte = texte.replace("'", "’")
    # Guillemets droits -> guillemets français (avec espace fine insécable)
    texte = re.sub(r'"(.*?)"', r'« \1 »', texte)
    # Espaces fines insécables avant : ; ! ?
    texte = re.sub(r' (?=[:;!?])', '\u202F', texte)
    # Unités : espace insécable entre chiffre et unité
    texte = re.sub(r'(\d) (?=\w+)', lambda m: f"{m.group(1)}\u202F", texte)
    # Suppression des doubles espaces
    texte = re.sub(r' {2,}', ' ', texte)
    # Remplacement optionnel des tirets simples (optionnel)
    texte = texte.replace(" - ", " – ")
    # Nettoyage ponctuation multiple accidentelle
    texte = re.sub(r'\s+([.,;!?])', r'\1', texte)
    return texte
