"""Configuration management for Resource Hacker GUI."""

from __future__ import annotations

import atexit
import json
import logging
from dataclasses import dataclass, field
from functools import cached_property
from pathlib import Path

logger = logging.getLogger(__name__)

# Configuration file location
CONFIG_FILE = Path.home() / ".pytola" / "reshack.json"


@dataclass
class ResHackConfig:
    """Configuration for Resource Hacker application."""

    # Window settings
    window_width: int = 1200
    window_height: int = 800
    window_x: int | None = None
    window_y: int | None = None

    # Recent files
    max_recent_files: int = 10
    recent_files: list[str] = field(default_factory=list)

    # Preview settings
    preview_auto_refresh: bool = True
    preview_show_hex: bool = False
    preview_max_size: int = 1024 * 1024  # 1MB

    # Export settings
    export_default_dir: str = ""
    export_preserve_structure: bool = True

    # Resource filtering
    hidden_resource_types: set[int] = field(default_factory=set)

    def __post_init__(self) -> None:
        """Initialize configuration with proper defaults."""
        if self.hidden_resource_types is None:
            self.hidden_resource_types = set()
        if self.recent_files is None:
            self.recent_files = []

    def __init__(
        self,
        window_width: int = 1200,
        window_height: int = 800,
        window_x: int | None = None,
        window_y: int | None = None,
        max_recent_files: int = 10,
        recent_files: list[str] | None = None,
        preview_auto_refresh: bool = True,
        preview_show_hex: bool = False,
        preview_max_size: int = 1024 * 1024,
        export_default_dir: str = "",
        export_preserve_structure: bool = True,
        hidden_resource_types: set[int] | None = None,
    ) -> None:
        """Initialize configuration with default values."""
        # Set default values
        self.window_width = window_width
        self.window_height = window_height
        self.window_x = window_x
        self.window_y = window_y
        self.max_recent_files = max_recent_files
        self.recent_files = recent_files or []
        self.preview_auto_refresh = preview_auto_refresh
        self.preview_show_hex = preview_show_hex
        self.preview_max_size = preview_max_size
        self.export_default_dir = export_default_dir
        self.export_preserve_structure = export_preserve_structure
        self.hidden_resource_types = hidden_resource_types or set()

        # Load existing configuration
        self._load_from_file()

    def _load_from_file(self) -> None:
        """Load configuration from file if it exists."""
        if CONFIG_FILE.exists():
            try:
                config_data = json.loads(CONFIG_FILE.read_text(encoding="utf-8"))
                self._apply_config_data(config_data)
                logger.info(f"Loaded configuration from {CONFIG_FILE}")
            except (json.JSONDecodeError, TypeError, AttributeError) as e:
                logger.warning(f"Could not load config from {CONFIG_FILE}: {e}")

    def _apply_config_data(self, config_data: dict) -> None:
        """Apply configuration data to instance attributes."""
        for key, value in config_data.items():
            if hasattr(self, key):
                attr_type = type(getattr(self, key))
                try:
                    if isinstance(attr_type, set) and isinstance(value, list):
                        setattr(self, key, set(value))
                    elif isinstance(attr_type, list) and isinstance(value, list):
                        setattr(self, key, value[: getattr(self, f"max_{key}", len(value))])
                    else:
                        setattr(self, key, value)
                except (TypeError, ValueError) as e:
                    logger.warning(f"Could not apply config value for {key}: {e}")

    def save(self) -> None:
        """Save current configuration to file."""
        try:
            CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)

            config_dict = {
                "window_width": self.window_width,
                "window_height": self.window_height,
                "window_x": self.window_x,
                "window_y": self.window_y,
                "max_recent_files": self.max_recent_files,
                "recent_files": self.recent_files,
                "preview_auto_refresh": self.preview_auto_refresh,
                "preview_show_hex": self.preview_show_hex,
                "preview_max_size": self.preview_max_size,
                "export_default_dir": self.export_default_dir,
                "export_preserve_structure": self.export_preserve_structure,
                "hidden_resource_types": list(self.hidden_resource_types),
            }

            CONFIG_FILE.write_text(json.dumps(config_dict, indent=4, ensure_ascii=False), encoding="utf-8")
            logger.info(f"Saved configuration to {CONFIG_FILE}")
        except Exception as e:
            logger.error(f"Failed to save configuration: {e}")

    @cached_property
    def config_directory(self) -> Path:
        """Get the configuration directory path."""
        return CONFIG_FILE.parent

    @cached_property
    def default_export_directory(self) -> Path:
        """Get the default export directory path."""
        if self.export_default_dir:
            return Path(self.export_default_dir)
        return Path.cwd() / "exports"

    def add_recent_file(self, file_path: str) -> None:
        """Add a file to recent files list."""
        if file_path in self.recent_files:
            self.recent_files.remove(file_path)
        self.recent_files.insert(0, file_path)

        # Keep only the maximum number of recent files
        self.recent_files = self.recent_files[: self.max_recent_files]

    def get_recent_files(self) -> list[str]:
        """Get the list of recent files."""
        return self.recent_files.copy()

    def is_resource_type_hidden(self, type_id: int) -> bool:
        """Check if a resource type is hidden."""
        return type_id in self.hidden_resource_types

    def toggle_resource_type_visibility(self, type_id: int) -> None:
        """Toggle visibility of a resource type."""
        if type_id in self.hidden_resource_types:
            self.hidden_resource_types.remove(type_id)
        else:
            self.hidden_resource_types.add(type_id)


# Global configuration instance
app_config = ResHackConfig()
atexit.register(app_config.save)
