#!/usr/bin/env python3
import os
import re
import yaml
import requests
import argparse
import logging

# Import des fonctions de génération
from app.fiches.generer import (
    generer_fiche
)
from app.fiches.utils.fiche_utils import load_seuils
from utils.gitea import charger_arborescence_fiches
from config import GITEA_TOKEN, FICHES_CRITICITE

# Configuration du logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("batch_generation.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

def get_fiche_type(md_source):
    """Extrait le type de fiche depuis le frontmatter YAML."""
    front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md_source)
    if not front_match:
        return "autre"

    context = yaml.safe_load(front_match.group(1))
    return context.get("type_fiche", "autre")

def get_indice_court(md_source):
    """Extrait l'indice court depuis le frontmatter YAML."""
    front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md_source)
    if not front_match:
        return None

    context = yaml.safe_load(front_match.group(1))
    return context.get("indice_court")

def batch_generate_fiches(output_dir="", force_regenerate=False):
    """Génère toutes les fiches en batch en suivant un ordre de priorité."""
    # Assurer que les répertoires de sortie existent
    if output_dir:
        os.makedirs(output_dir, exist_ok=True)

    # Toujours créer les répertoires nécessaires
    os.makedirs(os.path.join("Fiches"), exist_ok=True)
    os.makedirs(os.path.join("HTML"), exist_ok=True)
    os.makedirs(os.path.join("static", "Fiches"), exist_ok=True)

    # Charger les seuils
    try:
        seuils = load_seuils("assets/config.yaml")
        logger.info("Seuils chargés avec succès")
    except Exception as e:
        logger.error(f"Erreur lors du chargement des seuils: {e}")
        return

    # Charger l'arborescence des fiches
    try:
        arborescence = charger_arborescence_fiches()
        logger.info(f"Arborescence chargée: {len(arborescence)} dossiers trouvés")
    except Exception as e:
        logger.error(f"Erreur lors du chargement de l'arborescence: {e}")
        return

    # Créer une liste de toutes les fiches avec leurs informations
    toutes_fiches = []
    for dossier, fiches in arborescence.items():
        for fiche in fiches:
            toutes_fiches.append({
                "dossier": dossier,
                "nom": fiche["nom"],
                "download_url": fiche["download_url"],
                "type": fiche.get("type", "autre")
            })

    logger.info(f"Total de {len(toutes_fiches)} fiches à traiter")

    # Organisation des fiches par type pour respecter l'ordre de priorité
    fiches_par_type = {
        "criticite": [],
        "assemblage": [],
        "fabrication": [],
        "minerai": [],
        "autre": []
    }

    # Télécharger et catégoriser les fiches
    headers = {"Authorization": f"token {GITEA_TOKEN}"}

    # Création des listes spécifiques pour faciliter le traitement ordonné
    fiches_criticite = []
    autres_fiches = []

    # Première étape : identifier les fiches de criticité
    logger.info("Identification des fiches de criticité...")
    for fiche in toutes_fiches:
        # Vérifier si c'est une fiche de criticité par deux méthodes
        est_criticite = False

        # Méthode 1: vérifier par le nom du fichier
        if fiche["nom"] in FICHES_CRITICITE:
            est_criticite = True
            logger.info(f"Fiche de criticité identifiée par nom: {fiche['nom']}")

        # Méthode 2: vérifier par le dossier
        elif fiche["dossier"] == "Criticités":
            est_criticite = True
            logger.info(f"Fiche de criticité identifiée par dossier: {fiche['nom']}")

        if est_criticite:
            fiches_criticite.append(fiche)
        else:
            autres_fiches.append(fiche)

    # Traiter d'abord les fiches de criticité
    logger.info(f"Traitement prioritaire des fiches de criticité ({len(fiches_criticite)} fiches)")
    criticite_count = 0

    for fiche in fiches_criticite:
        try:
            # Télécharger la fiche de criticité
            reponse = requests.get(fiche["download_url"], headers=headers)
            reponse.raise_for_status()
            md_source = reponse.text

            # Générer immédiatement la fiche de criticité
            logger.info(f"Génération prioritaire de la fiche de criticité: {fiche['dossier']}/{fiche['nom']}")
            generer_fiche(md_source, fiche["dossier"], fiche["nom"], seuils)

            # Ajouter à la liste pour le décompte
            fiches_par_type["criticite"].append(fiche)
            criticite_count += 1
        except Exception as e:
            logger.error(f"Erreur lors de la génération de la fiche de criticité {fiche['nom']}: {e}")

    logger.info(f"{criticite_count} fiches de criticité générées")

    # Maintenant catégoriser et traiter les fiches restantes (non-criticité)
    for fiche in autres_fiches:
        try:
            # Télécharger le contenu pour déterminer le type
            reponse = requests.get(fiche["download_url"], headers=headers)
            reponse.raise_for_status()
            md_source = reponse.text

            # Déterminer le type
            type_fiche = get_fiche_type(md_source)
            if type_fiche in fiches_par_type:
                fiches_par_type[type_fiche].append({**fiche, "md_source": md_source})
            else:
                fiches_par_type["autre"].append({**fiche, "md_source": md_source})

        except Exception as e:
            logger.error(f"Erreur lors du traitement de {fiche['nom']}: {e}")

    # Ordre de traitement pour les fiches restantes
    ordre_types = ["assemblage", "fabrication", "minerai", "autre"]

    # Générer les fiches restantes dans l'ordre spécifié
    for type_fiche in ordre_types:
        logger.info(f"Traitement des fiches de type '{type_fiche}' ({len(fiches_par_type[type_fiche])} fiches)")

        for fiche in fiches_par_type[type_fiche]:
            try:
                md_source = fiche["md_source"]
                dossier = fiche["dossier"]
                nom_fichier = fiche["nom"]

                # Vérifier si la génération est nécessaire
                html_path = os.path.join("HTML", dossier, os.path.splitext(nom_fichier)[0] + ".html")
                if force_regenerate or not os.path.exists(html_path):
                    logger.info(f"Génération de {dossier}/{nom_fichier}")
                    generer_fiche(md_source, dossier, nom_fichier, seuils)
                else:
                    logger.info(f"Ignoré (déjà généré): {dossier}/{nom_fichier}")

            except Exception as e:
                logger.error(f"Erreur lors de la génération de {fiche['nom']}: {e}")

    logger.info("Génération batch terminée")

def main():
    parser = argparse.ArgumentParser(description="Générateur batch de fiches")
    parser.add_argument("--output", "-o", default="", help="Répertoire de sortie (laissez vide pour utiliser les dossiers de l'application)")
    parser.add_argument("--force", "-f", action="store_true", help="Forcer la régénération de toutes les fiches")
    args = parser.parse_args()

    logger.info(f"Démarrage de la génération batch (output: {args.output if args.output else 'dossiers par défaut'}, force: {args.force})")
    batch_generate_fiches(output_dir=args.output, force_regenerate=args.force)

if __name__ == "__main__":
    main()
