"""Settings endpoints: LLM keys, Langfuse, defaults, integrations, secrets, validation."""
from __future__ import annotations

from typing import Any

from fastapi import APIRouter, Request

from api.deps import (
    _as_bool,
    _effective_identity,
    _normalize_target,
    _now_iso,
    _record_audit,
    _require_role,
)
from api.models import (
    DefaultsSettingsRequest,
    IntegrationsSettingsRequest,
    LangfuseSettingsRequest,
    LLMSettingsRequest,
    ValidateSettingsRequest,
)
from src.bootstrap_config import get_bootstrap_config_status
from src.env_settings import (
    OPTIONAL_ENV_KEYS,
    LLM_ENV_KEYS,
    as_masked_key,
    llm_key_status,
    read_current_key_values,
    save_env_values,
    supported_env_locations,
)

router = APIRouter()


def _safe_int(val: object, default: int = 0) -> int:
    try:
        return int(val or default)
    except (ValueError, TypeError):
        return default


@router.get("/api/models/available")
def list_available_models(request: Request):
    _effective_identity(request)
    from src.agent_core import get_available_models

    return get_available_models()


@router.get("/api/settings/llm-keys")
def get_llm_settings(request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    keys = [*LLM_ENV_KEYS, *OPTIONAL_ENV_KEYS]
    current = read_current_key_values(keys)
    return {
        "status": llm_key_status(),
        "locations": supported_env_locations(),
        "masked": {key: as_masked_key(current.get(key, "")) for key in keys},
        "present": {key: bool(str(current.get(key, "")).strip()) for key in keys},
    }


@router.get("/api/settings/bootstrap-config")
def get_bootstrap_config(request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    status = get_bootstrap_config_status()
    return {"ok": True, "data": status}


@router.post("/api/settings/llm-keys")
def save_llm_settings(payload: LLMSettingsRequest, request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    target = _normalize_target(payload.target)
    saved = save_env_values(
        {
            "OPENAI_API_KEY": payload.openai_api_key,
            "ANTHROPIC_API_KEY": payload.anthropic_api_key,
            "GOOGLE_API_KEY": payload.google_api_key,
            "GEMINI_API_KEY": payload.gemini_api_key,
            "OPENROUTER_API_KEY": payload.openrouter_api_key,
            "OPENROUTER_BASE_URL": payload.openrouter_base_url,
            "OLLAMA_BASE_URL": payload.ollama_base_url,
            "VLLM_BASE_URL": payload.vllm_base_url,
            "LMSTUDIO_BASE_URL": payload.lmstudio_base_url,
        },
        target=target,
    )
    _record_audit(
        request,
        action="settings.llm_keys.update",
        resource_type="settings",
        resource_id="llm-keys",
        detail={"target": target, "updated_keys": saved.get("updated_keys", [])},
    )
    return {
        "ok": True,
        "saved": saved,
        "status": llm_key_status(),
    }


@router.get("/api/settings/langfuse")
def get_langfuse_settings(request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    keys = ["LANGFUSE_BASE_URL", "LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY", "LANGFUSE_ENVIRONMENT"]
    current = read_current_key_values(keys)
    return {
        "ok": True,
        "data": {
            "status": {
                "base_url": bool(str(current.get("LANGFUSE_BASE_URL", "")).strip()),
                "public_key": bool(str(current.get("LANGFUSE_PUBLIC_KEY", "")).strip()),
                "secret_key": bool(str(current.get("LANGFUSE_SECRET_KEY", "")).strip()),
            },
            "masked": {key: as_masked_key(current.get(key, "")) for key in keys},
            "locations": supported_env_locations(),
        },
    }


@router.put("/api/settings/langfuse")
def put_langfuse_settings(payload: LangfuseSettingsRequest, request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    target = _normalize_target(payload.target)
    saved = save_env_values(
        {
            "LANGFUSE_BASE_URL": payload.base_url,
            "LANGFUSE_PUBLIC_KEY": payload.public_key,
            "LANGFUSE_SECRET_KEY": payload.secret_key,
            "LANGFUSE_ENVIRONMENT": payload.environment,
        },
        target=target,
    )
    _record_audit(
        request,
        action="settings.langfuse.update",
        resource_type="settings",
        resource_id="langfuse",
        detail={"target": target, "updated_keys": saved.get("updated_keys", [])},
    )
    return {
        "ok": True,
        "data": {
            "saved": saved,
            "validated": payload.base_url.startswith("http"),
        },
    }


@router.get("/api/settings/defaults")
def get_default_settings(request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    keys = {
        "default_mode": "AGENT_DEFAULT_MODE",
        "default_limit": "AGENT_DEFAULT_LIMIT",
        "timezone": "AGENT_DEFAULT_TIMEZONE",
        "retention_days": "AGENT_RETENTION_DAYS",
        "default_compare_models": "AGENT_DEFAULT_COMPARE_MODELS",
        "report_summary_model": "AGENT_REPORT_SUMMARY_MODEL",
        "allow_signup": "AGENT_AUTH_ALLOW_SIGNUP",
    }
    current = read_current_key_values(list(keys.values()))

    return {
        "ok": True,
        "data": {
            "default_mode": str(current.get("AGENT_DEFAULT_MODE", "overview") or "overview"),
            "default_limit": _safe_int(current.get("AGENT_DEFAULT_LIMIT"), 20),
            "timezone": str(current.get("AGENT_DEFAULT_TIMEZONE", "UTC") or "UTC"),
            "retention_days": _safe_int(current.get("AGENT_RETENTION_DAYS"), 30),
            "default_compare_models": _as_bool(current.get("AGENT_DEFAULT_COMPARE_MODELS", "false")),
            "report_summary_model": str(current.get("AGENT_REPORT_SUMMARY_MODEL", "") or ""),
            "allow_signup": _as_bool(current.get("AGENT_AUTH_ALLOW_SIGNUP", "true"), default=True),
            "locations": supported_env_locations(),
        },
    }


@router.put("/api/settings/defaults")
def put_default_settings(payload: DefaultsSettingsRequest, request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    target = _normalize_target(payload.target)
    values = {
        "AGENT_DEFAULT_MODE": payload.default_mode,
        "AGENT_DEFAULT_LIMIT": str(payload.default_limit),
        "AGENT_DEFAULT_TIMEZONE": payload.timezone,
        "AGENT_RETENTION_DAYS": str(payload.retention_days),
        "AGENT_DEFAULT_COMPARE_MODELS": "true" if payload.default_compare_models else "false",
        "AGENT_REPORT_SUMMARY_MODEL": payload.report_summary_model,
    }
    if payload.allow_signup is not None:
        values["AGENT_AUTH_ALLOW_SIGNUP"] = "true" if payload.allow_signup else "false"
    saved = save_env_values(values, target=target)
    _record_audit(
        request,
        action="settings.defaults.update",
        resource_type="settings",
        resource_id="defaults",
        detail={"target": target, "updated_keys": saved.get("updated_keys", [])},
    )
    return {"ok": True, "data": {"saved": saved, "updated_at": _now_iso()}}


@router.get("/api/settings/integrations")
def get_integration_settings(request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    keys = ["AGENT_SLACK_WEBHOOK", "AGENT_ALERT_WEBHOOK", "AGENT_ALERT_EMAIL_RECIPIENTS", "AGENT_ALERTS_ENABLED"]
    current = read_current_key_values(keys)
    emails = [part.strip() for part in str(current.get("AGENT_ALERT_EMAIL_RECIPIENTS", "")).split(",") if part.strip()]
    return {
        "ok": True,
        "data": {
            "slack_webhook": as_masked_key(current.get("AGENT_SLACK_WEBHOOK", "")),
            "webhook_url": as_masked_key(current.get("AGENT_ALERT_WEBHOOK", "")),
            "email_recipients": emails,
            "enabled": _as_bool(current.get("AGENT_ALERTS_ENABLED", "false")),
            "locations": supported_env_locations(),
        },
    }


@router.put("/api/settings/integrations")
def put_integration_settings(payload: IntegrationsSettingsRequest, request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    target = _normalize_target(payload.target)
    saved = save_env_values(
        {
            "AGENT_SLACK_WEBHOOK": payload.slack_webhook,
            "AGENT_ALERT_WEBHOOK": payload.webhook_url,
            "AGENT_ALERT_EMAIL_RECIPIENTS": ",".join(payload.email_recipients),
            "AGENT_ALERTS_ENABLED": "true" if payload.enabled else "false",
        },
        target=target,
    )
    _record_audit(
        request,
        action="settings.integrations.update",
        resource_type="settings",
        resource_id="integrations",
        detail={"target": target, "updated_keys": saved.get("updated_keys", [])},
    )
    return {"ok": True, "data": {"saved": saved}}


@router.get("/api/settings/secrets/status")
def get_secret_status(request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    keys = [
        *LLM_ENV_KEYS,
        *OPTIONAL_ENV_KEYS,
        "LANGFUSE_BASE_URL",
        "LANGFUSE_PUBLIC_KEY",
        "LANGFUSE_SECRET_KEY",
        "AGENT_SLACK_WEBHOOK",
    ]
    current = read_current_key_values(keys)

    checks: list[dict[str, Any]] = []
    for key in keys:
        value = str(current.get(key, "") or "").strip()
        present = bool(value)
        valid = present
        if key.endswith("BASE_URL") or "WEBHOOK" in key:
            valid = present and value.startswith("http")
        if key.endswith("SECRET_KEY"):
            valid = present and (value.startswith("sk-") or len(value) > 10)
        checks.append({"name": key, "present": present, "valid": valid, "last_checked_at": _now_iso()})

    return {"ok": True, "data": {"checks": checks}}


@router.post("/api/settings/validate")
def validate_settings(payload: ValidateSettingsRequest, request: Request) -> dict[str, Any]:
    _require_role(request, "owner")
    targets = [str(t).strip().lower() for t in payload.targets if str(t).strip()]
    if not targets:
        targets = ["langfuse"]

    current = read_current_key_values(
        [
            "LANGFUSE_BASE_URL",
            "LANGFUSE_PUBLIC_KEY",
            "LANGFUSE_SECRET_KEY",
            "OPENROUTER_API_KEY",
            "OPENROUTER_BASE_URL",
            "AGENT_SLACK_WEBHOOK",
        ]
    )

    results: list[dict[str, Any]] = []
    for target in targets:
        if target == "langfuse":
            ok = all(
                bool(str(current.get(key, "")).strip())
                for key in ("LANGFUSE_BASE_URL", "LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY")
            )
            results.append({"target": target, "ok": ok, "detail": "required keys present" if ok else "missing keys"})
        elif target == "openrouter":
            key = str(current.get("OPENROUTER_API_KEY", "")).strip()
            base_url = str(current.get("OPENROUTER_BASE_URL", "")).strip()
            ok = bool(key) and base_url.startswith("http")
            results.append(
                {"target": target, "ok": ok, "detail": "key+base_url valid" if ok else "missing key or invalid base_url"}
            )
        elif target == "slack":
            webhook = str(current.get("AGENT_SLACK_WEBHOOK", "")).strip()
            ok = webhook.startswith("https://hooks.slack.com/")
            results.append(
                {
                    "target": target,
                    "ok": ok,
                    "detail": "webhook format valid" if ok else "invalid slack webhook format",
                }
            )
        else:
            results.append({"target": target, "ok": False, "detail": "unsupported target"})

    return {"ok": True, "data": {"overall_ok": all(r["ok"] for r in results), "results": results}}
