"""
Configuration Model
Manejo de la configuración global del sistema
"""

import json
from typing import Dict, List, Any
from pathlib import Path


class Config:
    """Clase para manejar la configuración global del sistema"""

    def __init__(self, config_path: str = None):
        if config_path is None:
            # Buscar config.json en el directorio del proyecto
            current_dir = Path(__file__).parent.parent.parent
            config_path = current_dir / "config.json"

        self.config_path = Path(config_path)
        self._config = {}
        self.load_config()

    def load_config(self) -> None:
        """Cargar configuración desde archivo JSON"""
        try:
            if self.config_path.exists():
                with open(self.config_path, "r", encoding="utf-8") as f:
                    self._config = json.load(f)
            else:
                # Crear configuración por defecto si no existe
                self._create_default_config()
                self.save_config()
        except Exception as e:
            raise Exception(f"Error cargando configuración: {e}")

    def save_config(self) -> None:
        """Guardar configuración actual al archivo JSON"""
        try:
            with open(self.config_path, "w", encoding="utf-8") as f:
                json.dump(self._config, f, indent=2, ensure_ascii=False)
        except Exception as e:
            raise Exception(f"Error guardando configuración: {e}")

    def _create_default_config(self) -> None:
        """Crear configuración por defecto"""
        self._config = {
            "observation_directories": [],
            "backup_destination": "D:\\Backups\\AutoBackups",
            "global_settings": {
                "default_schedule": "daily",
                "default_schedule_time": "02:00",
                "retry_delay_hours": 1,
                "backup_timeout_minutes": 0,
                "min_free_space_mb": 100,
                "scan_interval_minutes": 60,
                "min_backup_interval_minutes": 10,
            },
            "everything_api": {
                "dll_path": "Everything-SDK\\dll\\Everything64.dll",
                "enabled": True,
                "search_depth": -1,
                "skip_last_level_for_s7p": True,
            },
            "web_interface": {"host": "127.0.0.1", "port": 5000, "debug": False},
            "logging": {"level": "INFO", "max_log_files": 30, "log_rotation_days": 30},
            "backup_options": {
                "compression_level": 6,
                "include_subdirectories": True,
                "preserve_directory_structure": True,
                "hash_algorithm": "md5",
                "hash_includes": ["timestamp", "size"],
                "backup_type": "complete",
                "process_priority": "low",
                "sequential_execution": True,
                "filename_format": "HH-MM-SS_projects.zip",
                "date_format": "YYYY-MM-DD",
            },
        }

    # Getters para las secciones principales
    @property
    def observation_directories(self) -> List[Dict[str, Any]]:
        return self._config.get("observation_directories", [])

    @property
    def backup_destination(self) -> str:
        return self._config.get("backup_destination", "")

    @property
    def global_settings(self) -> Dict[str, Any]:
        return self._config.get("global_settings", {})

    @property
    def everything_api(self) -> Dict[str, Any]:
        return self._config.get("everything_api", {})

    @property
    def web_interface(self) -> Dict[str, Any]:
        return self._config.get("web_interface", {})

    @property
    def logging_config(self) -> Dict[str, Any]:
        return self._config.get("logging", {})

    @property
    def backup_options(self) -> Dict[str, Any]:
        return self._config.get("backup_options", {})

    # Métodos de utilidad
    def get_dll_path(self) -> str:
        """Obtener la ruta completa de la DLL de Everything"""
        dll_relative_path = self.everything_api.get("dll_path", "")
        if dll_relative_path:
            # Convertir ruta relativa a absoluta
            current_dir = Path(__file__).parent.parent.parent.parent
            return str(current_dir / dll_relative_path)
        return ""

    def get_min_free_space_mb(self) -> int:
        """Obtener el espacio mínimo libre requerido en MB"""
        return self.global_settings.get("min_free_space_mb", 100)

    def get_scan_interval_minutes(self) -> int:
        """Obtener el intervalo de escaneo en minutos"""
        return self.global_settings.get("scan_interval_minutes", 60)

    def get_min_backup_interval_minutes(self) -> int:
        """Obtener el intervalo mínimo de backup en minutos"""
        return self.global_settings.get("min_backup_interval_minutes", 10)

    def add_observation_directory(
        self, path: str, dir_type: str, description: str = ""
    ) -> None:
        """Agregar un nuevo directorio de observación"""
        new_dir = {
            "path": path,
            "type": dir_type,
            "enabled": True,
            "description": description,
        }
        if "observation_directories" not in self._config:
            self._config["observation_directories"] = []
        self._config["observation_directories"].append(new_dir)
        self.save_config()

    def update_config_value(self, key_path: str, value: Any) -> None:
        """Actualizar un valor específico en la configuración usando dot
        notation"""
        keys = key_path.split(".")
        current = self._config

        # Navegar hasta el penúltimo nivel
        for key in keys[:-1]:
            if key not in current:
                current[key] = {}
            current = current[key]

        # Establecer el valor final
        current[keys[-1]] = value
        self.save_config()

    def get_full_config(self) -> Dict[str, Any]:
        """Obtener toda la configuración actual"""
        return self._config.copy()
