"""Configuration management routes: get/set/reset/validate config."""

from fastapi import APIRouter, Request
from fastapi.responses import JSONResponse
import globals
from utils.logger import get_logger

logger = get_logger('api')

router = APIRouter()


@router.get("/config")
async def get_full_config():
    """
    Get full configuration including static, runtime, and state.
    Useful for debugging and config display in UI.
    """
    try:
        from config_manager import config_manager
        full_config = config_manager.get_full_config()
        return {
            "success": True,
            "config": full_config
        }
    except Exception as e:
        logger.error(f"Failed to get config: {e}")
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})


@router.get("/config/static")
async def get_static_config():
    """
    Get static configuration from config.yaml.
    These are default values that can be overridden at runtime.
    """
    try:
        from config_manager import config_manager
        return {
            "success": True,
            "config": config_manager.static_config
        }
    except Exception as e:
        logger.error(f"Failed to get static config: {e}")
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})


@router.get("/config/runtime")
async def get_runtime_config():
    """
    Get runtime configuration overrides.
    These are values changed via Web UI that override config.yaml.
    """
    try:
        from config_manager import config_manager
        return {
            "success": True,
            "config": config_manager.runtime_config,
            "path": str(config_manager.runtime_config_path)
        }
    except Exception as e:
        logger.error(f"Failed to get runtime config: {e}")
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})


@router.post("/config/set")
async def set_config_value(request: Request):
    """
    Set a configuration value with optional persistence.

    Body: {
        "key_path": "discord.language_mode",  // Dot-separated path
        "value": "japanese",
        "persist": true  // Save to config_runtime.yaml
    }
    """
    try:
        data = await request.json()
        key_path = data.get("key_path")
        value = data.get("value")
        persist = data.get("persist", True)

        if not key_path:
            return JSONResponse(status_code=400, content={"success": False, "error": "key_path is required"})

        from config_manager import config_manager
        config_manager.set(key_path, value, persist=persist)

        # ── Sync globals for every runtime-relevant key path ──
        _GLOBALS_SYNC = {
            "discord.language_mode":    ("LANGUAGE_MODE",     str),
            "autonomous.debug_mode":    ("AUTONOMOUS_DEBUG",  bool),
            "voice.debug_mode":         ("VOICE_DEBUG_MODE",  bool),
            "memory.use_cheshire_cat":  ("USE_CHESHIRE_CAT",  bool),
            "gpu.prefer_amd":           ("PREFER_AMD_GPU",    bool),
            "models.text":              ("TEXT_MODEL",        str),
            "models.evil":              ("EVIL_TEXT_MODEL",   str),
            "models.japanese":          ("JAPANESE_TEXT_MODEL", str),
        }

        if key_path in _GLOBALS_SYNC:
            attr, converter = _GLOBALS_SYNC[key_path]
            setattr(globals, attr, converter(value))
        elif key_path == "runtime.mood.dm_mood":
            # DM mood needs description loaded alongside
            if isinstance(value, str) and value in getattr(globals, "AVAILABLE_MOODS", []):
                globals.DM_MOOD = value
                try:
                    from utils.moods import load_mood_description
                    globals.DM_MOOD_DESCRIPTION = load_mood_description(value)
                except Exception:
                    globals.DM_MOOD_DESCRIPTION = f"I'm feeling {value} today."

        return {
            "success": True,
            "message": f"Set {key_path} = {value}",
            "persisted": persist
        }
    except Exception as e:
        logger.error(f"Failed to set config: {e}")
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})


@router.post("/config/reset")
async def reset_config(request: Request):
    """
    Reset configuration to defaults.

    Body: {
        "key_path": "discord.language_mode",  // Optional: reset specific key
        "persist": true  // Remove from config_runtime.yaml
    }

    If key_path is omitted, resets all runtime config to defaults.
    """
    try:
        data = await request.json()
        key_path = data.get("key_path")
        persist = data.get("persist", True)

        from config_manager import config_manager
        config_manager.reset_to_defaults(key_path)

        return {
            "success": True,
            "message": f"Reset {key_path or 'all config'} to defaults"
        }
    except Exception as e:
        logger.error(f"Failed to reset config: {e}")
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})


@router.post("/config/validate")
async def validate_config_endpoint():
    """
    Validate current configuration.
    Returns list of errors if validation fails.
    """
    try:
        from config_manager import config_manager
        is_valid, errors = config_manager.validate_config()

        return {
            "success": is_valid,
            "is_valid": is_valid,
            "errors": errors
        }
    except Exception as e:
        logger.error(f"Failed to validate config: {e}")
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})


@router.get("/config/state")
async def get_config_state():
    """
    Get runtime state (not persisted config).
    These are transient values like current mood, evil mode, etc.
    """
    try:
        from config_manager import config_manager
        return {
            "success": True,
            "state": config_manager.runtime_state
        }
    except Exception as e:
        logger.error(f"Failed to get config state: {e}")
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})
