import json
import logging
from pathlib import Path
from typing import Optional

from nexus_agent.models.memory import MemorySettings
from nexus_agent.models.settings import AppSettings, LLMSettings, ProfileSettings, ThemeSettings

logger = logging.getLogger(__name__)


class SettingsManager:
    def __init__(self):
        self._settings = AppSettings()
        self._config_path: Optional[Path] = None

    @property
    def llm(self) -> LLMSettings:
        return self._settings.llm

    @property
    def memory(self) -> MemorySettings:
        return self._settings.memory

    @property
    def profile(self) -> ProfileSettings:
        return self._settings.profile

    @property
    def theme(self) -> ThemeSettings:
        return self._settings.theme

    @property
    def settings(self) -> AppSettings:
        return self._settings

    def load_config(self, config_path: str) -> None:
        path = Path(config_path)
        if not path.is_absolute():
            from nexus_agent.config import get_config_path
            path = get_config_path(config_path)
        self._config_path = path

        if not path.exists():
            logger.info(f"Settings file not found: {path}, using defaults")
            self._save_config()
            return

        try:
            data = json.loads(path.read_text(encoding="utf-8"))
            self._settings = AppSettings(**data)
            logger.info(f"Loaded settings from {path}")
        except Exception as e:
            logger.warning(f"Failed to parse settings: {e}, using defaults")
            self._settings = AppSettings()

    def _save_config(self) -> None:
        if not self._config_path:
            return
        data = self._settings.model_dump()
        self._config_path.write_text(
            json.dumps(data, indent=2, ensure_ascii=False) + "\n",
            encoding="utf-8",
        )

    def update_llm(self, **kwargs) -> LLMSettings:
        current = self._settings.llm.model_dump()
        for k, v in kwargs.items():
            current[k] = v
        self._settings.llm = LLMSettings(**current)
        self._save_config()
        logger.info(f"Updated LLM settings: model={self._settings.llm.model}")
        return self._settings.llm

    def update_memory(self, **kwargs) -> MemorySettings:
        current = self._settings.memory.model_dump()
        for k, v in kwargs.items():
            if v is not None:
                current[k] = v
        self._settings.memory = MemorySettings(**current)
        self._save_config()
        logger.info(f"Updated memory settings: enabled={self._settings.memory.enabled}")
        return self._settings.memory

    def update_profile(self, **kwargs) -> ProfileSettings:
        current = self._settings.profile.model_dump()
        for k, v in kwargs.items():
            if v is not None:
                current[k] = v
        self._settings.profile = ProfileSettings(**current)
        self._save_config()
        logger.info(f"Updated profile settings: name={self._settings.profile.name}")
        return self._settings.profile

    def update_theme(self, **kwargs) -> ThemeSettings:
        current = self._settings.theme.model_dump()
        for k, v in kwargs.items():
            if v is not None:
                current[k] = v
        self._settings.theme = ThemeSettings(**current)
        self._save_config()
        logger.info(f"Updated theme settings: mode={self._settings.theme.mode}, accent={self._settings.theme.accent_color}")
        return self._settings.theme


settings_manager = SettingsManager()
