"""
Configuration management for the hosts TUI application.

This module handles application settings and preferences.
"""

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


class Config:
    """
    Configuration manager for the hosts application.

    Handles loading, saving, and managing application settings.
    """

    def __init__(self):
        self.config_dir = Path.home() / ".config" / "hosts-manager"
        self.config_file = self.config_dir / "config.json"
        self._settings = self._load_default_settings()
        self.load()

    def _load_default_settings(self) -> Dict[str, Any]:
        """Load default configuration settings."""
        return {
            "show_default_entries": False,  # Hide default entries by default
            "default_entries": [
                {"ip": "127.0.0.1", "hostname": "localhost"},
                {"ip": "255.255.255.255", "hostname": "broadcasthost"},
                {"ip": "::1", "hostname": "localhost"},
            ],
            "window_settings": {
                "last_sort_column": "",
                "last_sort_ascending": True,
            },
            "dns_resolution": {
                "enabled": True,
                "timeout": 5.0,   # 5 seconds timeout
            },
            "filter_settings": {
                "remember_filter_state": True,
                "default_filter_options": {
                    "show_active_only": False,
                    "show_inactive_only": False,
                    "show_dns_entries_only": False,
                    "show_ip_entries_only": False,
                    "show_mismatch_only": False,
                },
            },
            "import_export": {
                "default_export_format": "hosts",
                "export_directory": str(Path.home() / "Downloads"),
            },
        }

    def load(self) -> None:
        """Load configuration from file."""
        try:
            if self.config_file.exists():
                with open(self.config_file, "r") as f:
                    loaded_settings = json.load(f)
                    # Merge with defaults to ensure all keys exist
                    self._settings.update(loaded_settings)
        except (json.JSONDecodeError, IOError):
            # If loading fails, use defaults
            pass

    def save(self) -> None:
        """Save configuration to file."""
        try:
            # Ensure config directory exists
            self.config_dir.mkdir(parents=True, exist_ok=True)

            with open(self.config_file, "w") as f:
                json.dump(self._settings, f, indent=2)
        except IOError:
            # Silently fail if we can't save config
            pass

    def get(self, key: str, default: Any = None) -> Any:
        """Get a configuration value."""
        return self._settings.get(key, default)

    def set(self, key: str, value: Any) -> None:
        """Set a configuration value."""
        self._settings[key] = value

    def is_default_entry(self, ip_address: str, hostname: str) -> bool:
        """Check if an entry is a default system entry."""
        default_entries = self.get("default_entries", [])
        for entry in default_entries:
            if entry["ip"] == ip_address and entry["hostname"] == hostname:
                return True
        return False

    def should_show_default_entries(self) -> bool:
        """Check if default entries should be shown."""
        return self.get("show_default_entries", False)

    def toggle_show_default_entries(self) -> None:
        """Toggle the show default entries setting."""
        current = self.get("show_default_entries", False)
        self.set("show_default_entries", not current)
        self.save()

    # DNS Configuration Methods
    def is_dns_resolution_enabled(self) -> bool:
        """Check if DNS resolution is enabled."""
        return self.get("dns_resolution", {}).get("enabled", True)

    def get_dns_timeout(self) -> float:
        """Get DNS resolution timeout in seconds."""
        return self.get("dns_resolution", {}).get("timeout", 5.0)

    def set_dns_resolution_enabled(self, enabled: bool) -> None:
        """Enable or disable DNS resolution."""
        dns_settings = self.get("dns_resolution", {})
        dns_settings["enabled"] = enabled
        self.set("dns_resolution", dns_settings)
        self.save()

    def set_dns_timeout(self, timeout: float) -> None:
        """Set DNS resolution timeout in seconds."""
        dns_settings = self.get("dns_resolution", {})
        dns_settings["timeout"] = timeout
        self.set("dns_resolution", dns_settings)
        self.save()

    # Filter Configuration Methods
    def get_filter_settings(self) -> Dict[str, Any]:
        """Get current filter settings."""
        return self.get("filter_settings", {}).get("default_filter_options", {})

    def should_remember_filter_state(self) -> bool:
        """Check if filter state should be remembered."""
        return self.get("filter_settings", {}).get("remember_filter_state", True)

    def set_filter_settings(self, filter_options: Dict[str, Any]) -> None:
        """Save filter settings."""
        filter_settings = self.get("filter_settings", {})
        filter_settings["default_filter_options"] = filter_options
        self.set("filter_settings", filter_settings)
        if self.should_remember_filter_state():
            self.save()

    def get_filter_presets(self) -> Dict[str, Dict[str, Any]]:
        """Get saved filter presets."""
        filter_settings = self.get("filter_settings", {})
        return filter_settings.get("saved_presets", {})

    def save_filter_preset(self, name: str, filter_options: Dict[str, Any]) -> None:
        """Save a filter preset."""
        filter_settings = self.get("filter_settings", {})
        if "saved_presets" not in filter_settings:
            filter_settings["saved_presets"] = {}
        filter_settings["saved_presets"][name] = filter_options
        self.set("filter_settings", filter_settings)
        self.save()

    def delete_filter_preset(self, name: str) -> bool:
        """Delete a filter preset. Returns True if deleted, False if not found."""
        filter_settings = self.get("filter_settings", {})
        saved_presets = filter_settings.get("saved_presets", {})
        if name in saved_presets:
            del saved_presets[name]
            filter_settings["saved_presets"] = saved_presets
            self.set("filter_settings", filter_settings)
            self.save()
            return True
        return False

    def get_last_used_filter_options(self) -> Dict[str, Any]:
        """Get the last used filter options if remember_filter_state is enabled."""
        if self.should_remember_filter_state():
            filter_settings = self.get("filter_settings", {})
            return filter_settings.get("last_used_options", {})
        return {}

    def save_last_used_filter_options(self, filter_options: Dict[str, Any]) -> None:
        """Save the last used filter options if remember_filter_state is enabled."""
        if self.should_remember_filter_state():
            filter_settings = self.get("filter_settings", {})
            filter_settings["last_used_options"] = filter_options
            self.set("filter_settings", filter_settings)
            self.save()

    def clear_filter_data(self) -> None:
        """Clear all filter data (presets and last used options)."""
        filter_settings = self.get("filter_settings", {})
        filter_settings.pop("saved_presets", None)
        filter_settings.pop("last_used_options", None)
        self.set("filter_settings", filter_settings)
        self.save()

    # Import/Export Configuration Methods
    def get_default_export_format(self) -> str:
        """Get default export format."""
        return self.get("import_export", {}).get("default_export_format", "hosts")

    def get_export_directory(self) -> str:
        """Get default export directory."""
        return self.get("import_export", {}).get("export_directory", str(Path.home() / "Downloads"))

    def set_default_export_format(self, format_name: str) -> None:
        """Set default export format."""
        import_export_settings = self.get("import_export", {})
        import_export_settings["default_export_format"] = format_name
        self.set("import_export", import_export_settings)
        self.save()

    def set_export_directory(self, directory: str) -> None:
        """Set default export directory."""
        import_export_settings = self.get("import_export", {})
        import_export_settings["export_directory"] = directory
        self.set("import_export", import_export_settings)
        self.save()
