"""
Scanner de projet pour analyser la structure des fichiers
"""
import os
from typing import Dict, List, Tuple, Set
from pathlib import Path

from ..utils.constants import IGNORED_DIRS, IGNORED_FILE_PREFIXES, FILES_TO_ANALYZE
from .reader import FileReader


class ProjectScanner:
    """Scanner pour analyser la structure complète d'un projet"""
    
    def __init__(self, root_path: str):
        self.root_path = Path(root_path).resolve()
        self.reader = FileReader()
        
    def scan_structure(self) -> Tuple[Dict[str, List[str]], Dict[str, str]]:
        """
        Scanne la structure complète du projet
        
        Returns:
            Tuple[project_tree, file_contents] où:
            - project_tree: structure des répertoires et fichiers
            - file_contents: contenu des fichiers importants
        """
        project_tree = {}
        file_contents = {}
        
        for current_root, dirs, files in os.walk(self.root_path, topdown=True):
            # Filtrer les répertoires ignorés
            dirs[:] = [d for d in dirs if d not in IGNORED_DIRS and not d.startswith('.')]
            
            # Calculer le chemin relatif
            relative_path = self._get_relative_path(current_root)
            
            # Filtrer les fichiers
            filtered_files = self._filter_files(files)
            project_tree[relative_path] = filtered_files
            
            # Lire le contenu des fichiers importants
            for file_name in filtered_files:
                if self._should_analyze_file(file_name):
                    file_path = os.path.join(current_root, file_name)
                    content = self.reader.read_text(file_path)
                    if content and not content.startswith('__'):
                        file_contents[file_path] = content
        
        return project_tree, file_contents
    
    def scan_files_by_extension(self) -> Dict[str, int]:
        """
        Compte les fichiers par extension
        
        Returns:
            Dictionnaire extension -> nombre de fichiers
        """
        extension_counts = {}
        
        for current_root, dirs, files in os.walk(self.root_path, topdown=True):
            dirs[:] = [d for d in dirs if d not in IGNORED_DIRS]
            
            for file_name in files:
                if self._should_count_file(file_name):
                    _, ext = os.path.splitext(file_name.lower())
                    if ext:
                        extension_counts[ext] = extension_counts.get(ext, 0) + 1
        
        return extension_counts
    
    def find_key_files(self) -> List[str]:
        """
        Trouve les fichiers clés du projet
        
        Returns:
            Liste des chemins des fichiers clés trouvés
        """
        key_files = []
        
        for current_root, dirs, files in os.walk(self.root_path, topdown=True):
            dirs[:] = [d for d in dirs if d not in IGNORED_DIRS]
            
            for file_name in files:
                if file_name in FILES_TO_ANALYZE:
                    file_path = os.path.join(current_root, file_name)
                    key_files.append(file_path)
        
        return key_files
    
    def _get_relative_path(self, current_root: str) -> str:
        """Calcule le chemin relatif depuis la racine du projet"""
        relative = os.path.relpath(current_root, self.root_path)
        return '.' if relative == '.' else relative
    
    def _filter_files(self, files: List[str]) -> List[str]:
        """Filtre les fichiers à ignorer"""
        return [
            f for f in files 
            if not any(f.startswith(prefix) for prefix in IGNORED_FILE_PREFIXES)
            and f not in {'.DS_Store', 'Thumbs.db', 'desktop.ini'}
        ]
    
    def _should_analyze_file(self, file_name: str) -> bool:
        """Détermine si un fichier doit être analysé pour son contenu"""
        return file_name in FILES_TO_ANALYZE
    
    def _should_count_file(self, file_name: str) -> bool:
        """Détermine si un fichier doit être compté dans les statistiques"""
        return (
            not any(file_name.startswith(prefix) for prefix in IGNORED_FILE_PREFIXES)
            and file_name not in {'.DS_Store', 'Thumbs.db', 'desktop.ini'}
            and not file_name.endswith('.pyc')
        )