# ruff: noqa: F401,F403,F405,I001
from ._runtime import *  # noqa: F403,F405
from .webapp_runtime import refresh_webapp_runtime_after_settings_change

from config.subscription_guides_config import (
    SubscriptionGuidesConfigError,
    subscription_guides_admin_config_json,
)


async def admin_settings_get_route(request: web.Request) -> web.Response:
    _require_admin_user_id(request)
    settings: Settings = request.app["settings"]
    async_session_factory: sessionmaker = request.app["async_session_factory"]

    async with async_session_factory() as session:
        overrides = await app_settings_dal.get_overrides_with_meta(session)

    overrides_by_key = {entry["key"]: entry for entry in overrides}

    fields = manifest_payload()
    webhook_base_url = str(settings.WEBHOOK_BASE_URL or "").strip().rstrip("/")
    sections: Dict[str, Dict[str, Any]] = {}
    for field in fields:
        key = field["key"]
        section_id = field["section"]
        if section_id not in sections:
            sections[section_id] = {
                "id": section_id,
                "order": field["section_order"],
                "fields": [],
            }
        override = overrides_by_key.get(key)
        value = current_value(settings, key)
        is_secret = bool(field.get("secret"))
        overridden = bool(override)
        source = None
        read_error = None
        if key == "SUBSCRIPTION_PAGE_CONFIG_JSON":
            try:
                value, source = subscription_guides_admin_config_json(settings)
                overridden = source == "admin_json"
            except SubscriptionGuidesConfigError as exc:
                read_error = str(exc)
        response_field = {
            **field,
            "value": "" if is_secret else value,
            "overridden": overridden,
            "updated_at": override.get("updated_at") if override else None,
        }
        if source:
            response_field["source"] = source
        if read_error:
            response_field["read_error"] = read_error
        if is_secret:
            response_field["has_value"] = bool(value)
        webhook_path = str(response_field.get("webhook_path") or "").strip()
        if webhook_path:
            if not webhook_path.startswith("/"):
                webhook_path = f"/{webhook_path}"
            response_field["webhook_path"] = webhook_path
            response_field["webhook_base_url_configured"] = bool(webhook_base_url)
            if webhook_base_url:
                response_field["webhook_url"] = f"{webhook_base_url}{webhook_path}"
        sections[section_id]["fields"].append(response_field)

    ordered_sections = sorted(sections.values(), key=lambda s: s["order"])
    return _ok({"sections": ordered_sections})


async def admin_settings_patch_route(request: web.Request) -> web.Response:
    actor_id = _require_admin_user_id(request)
    settings: Settings = request.app["settings"]
    async_session_factory: sessionmaker = request.app["async_session_factory"]
    payload = await _read_json(request)
    updates = payload.get("updates") or {}
    deletes = payload.get("deletes") or []
    if not isinstance(updates, dict):
        return _error(400, "invalid_updates")
    if not isinstance(deletes, list):
        return _error(400, "invalid_deletes")
    if (
        "SUBSCRIPTION_PAGE_CONFIG_JSON" in updates
        and not str(updates.get("SUBSCRIPTION_PAGE_CONFIG_JSON") or "").strip()
    ):
        updates = dict(updates)
        updates.pop("SUBSCRIPTION_PAGE_CONFIG_JSON", None)
        deletes = [*deletes, "SUBSCRIPTION_PAGE_CONFIG_JSON"]

    result = await update_overrides(
        settings,
        async_session_factory,
        updates=updates,
        deletes=deletes,
        actor_id=actor_id,
    )
    if not result.get("ok"):
        return web.json_response(
            {"ok": False, "error": "validation_failed", "errors": result.get("errors", {})},
            status=400,
        )

    await refresh_webapp_runtime_after_settings_change(request, updates=updates, deletes=deletes)

    return _ok({"applied": result.get("applied", 0), "reverted": result.get("reverted", 0)})
