"""Configuration management utilities."""

from __future__ import annotations

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

CONFIG_DIR = Path.home() / ".lscsim"
CONFIG_FILE = CONFIG_DIR / "config.json"

logger = logging.getLogger(__name__)


@dataclass
class DatabaseConfig:
    """Database configuration."""

    host: str = "localhost"
    port: int = 5432
    database: str = "lscsim.db"
    username: str = "user"
    password: str = ""

    @cached_property
    def connection_url(self) -> str:
        """Generate connection URL."""
        if self.password:
            return f"postgresql://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
        return f"postgresql://{self.username}@{self.host}:{self.port}/{self.database}"


@dataclass
class UISettings:
    """UI appearance settings."""

    theme: str = "light"
    language: str = "en_US"
    font_size: int = 12
    recent_files: list[str] = field(default_factory=list)


@dataclass
class AppConfig:
    """Main application configuration."""

    database: DatabaseConfig = field(default_factory=DatabaseConfig)
    ui: UISettings = field(default_factory=UISettings)
    max_recent_files: int = 10
    auto_save_interval: int = 300  # seconds

    def __post_init__(self) -> None:
        """Initialize after construction."""
        self._load_config()
        atexit.register(self.save_config)

    def _load_config(self) -> None:
        """Load configuration from file."""
        if CONFIG_FILE.exists():
            try:
                with Path(CONFIG_FILE).open(encoding="utf-8") as f:
                    data = json.load(f)
                self._update_from_dict(data)
                logger.info("Configuration loaded successfully")
            except (json.JSONDecodeError, KeyError) as e:
                logger.warning(f"Failed to load config: {e}")
                logger.info("Using default configuration")
        else:
            logger.info("No existing configuration found, using defaults")

    def _update_from_dict(self, data: dict) -> None:
        """Update configuration from dictionary."""
        if "database" in data:
            db_data = data["database"]
            self.database = DatabaseConfig(
                host=db_data.get("host", self.database.host),
                port=db_data.get("port", self.database.port),
                database=db_data.get("database", self.database.database),
                username=db_data.get("username", self.database.username),
                password=db_data.get("password", self.database.password),
            )

        if "ui" in data:
            ui_data = data["ui"]
            self.ui = UISettings(
                theme=ui_data.get("theme", self.ui.theme),
                language=ui_data.get("language", self.ui.language),
                font_size=ui_data.get("font_size", self.ui.font_size),
                recent_files=ui_data.get("recent_files", self.ui.recent_files),
            )

        self.max_recent_files = data.get("max_recent_files", self.max_recent_files)
        self.auto_save_interval = data.get("auto_save_interval", self.auto_save_interval)

    def save_config(self) -> None:
        """Save configuration to file."""
        try:
            CONFIG_DIR.mkdir(parents=True, exist_ok=True)
            with Path(CONFIG_FILE).open("w", encoding="utf-8") as f:
                json.dump(self._to_dict(), f, indent=4, ensure_ascii=False)
        except Exception:
            logger.exception("Failed to save configuration")

    def _to_dict(self) -> dict:
        """Convert to dictionary for serialization."""
        return {
            "database": {
                "host": self.database.host,
                "port": self.database.port,
                "database": self.database.database,
                "username": self.database.username,
                "password": self.database.password,
            },
            "ui": {
                "theme": self.ui.theme,
                "language": self.ui.language,
                "font_size": self.ui.font_size,
                "recent_files": self.ui.recent_files,
            },
            "max_recent_files": self.max_recent_files,
            "auto_save_interval": self.auto_save_interval,
        }


# Global configuration instance
config_manager = AppConfig()
