"""
Analyseur principal de projet
"""
import os
import json
import re
from typing import Dict, Optional
from pathlib import Path

from ..core.scanner import ProjectScanner
from .technology import TechnologyAnalyzer
from .framework import FrameworkAnalyzer
from ...monitoring.logger import logger


class ProjectAnalyzer:
    """Analyseur principal pour analyser complètement un projet"""
    
    def __init__(self, project_root: Optional[str] = None):
        self.project_root = Path(project_root or os.getcwd()).resolve()
        self.scanner = ProjectScanner(str(self.project_root))
        self.tech_analyzer = TechnologyAnalyzer(str(self.project_root))
        self.framework_analyzer = FrameworkAnalyzer()
    
    def analyze(self) -> Optional[Dict]:
        """
        Effectue l'analyse complète du projet
        
        Returns:
            Dictionnaire avec tous les résultats d'analyse ou None en cas d'erreur
        """
        try:
            logger('info', f"Analyse du projet: {self.project_root}")
            
            # Scanner la structure et le contenu
            logger('info', "Collecte de la structure du projet...")
            project_tree, file_contents = self.scanner.scan_structure()
            
            # Extraire le nom du projet
            logger('info', "Extraction du nom du projet...")
            project_name = self._extract_project_name(file_contents)
            
            # Analyser les technologies
            logger('info', "Détection des technologies...")
            tech_analysis = self.tech_analyzer.analyze()
            
            # Détecter les frameworks
            logger('info', "Détection des frameworks...")
            detected_frameworks = self.framework_analyzer.detect(file_contents)
            
            # Créer le résultat final
            result = {
                "project_name": project_name,
                "project_root": str(self.project_root),
                "project_structure": project_tree,
                "project_structure_summary": self._create_structure_summary(project_tree, file_contents),
                "technologies": tech_analysis.get('percentages', {}),
                "technologies_details": tech_analysis.get('details', {}),
                "technologies_summary": tech_analysis.get('summary', {}),
                "detected_frameworks": detected_frameworks,
                "file_contents_summary": self._create_content_summary(file_contents),
                "sdk_client_version": "2.0.0"
            }
            
            logger('success', f"Analyse terminée pour le projet '{project_name}'")
            return result
            
        except Exception as e:
            logger('error', f"Erreur durant l'analyse du projet: {e}")
            return None
    
    def _extract_project_name(self, file_contents: Dict[str, str]) -> str:
        """Extrait le nom du projet à partir des fichiers de configuration"""
        
        # Essayer package.json (Node.js)
        for file_path, content in file_contents.items():
            if file_path.endswith('package.json'):
                try:
                    data = json.loads(content)
                    if isinstance(data, dict) and 'name' in data:
                        return data['name']
                except json.JSONDecodeError:
                    continue
        
        # Essayer pyproject.toml (Python)
        for file_path, content in file_contents.items():
            if file_path.endswith('pyproject.toml'):
                # Poetry format
                match = re.search(r'\[tool\.poetry\]\s*name\s*=\s*"([^"]+)"', content)
                if match:
                    return match.group(1)
                
                # PEP 621 format
                match = re.search(r'\[project\]\s*name\s*=\s*"([^"]+)"', content)
                if match:
                    return match.group(1)
        
        # Essayer composer.json (PHP)
        for file_path, content in file_contents.items():
            if file_path.endswith('composer.json'):
                try:
                    data = json.loads(content)
                    if isinstance(data, dict) and 'name' in data:
                        return data['name']
                except json.JSONDecodeError:
                    continue
        
        # Essayer Cargo.toml (Rust)
        for file_path, content in file_contents.items():
            if file_path.endswith('Cargo.toml'):
                match = re.search(r'\[package\]\s*name\s*=\s*"([^"]+)"', content)
                if match:
                    return match.group(1)
        
        # Utiliser le nom du dossier racine comme fallback
        return self.project_root.name
    
    def _create_structure_summary(self, project_tree: Dict, file_contents: Dict) -> Dict:
        """Crée un résumé de la structure du projet"""
        total_files = sum(len(files) for files in project_tree.values())
        total_dirs = len(project_tree)
        
        return {
            "root_dir_name": self.project_root.name,
            "total_files_scanned": total_files,
            "total_directories": total_dirs,
            "key_files_found": [Path(path).name for path in file_contents.keys()],
            "project_size_category": self._categorize_project_size(total_files, total_dirs)
        }
    
    def _create_content_summary(self, file_contents: Dict[str, str]) -> Dict[str, str]:
        """Crée un résumé du contenu des fichiers importants"""
        summary = {}
        
        for file_path, content in file_contents.items():
            if content and not content.startswith('__'):
                # Limiter à 200 caractères pour le résumé
                if len(content) > 200:
                    summary[file_path] = content[:200] + "..."
                else:
                    summary[file_path] = content
        
        return summary
    
    def _categorize_project_size(self, total_files: int, total_dirs: int) -> str:
        """Catégorise la taille du projet"""
        if total_files < 10:
            return "small"
        elif total_files < 50:
            return "medium"
        elif total_files < 200:
            return "large"
        else:
            return "very_large"