import os
import difflib
from typing import Dict, Any, Optional

def clean_path(path: str) -> str:
    """Limpia la ruta de caracteres innecesarios."""
    if not path:
        return ""
    return path.strip().replace('@', '')


def write_file_tool(path: str, content: str, confirm: bool = False) -> str | Dict[str, Any]:
    """
    Escribe el contenido completo en un archivo.
    Si el archivo existe, mostrará un diff antes de sobrescribirlo para su confirmación.
    """
    path = clean_path(path)
    if not path:
        return {"error": "Path no proporcionado"}
    if content is None:
        return {"error": "Contenido no proporcionado"}

    if not confirm:
        if os.path.exists(path):
            try:
                with open(path, 'r', encoding='utf-8') as f:
                    old_content = f.read()
                diff = "".join(difflib.unified_diff(
                    old_content.splitlines(keepends=True),
                    content.splitlines(keepends=True),
                    fromfile=f"a/{path}",
                    tofile=f"b/{path}",
                ))
            except Exception as e:
                diff = f"No se pudo generar diff: {e}"
        else:
            diff = "".join(difflib.unified_diff(
                [],
                content.splitlines(keepends=True),
                fromfile="/dev/null",
                tofile=f"b/{path}",
            ))
            if not diff:
                diff = f"--- /dev/null\n+++ b/{path}\n@@ -0,0,0 @@\n"

        if diff:
            return {
                "status": "requires_confirmation",
                "action_description": f"escribir en el archivo '{path}'",
                "operation": "write_file_tool",
                "args": {
                    "path": path,
                    "content": content,
                    "confirm": True
                },
                "diff": diff
            }

    try:
        parent_dir = os.path.dirname(path)
        if parent_dir and not os.path.exists(parent_dir):
            os.makedirs(parent_dir, exist_ok=True)

        with open(path, 'w', encoding='utf-8') as f:
            f.write(content)
        return {"status": "success", "message": f"Archivo escrito exitosamente: {path}"}
    except Exception as e:
        return {"error": f"Error al escribir el archivo '{path}': {e}"}


def append_file_tool(path: str, content: str, confirm: bool = False) -> str | Dict[str, Any]:
    """Añade contenido al final de un archivo existente."""
    path = clean_path(path)
    if not path:
        return {"error": "Path no proporcionado"}
    if content is None:
        return {"error": "Contenido no proporcionado"}

    if not confirm:
        return {
            "status": "requires_confirmation",
            "action_description": f"añadir contenido a '{path}'",
            "operation": "append_file_tool",
            "args": {
                "path": path,
                "content": content,
                "confirm": True
            },
            "diff": f"+ (Añadiendo {len(content)} caracteres al final)\n+ {content[:200]}..."
        }

    try:
        with open(path, 'a', encoding='utf-8') as f:
            f.write(content)
        return {"status": "success", "message": f"Contenido añadido exitosamente a: {path}"}
    except Exception as e:
        return {"error": f"Error al añadir a '{path}': {e}"}


def create_directory_tool(path: str) -> str | Dict[str, Any]:
    """Crea un directorio y todos los directorios padres necesarios."""
    if not path:
        return {"error": "Path no proporcionado"}

    try:
        os.makedirs(path, exist_ok=True)
        return {"status": "success", "message": f"Directorio creado exitosamente en: {path}"}
    except Exception as e:
        return {"error": f"Error al crear el directorio '{path}': {e}"}


# Metadata para el sistema de skills
# Estas líneas deben estar DESPUÉS de definir las funciones

write_file_tool.operation_summary = "Escribiendo archivo: {path}"
append_file_tool.operation_summary = "Añadiendo contenido a: {path}"
create_directory_tool.operation_summary = "Creando directorio: {path}"

# Schema de parámetros para write_file_tool (herramienta principal del módulo)
write_file_tool.parameters_schema = {
    "type": "object",
    "properties": {
        "path": {"type": "string", "description": "Ruta del archivo a escribir"},
        "content": {"type": "string", "description": "Contenido a escribir"},
        "confirm": {"type": "boolean", "description": "False=pide confirmación, True=aplica directamente"}
    },
    "required": ["path", "content"]
}
write_file_tool.name = "write_file_tool"
write_file_tool.description = "Escribe contenido completo en un archivo (sobrescribe). Llama primero con confirm=False para ver diff."

append_file_tool.parameters_schema = {
    "type": "object",
    "properties": {
        "path": {"type": "string", "description": "Ruta del archivo"},
        "content": {"type": "string", "description": "Contenido a añadir"},
        "confirm": {"type": "boolean", "description": "False=pide confirmación, True=aplica directamente"}
    },
    "required": ["path", "content"]
}
append_file_tool.name = "append_file_tool"
append_file_tool.description = "Añade contenido al final de un archivo existente."

create_directory_tool.parameters_schema = {
    "type": "object",
    "properties": {
        "path": {"type": "string", "description": "Ruta del directorio a crear"}
    },
    "required": ["path"]
}
create_directory_tool.name = "create_directory_tool"
create_directory_tool.description = "Crea un directorio y todos los directorios padres necesarios."