"""Configuration management for FOMO Guard."""

from pathlib import Path
from typing import Any

import toml
from pydantic import BaseModel
from pydantic_settings import BaseSettings


class APIKeys(BaseModel):
    """API key configuration."""

    coingecko: str | None = None
    coinmarketcap: str | None = None
    twitter: str | None = None
    reddit_client_id: str | None = None
    reddit_client_secret: str | None = None
    lunarcrush: str | None = None
    glassnode: str | None = None
    etherscan: str | None = None


class Settings(BaseModel):
    """Application settings."""

    default_cooldown_hours: int = 24
    cache_ttl_minutes: int = 5
    api_host: str = "0.0.0.0"
    api_port: int = 8000


class Config(BaseSettings):
    """Main configuration class."""

    api_keys: APIKeys = APIKeys()
    settings: Settings = Settings()

    @classmethod
    def get_config_dir(cls) -> Path:
        """Get the configuration directory path."""
        config_dir = Path.home() / ".config" / "fomo_guard"
        config_dir.mkdir(parents=True, exist_ok=True)
        return config_dir

    @classmethod
    def get_config_path(cls) -> Path:
        """Get the configuration file path."""
        return cls.get_config_dir() / "config.toml"

    @classmethod
    def get_data_dir(cls) -> Path:
        """Get the data directory path for cooldowns and history."""
        data_dir = Path.home() / ".local" / "share" / "fomo_guard"
        data_dir.mkdir(parents=True, exist_ok=True)
        return data_dir

    @classmethod
    def load(cls) -> "Config":
        """Load configuration from file."""
        config_path = cls.get_config_path()
        if config_path.exists():
            data = toml.load(config_path)
            return cls(**data)
        return cls()

    def save(self) -> None:
        """Save configuration to file."""
        config_path = self.get_config_path()
        data = {
            "api_keys": self.api_keys.model_dump(exclude_none=True),
            "settings": self.settings.model_dump(),
        }
        with open(config_path, "w") as f:
            toml.dump(data, f)

    def get_api_key(self, provider: str) -> str | None:
        """Get API key for a specific provider."""
        return getattr(self.api_keys, provider, None)

    def set_api_key(self, provider: str, key: str) -> None:
        """Set API key for a specific provider."""
        if hasattr(self.api_keys, provider):
            setattr(self.api_keys, provider, key)
            self.save()
        else:
            raise ValueError(f"Unknown provider: {provider}")

    def set_setting(self, key: str, value: Any) -> None:
        """Set a configuration setting."""
        if hasattr(self.settings, key):
            # Convert value to appropriate type
            field_type = type(getattr(self.settings, key))
            setattr(self.settings, key, field_type(value))
            self.save()
        else:
            raise ValueError(f"Unknown setting: {key}")

    def list_api_keys(self) -> dict[str, str | None]:
        """List all API keys (masked)."""
        keys = self.api_keys.model_dump()
        return {
            k: self._mask_key(v) if v else None
            for k, v in keys.items()
        }

    @staticmethod
    def _mask_key(key: str) -> str:
        """Mask an API key for display."""
        if len(key) <= 8:
            return "*" * len(key)
        return key[:4] + "*" * (len(key) - 8) + key[-4:]


# Global config instance
_config: Config | None = None


def get_config() -> Config:
    """Get the global configuration instance."""
    global _config
    if _config is None:
        _config = Config.load()
    return _config


def reload_config() -> Config:
    """Reload configuration from disk."""
    global _config
    _config = Config.load()
    return _config
