#!/usr/bin/env python3
"""
Script pour extraire des lots de tickets Odoo par critères (projet, statut, etc.).
Ce script permet d'automatiser la récupération de nombreux tickets en évitant
de recharger des tickets déjà traités.
"""

import os
import sys
import json
import logging
import argparse
from datetime import datetime
from .auth_manager import AuthManager
from .ticket_manager import TicketManager
from .batch_ticket_manager import BatchTicketManager
from .retrieve_ticket import load_config
from core.utils import setup_logging, log_separator

def retrieve_tickets_batch(domain=None, limit=50, offset=0, output=None, config_file="config.json", 
                          verbose=False, skip_existing=True):
    """
    Extrait un lot de tickets répondant à des critères spécifiques.
    
    Args:
        domain: Liste de critères de recherche au format Odoo 
                ex: [["project_id", "=", 1], ["stage_id", "=", 5]]
        limit: Nombre maximal de tickets à extraire
        offset: Index de départ pour la pagination
        output: Répertoire de sortie
        config_file: Chemin vers le fichier de configuration
        verbose: Mode verbeux pour les logs
        skip_existing: Ignorer les tickets déjà extraits
        
    Returns:
        Dictionnaire avec le résultat de l'opération ou None en cas d'erreur
    """
    config = load_config(config_file)
    
    # Si config est vide, initialiser avec des valeurs par défaut
    if not config:
        logging.error("Impossible de charger la configuration, utilisation des valeurs par défaut")
        config = {"odoo": {}, "output_dir": "output"}
    
    # Configurer la journalisation
    log_level = logging.DEBUG if verbose else logging.INFO
    setup_logging(log_level, "retrieve_tickets_batch.log")
    
    # Extraire les informations de connexion
    odoo_config = config.get("odoo", {})
    url = odoo_config.get("url")
    db = odoo_config.get("db")
    username = odoo_config.get("username")
    api_key = odoo_config.get("api_key")
    
    if not all([url, db, username, api_key]):
        logging.error("Informations de connexion Odoo manquantes dans le fichier de configuration")
        return None
    
    # Définir le répertoire de sortie
    base_output_dir = output or config.get("output_dir", "output")
    
    logging.info(f"Démarrage de l'extraction par lot avec les critères: {domain}")
    logging.info(f"Limite: {limit} tickets, offset: {offset}")
    log_separator()
    
    try:
        # Initialiser les gestionnaires
        auth_manager = AuthManager(
            url=url,
            db=db,
            username=username,
            api_key=api_key
        )
        
        if not auth_manager.login():
            logging.error("Échec de l'authentification à Odoo")
            return None
        
        # Initialiser les gestionnaires
        ticket_manager = TicketManager(auth_manager)
        batch_manager = BatchTicketManager(ticket_manager)
        
        # Vérifier combien de tickets correspondent aux critères
        total_count = batch_manager.get_ticket_count(domain)
        logging.info(f"Nombre total de tickets correspondant aux critères: {total_count}")
        
        if total_count == 0:
            logging.warning("Aucun ticket ne correspond aux critères spécifiés")
            return {"status": "warning", "message": "Aucun ticket ne correspond aux critères"}
        
        # Extraire les tickets par lot
        result = batch_manager.extract_tickets_batch(
            domain=domain, 
            limit=limit, 
            offset=offset, 
            base_output_dir=base_output_dir,
            skip_existing=skip_existing
        )
        
        # Afficher le résumé
        log_separator()
        logging.info(f"Extraction par lot terminée")
        logging.info(f"Tickets traités: {result.get('processed', 0)}")
        logging.info(f"Tickets ignorés: {result.get('skipped', 0)}")
        logging.info(f"Tickets exclus par tag 'BRG-LAB WIN': {result.get('excluded_by_tag', 0)}")
        logging.info(f"Répertoire: {result.get('batch_dir', '')}")
        log_separator()
        
        # Afficher les tickets exclus à cause du tag "BRG-LAB WIN"
        excluded_tickets = result.get('excluded_tickets', [])
        if excluded_tickets:
            print("\nLes tickets suivants ont été exclus car ils possèdent le tag 'BRG-LAB WIN':")
            for ticket in excluded_tickets:
                print(f"- {ticket.get('code', 'Code inconnu')}: {ticket.get('name', 'Nom inconnu')}")
            print(f"Total: {len(excluded_tickets)} ticket(s) exclu(s)")
            print("Ces tickets sont exclus de l'extraction conformément à la politique.")
        
        return result
        
    except Exception as e:
        logging.exception(f"Une erreur est survenue: {e}")
        return None

