"""
Linux BenchTools - YAML Configuration Loader
Load and manage YAML configuration files
"""

import os
import yaml
from typing import Dict, Any, List, Optional
from pathlib import Path


class YAMLConfigLoader:
    """YAML configuration file loader"""

    def __init__(self, config_dir: str = "./config"):
        """
        Initialize YAML loader

        Args:
            config_dir: Directory containing YAML config files
        """
        self.config_dir = config_dir
        self._cache = {}

    def load_config(self, filename: str, force_reload: bool = False) -> Dict[str, Any]:
        """
        Load a YAML configuration file

        Args:
            filename: YAML filename (without path)
            force_reload: Force reload even if cached

        Returns:
            Parsed YAML data as dictionary
        """
        if not force_reload and filename in self._cache:
            return self._cache[filename]

        filepath = os.path.join(self.config_dir, filename)

        if not os.path.exists(filepath):
            return {}

        with open(filepath, 'r', encoding='utf-8') as f:
            data = yaml.safe_load(f) or {}

        self._cache[filename] = data
        return data

    def save_config(self, filename: str, data: Dict[str, Any]) -> bool:
        """
        Save a YAML configuration file

        Args:
            filename: YAML filename (without path)
            data: Dictionary to save

        Returns:
            True if successful
        """
        filepath = os.path.join(self.config_dir, filename)

        # Ensure directory exists
        os.makedirs(self.config_dir, exist_ok=True)

        try:
            with open(filepath, 'w', encoding='utf-8') as f:
                yaml.safe_dump(data, f, allow_unicode=True, sort_keys=False, indent=2)

            # Update cache
            self._cache[filename] = data
            return True
        except Exception as e:
            print(f"Error saving YAML config: {e}")
            return False

    def get_peripheral_types(self) -> List[Dict[str, Any]]:
        """
        Get peripheral types configuration

        Returns:
            List of peripheral type definitions
        """
        config = self.load_config("peripheral_types.yaml")
        return config.get("peripheral_types", [])

    def get_peripheral_type(self, type_id: str) -> Optional[Dict[str, Any]]:
        """
        Get specific peripheral type configuration

        Args:
            type_id: Peripheral type ID

        Returns:
            Peripheral type definition or None
        """
        types = self.get_peripheral_types()
        for ptype in types:
            if ptype.get("id") == type_id:
                return ptype
        return None

    def add_peripheral_type(self, type_data: Dict[str, Any]) -> bool:
        """
        Add a new peripheral type

        Args:
            type_data: Peripheral type definition

        Returns:
            True if successful
        """
        config = self.load_config("peripheral_types.yaml", force_reload=True)

        if "peripheral_types" not in config:
            config["peripheral_types"] = []

        # Check if type already exists
        existing_ids = [t.get("id") for t in config["peripheral_types"]]
        if type_data.get("id") in existing_ids:
            return False

        config["peripheral_types"].append(type_data)
        return self.save_config("peripheral_types.yaml", config)

    def update_peripheral_type(self, type_id: str, type_data: Dict[str, Any]) -> bool:
        """
        Update an existing peripheral type

        Args:
            type_id: Peripheral type ID to update
            type_data: New peripheral type definition

        Returns:
            True if successful
        """
        config = self.load_config("peripheral_types.yaml", force_reload=True)

        if "peripheral_types" not in config:
            return False

        # Find and update
        for i, ptype in enumerate(config["peripheral_types"]):
            if ptype.get("id") == type_id:
                config["peripheral_types"][i] = type_data
                return self.save_config("peripheral_types.yaml", config)

        return False

    def delete_peripheral_type(self, type_id: str) -> bool:
        """
        Delete a peripheral type

        Args:
            type_id: Peripheral type ID to delete

        Returns:
            True if successful
        """
        config = self.load_config("peripheral_types.yaml", force_reload=True)

        if "peripheral_types" not in config:
            return False

        # Filter out the type
        original_count = len(config["peripheral_types"])
        config["peripheral_types"] = [
            t for t in config["peripheral_types"] if t.get("id") != type_id
        ]

        if len(config["peripheral_types"]) < original_count:
            return self.save_config("peripheral_types.yaml", config)

        return False

    def get_location_types(self) -> List[Dict[str, Any]]:
        """
        Get location types configuration

        Returns:
            List of location type definitions
        """
        config = self.load_config("locations.yaml")
        return config.get("location_types", [])

    def get_stockage_locations(self) -> List[str]:
        """
        Get storage locations list (for non-used peripherals)

        Returns:
            List of storage location names
        """
        config = self.load_config("locations.yaml")
        locations = config.get("stockage_locations", [])
        return [l for l in locations if isinstance(l, str)]

    def get_image_processing_config(self) -> Dict[str, Any]:
        """
        Get image processing configuration

        Returns:
            Image processing settings
        """
        config = self.load_config("image_processing.yaml")
        return config.get("image_processing", {})

    def get_notification_config(self) -> Dict[str, Any]:
        """
        Get notification configuration

        Returns:
            Notification settings
        """
        config = self.load_config("notifications.yaml")
        return config.get("notifications", {})

    def get_boutiques(self) -> List[str]:
        """
        Get boutique list configuration

        Returns:
            List of boutique names
        """
        config = self.load_config("boutique.yaml")
        boutiques = config.get("boutiques", [])
        return [b for b in boutiques if isinstance(b, str)]

    def get_hosts(self) -> List[Dict[str, str]]:
        """
        Get hosts list configuration

        Returns:
            List of hosts with name and location
        """
        config = self.load_config("host.yaml")
        hosts = config.get("hosts", [])
        result = []
        for host in hosts:
            if not isinstance(host, dict):
                continue
            name = host.get("nom")
            location = host.get("localisation", "")
            if isinstance(name, str) and name:
                result.append({"nom": name, "localisation": location})
        return result

    def get_loan_reminder_days(self) -> int:
        """
        Get number of days before loan return to send reminder

        Returns:
            Number of days
        """
        config = self.get_notification_config()
        return config.get("loan_reminder_days", 7)

    def clear_cache(self):
        """Clear the configuration cache"""
        self._cache = {}


# Global instance
yaml_loader = YAMLConfigLoader()
