import os
import shutil
from pathlib import Path
import re

class ClaudeProjectOrganizer:
    def __init__(self):
        self.source_dir = Path.cwd()
        self.claude_dir = self.source_dir / 'claude'
        self.file_mapping = {}
        
    def should_skip_directory(self, dir_name):
        skip_dirs = {'.git', '__pycache__', 'venv', 'env', '.pytest_cache', '.vscode', 'claude'}
        return dir_name in skip_dirs
    
    def get_comment_prefix(self, file_extension):
        """Determina el prefijo de comentario según la extensión del archivo"""
        comment_styles = {
            '.py': '#',
            '.js': '//',
            '.css': '/*',
            '.html': '<!--',
            '.scss': '//',
            '.less': '//',
            '.tsx': '//',
            '.ts': '//',
            '.jsx': '//',
        }
        return comment_styles.get(file_extension.lower(), None)
    
    def get_comment_suffix(self, file_extension):
        """Determina el sufijo de comentario si es necesario"""
        comment_suffixes = {
            '.css': ' */',
            '.html': ' -->',
        }
        return comment_suffixes.get(file_extension.lower(), '')

    def normalize_path(self, path_str: str) -> str:
        """Normaliza la ruta usando forward slashes"""
        return str(path_str).replace('\\', '/')

    def check_existing_path_comment(self, content: str, normalized_path: str, comment_prefix: str) -> bool:
        """Verifica si ya existe un comentario con la ruta en el archivo"""
        # Escapar caracteres especiales en el prefijo de comentario para regex
        escaped_prefix = re.escape(comment_prefix)
        
        # Crear patrones para buscar tanto forward como backward slashes
        forward_pattern = f"{escaped_prefix}\\s*{re.escape(normalized_path)}\\b"
        backward_path = normalized_path.replace('/', '\\\\')  # Doble backslash para el patrón
        backward_pattern = f"{escaped_prefix}\\s*{re.escape(backward_path)}"
        
        # Buscar en las primeras líneas del archivo
        first_lines = content.split('\n')[:5]
        for line in first_lines:
            if (re.search(forward_pattern, line) or 
                re.search(backward_pattern, line)):
                return True
        return False
    
    def add_path_comment(self, file_path: Path, content: str) -> str:
        """Agrega un comentario con la ruta al inicio del archivo si no existe"""
        relative_path = file_path.relative_to(self.source_dir)
        normalized_path = self.normalize_path(relative_path)
        comment_prefix = self.get_comment_prefix(file_path.suffix)
        
        if comment_prefix is None:
            return content
            
        comment_suffix = self.get_comment_suffix(file_path.suffix)
        
        # Verificar si ya existe el comentario
        if self.check_existing_path_comment(content, normalized_path, comment_prefix):
            print(f"  - Comentario de ruta ya existe en {file_path}")
            return content
        
        path_comment = f"{comment_prefix} {normalized_path}{comment_suffix}\n"
        
        # Para archivos HTML, insertar después del doctype si existe
        if file_path.suffix.lower() == '.html':
            if content.lower().startswith('<!doctype'):
                doctype_end = content.find('>') + 1
                return content[:doctype_end] + '\n' + path_comment + content[doctype_end:]
        
        return path_comment + content
    
    def clean_claude_directory(self):
        if self.claude_dir.exists():
            shutil.rmtree(self.claude_dir)
        self.claude_dir.mkdir()
        print(f"Directorio claude limpiado: {self.claude_dir}")
    
    def copy_files(self):
        self.clean_claude_directory()
        
        for root, dirs, files in os.walk(self.source_dir):
            dirs[:] = [d for d in dirs if not self.should_skip_directory(d)]
            current_path = Path(root)
            
            for file in files:
                file_path = current_path / file
                
                if file.endswith(('.py', '.js', '.css', '.html', '.json', '.yml', '.yaml', 
                                '.tsx', '.ts', '.jsx', '.scss', '.less')):
                    target_path = self.claude_dir / file
                    
                    # Si el archivo ya existe en el directorio claude, agregar un sufijo numérico
                    if target_path.exists():
                        base = target_path.stem
                        ext = target_path.suffix
                        counter = 1
                        while target_path.exists():
                            target_path = self.claude_dir / f"{base}_{counter}{ext}"
                            counter += 1
                    
                    try:
                        # Leer el contenido del archivo
                        with open(file_path, 'r', encoding='utf-8') as f:
                            content = f.read()
                        
                        # Agregar el comentario con la ruta si no existe
                        modified_content = self.add_path_comment(file_path, content)
                        
                        # Escribir el nuevo contenido
                        with open(target_path, 'w', encoding='utf-8', newline='\n') as f:
                            f.write(modified_content)
                            
                        self.file_mapping[str(file_path)] = target_path.name
                        print(f"Copiado: {file_path} -> {target_path}")
                            
                    except UnicodeDecodeError:
                        print(f"Advertencia: No se pudo procesar {file_path} como texto. Copiando sin modificar...")
                        shutil.copy2(file_path, target_path)
                    except Exception as e:
                        print(f"Error procesando {file_path}: {str(e)}")
    
    def generate_tree_report(self):
        """Genera el reporte en formato árbol visual"""
        report = ["Estructura del proyecto original:\n"]
        
        def add_to_report(path, prefix="", is_last=True):
            report.append(prefix + ("└── " if is_last else "├── ") + path.name)
            
            if path.is_dir() and not self.should_skip_directory(path.name):
                children = sorted(path.iterdir(), key=lambda x: (x.is_file(), x.name))
                children = [c for c in children if not (c.is_dir() and self.should_skip_directory(c.name))]
                
                for i, child in enumerate(children):
                    is_last_child = i == len(children) - 1
                    new_prefix = prefix + ("    " if is_last else "│   ")
                    add_to_report(child, new_prefix, is_last_child)
        
        add_to_report(self.source_dir)
        
        report_path = self.claude_dir / "project_structure.txt"
        with open(report_path, "w", encoding="utf-8") as f:
            f.write("\n".join(report))
        print(f"\nReporte generado en: {report_path}")

def main():
    try:
        print("Iniciando organización de archivos para Claude...")
        organizer = ClaudeProjectOrganizer()
        organizer.copy_files()
        organizer.generate_tree_report()
        print("\n¡Proceso completado exitosamente!")
    except Exception as e:
        print(f"\nError durante la ejecución: {str(e)}")

if __name__ == "__main__":
    main()