def list_projects(config_file="config.json"):
    """
    Liste tous les projets disponibles dans Odoo.
    
    Args:
        config_file: Chemin vers le fichier de configuration
        
    Returns:
        Liste des projets ou None en cas d'erreur
    """
    config = load_config(config_file)
    
    # Extraire les informations de connexion
    odoo_config = config.get("odoo", {})
    url = odoo_config.get("url")
    db = odoo_config.get("db")
    username = odoo_config.get("username")
    api_key = odoo_config.get("api_key")
    
    if not all([url, db, username, api_key]):
        print("Informations de connexion Odoo manquantes dans le fichier de configuration")
        return None
    
    try:
        # Initialiser les gestionnaires
        auth_manager = AuthManager(
            url=url,
            db=db,
            username=username,
            api_key=api_key
        )
        
        if not auth_manager.login():
            print("Échec de l'authentification à Odoo")
            return None
        
        # Récupérer la liste des projets
        ticket_manager = TicketManager(auth_manager)
        batch_manager = BatchTicketManager(ticket_manager)
        projects = batch_manager.get_projects()
        
        if not projects:
            print("Aucun projet trouvé")
            return None
        
        print("\nListe des projets disponibles:")
        print("-" * 50)
        for project in projects:
            print(f"ID: {project['id']}, Nom: {project['name']}")
        print("-" * 50)
        
        return projects
        
    except Exception as e:
        print(f"Une erreur est survenue: {e}")
        return None

def list_stages(config_file="config.json"):
    """
    Liste tous les statuts (étapes) disponibles dans Odoo.
    
    Args:
        config_file: Chemin vers le fichier de configuration
        
    Returns:
        Liste des étapes ou None en cas d'erreur
    """
    config = load_config(config_file)
    
    # Extraire les informations de connexion
    odoo_config = config.get("odoo", {})
    url = odoo_config.get("url")
    db = odoo_config.get("db")
    username = odoo_config.get("username")
    api_key = odoo_config.get("api_key")
    
    if not all([url, db, username, api_key]):
        print("Informations de connexion Odoo manquantes dans le fichier de configuration")
        return None
    
    try:
        # Initialiser les gestionnaires
        auth_manager = AuthManager(
            url=url,
            db=db,
            username=username,
            api_key=api_key
        )
        
        if not auth_manager.login():
            print("Échec de l'authentification à Odoo")
            return None
        
        # Récupérer la liste des étapes
        ticket_manager = TicketManager(auth_manager)
        batch_manager = BatchTicketManager(ticket_manager)
        stages = batch_manager.get_stages()
        
        if not stages:
            print("Aucune étape trouvée")
            return None
        
        print("\nListe des étapes disponibles:")
        print("-" * 50)
        for stage in stages:
            print(f"ID: {stage['id']}, Nom: {stage['name']}")
        print("-" * 50)
        
        return stages
        
    except Exception as e:
        print(f"Une erreur est survenue: {e}")
        return None

def parse_domain(domain_str):
    """
    Convertit une chaîne de critères en domaine Odoo.
    Format attendu: "field1:op1:value1;field2:op2:value2"
    Exemple: "project_id:=:1;stage_id:=:5"
    
    Args:
        domain_str: Chaîne de critères
        
    Returns:
        Liste de critères au format Odoo
    """
    if not domain_str:
        return []
    
    domain = []
    criteria = domain_str.split(";")
    
    for criterion in criteria:
        if not criterion:
            continue
            
        parts = criterion.split(":")
        if len(parts) != 3:
            print(f"Format invalide pour le critère: {criterion}")
            continue
            
        field, operator, value = parts
        
        # Convertir value en entier si possible
        try:
            if value.isdigit():
                value = int(value)
            elif value.lower() == "true":
                value = True
            elif value.lower() == "false":
                value = False
        except:
            pass
            
        domain.append([field, operator, value])
    
    return domain

