"""Configuration read/write endpoints."""

from typing import Dict, Optional, Any
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel

from web.backend.auth.dependencies import get_current_user

router = APIRouter(prefix="/api/config", tags=["config"])

# Keys that should be masked in GET responses
_SENSITIVE_KEYS = {"api_key", "secret_key", "token", "password", "api_secret", "access_key"}

# Sections to expose (match actual config.ini)
_ALLOWED_SECTIONS = {"API", "Paths", "Performance", "File", "Templates", "Gitea", "WebAuth"}


class ConfigUpdate(BaseModel):
    section: str
    key: str
    value: str


class ConfigBulkUpdate(BaseModel):
    updates: list[ConfigUpdate]


def _get_config():
    from app.config.settings import ConfigManager
    return ConfigManager()


def _mask_value(key: str, value: str) -> str:
    if any(s in key.lower() for s in _SENSITIVE_KEYS):
        if len(value) > 4:
            return value[:2] + "*" * (len(value) - 4) + value[-2:]
        return "****"
    return value


@router.get("")
async def get_config(
    section: Optional[str] = None,
    current_user: dict = Depends(get_current_user),
):
    cfg = _get_config()
    if section:
        if section not in _ALLOWED_SECTIONS and section != "DEFAULT":
            raise HTTPException(403, f"不允许访问配置节: {section}")
        items = {}
        for key, value in cfg.config.items(section):
            items[key] = _mask_value(key, value)
        return {"section": section, "items": items}

    result = {}
    for sec in _ALLOWED_SECTIONS:
        try:
            items = {}
            for key, value in cfg.config.items(sec):
                items[key] = _mask_value(key, value)
            result[sec] = items
        except Exception:
            pass
    return result


def _is_masked(key: str, value: str) -> bool:
    """Check if a value looks like a masked sensitive field (contains asterisks)."""
    return any(s in key.lower() for s in _SENSITIVE_KEYS) and '*' in value


@router.put("")
async def update_config(
    body: ConfigUpdate,
    current_user: dict = Depends(get_current_user),
):
    if body.section not in _ALLOWED_SECTIONS:
        raise HTTPException(403, f"不允许修改配置节: {body.section}")

    if _is_masked(body.key, body.value):
        raise HTTPException(400, "敏感字段不能直接提交掩码值，请先清除输入框再输入真实值")

    cfg = _get_config()
    try:
        cfg.update(body.section, body.key, body.value)
        cfg.save_config()
        return {"message": f"已更新 [{body.section}] {body.key}"}
    except Exception as e:
        raise HTTPException(500, f"保存失败: {e}")


@router.put("/bulk")
async def bulk_update_config(
    body: ConfigBulkUpdate,
    current_user: dict = Depends(get_current_user),
):
    cfg = _get_config()
    updated = []
    skipped = []
    for item in body.updates:
        if item.section not in _ALLOWED_SECTIONS:
            continue
        # Skip masked sensitive values to prevent destroying real credentials
        if _is_masked(item.key, item.value):
            skipped.append(f"[{item.section}] {item.key}")
            continue
        cfg.update(item.section, item.key, item.value)
        updated.append(f"[{item.section}] {item.key}")

    cfg.save_config()
    msg = f"已更新 {len(updated)} 项"
    if skipped:
        msg += f"，跳过 {len(skipped)} 项掩码值"
    return {"message": msg, "updated": updated, "skipped": skipped}