def parse_arguments():
    parser = argparse.ArgumentParser(description="Récupère des tickets Odoo par lots selon des critères.")
    subparsers = parser.add_subparsers(dest="command", help="Commande à exécuter")
    
    # Commande pour extraire un lot de tickets
    batch_parser = subparsers.add_parser("batch", help="Extrait un lot de tickets")
    batch_parser.add_argument("--domain", "-d", help="Critères de recherche (format: field1:op1:value1;field2:op2:value2)")
    batch_parser.add_argument("--project", "-p", type=int, help="ID du projet")
    batch_parser.add_argument("--stage", "-s", type=int, help="ID de l'étape/statut")
    batch_parser.add_argument("--limit", "-l", type=int, default=50, help="Nombre maximum de tickets à extraire")
    batch_parser.add_argument("--offset", "-o", type=int, default=0, help="Index de départ pour la pagination")
    batch_parser.add_argument("--output", help="Répertoire de sortie")
    batch_parser.add_argument("--include-existing", action="store_true", help="Inclure les tickets déjà extraits")
    batch_parser.add_argument("--config", "-c", default="config.json", help="Fichier de configuration")
    batch_parser.add_argument("--verbose", "-v", action="store_true", help="Mode verbeux")
    
    # Commande pour lister les projets
    projects_parser = subparsers.add_parser("projects", help="Liste les projets disponibles")
    projects_parser.add_argument("--config", "-c", default="config.json", help="Fichier de configuration")
    
    # Commande pour lister les étapes
    stages_parser = subparsers.add_parser("stages", help="Liste les étapes/statuts disponibles")
    stages_parser.add_argument("--config", "-c", default="config.json", help="Fichier de configuration")
    
    # Commande pour extraire un ticket unique (compatibilité avec retrieve_ticket.py)
    ticket_parser = subparsers.add_parser("ticket", help="Extrait un ticket unique par son code")
    ticket_parser.add_argument("ticket_code", help="Code du ticket à extraire")
    ticket_parser.add_argument("--output", help="Répertoire de sortie")
    ticket_parser.add_argument("--config", "-c", default="config.json", help="Fichier de configuration")
    ticket_parser.add_argument("--verbose", "-v", action="store_true", help="Mode verbeux")
    
    return parser.parse_args()

def main():
    args = parse_arguments()
    
    if args.command == "projects":
        list_projects(args.config)
        
    elif args.command == "stages":
        list_stages(args.config)
        
    elif args.command == "ticket":
        # Compatibilité avec retrieve_ticket.py
        from .retrieve_ticket import retrieve_ticket
        
        result = retrieve_ticket(
            ticket_code=args.ticket_code,
            output=args.output,
            config_file=args.config,
            verbose=args.verbose
        )
        
        if not result:
            sys.exit(1)
            
    elif args.command == "batch":
        # Construire le domaine à partir des options
        domain = []
        
        if args.domain:
            domain = parse_domain(args.domain)
        
        # Ajouter project_id et stage_id si spécifiés
        if args.project:
            domain.append(["project_id", "=", args.project])
            
        if args.stage:
            domain.append(["stage_id", "=", args.stage])
        
        result = retrieve_tickets_batch(
            domain=domain,
            limit=args.limit,
            offset=args.offset,
            output=args.output,
            config_file=args.config,
            verbose=args.verbose,
            skip_existing=not args.include_existing
        )
        
        if not result or result.get("status") == "error":
            sys.exit(1)
    
    else:
        # Aucune commande spécifiée, afficher l'aide
        parser = argparse.ArgumentParser(description="Récupère des tickets Odoo par lots selon des critères.")
        parser.print_help()
        sys.exit(1)

if __name__ == "__main__":
    main()