# retoor <retoor@molodetz.nl>

import logging
from typing import Annotated
from fastapi import Depends, APIRouter, Request
from fastapi.responses import HTMLResponse
from devplacepy.models import AdminSettingsForm
from devplacepy.database import get_table, clear_settings_cache
from devplacepy.utils import require_admin, generate_uid
from devplacepy.seo import base_seo_context, site_url, website_schema
from devplacepy.responses import respond, action_result
from devplacepy.schemas import AdminSettingsOut
from devplacepy.services.audit import record as audit
from devplacepy.dependencies import json_or_form

logger = logging.getLogger(__name__)
router = APIRouter()

CLEARABLE_SETTINGS = {"extra_head", "ios_app_url"}

@router.get("/settings", response_class=HTMLResponse)
async def admin_settings(request: Request):
    admin = require_admin(request)
    settings = get_table("site_settings")
    all_settings = {s["key"]: s["value"] for s in settings.all()}
    base = site_url(request)
    seo_ctx = base_seo_context(
        request,
        title="Settings - Admin",
        description="Manage DevPlace site settings.",
        robots="noindex,nofollow",
        breadcrumbs=[
            {"name": "Home", "url": "/feed"},
            {"name": "Admin", "url": "/admin"},
            {"name": "Settings", "url": "/admin/settings"},
        ],
        schemas=[website_schema(base)],
    )
    return respond(
        request,
        "admin_settings.html",
        {
            **seo_ctx,
            "request": request,
            "user": admin,
            "settings": all_settings,
            "admin_section": "settings",
        },
        model=AdminSettingsOut,
    )

@router.post("/settings")
async def admin_settings_save(
    request: Request, data: Annotated[AdminSettingsForm, Depends(json_or_form(AdminSettingsForm))]
):
    admin = require_admin(request)
    settings = get_table("site_settings")
    changes = []
    for key, value in data.model_dump().items():
        existing = settings.find_one(key=key)
        if existing:
            if value == "" and key not in CLEARABLE_SETTINGS:
                continue
            old_value = existing.get("value")
            if str(old_value) == str(value):
                continue
            settings.update({"id": existing["id"], "key": key, "value": value}, ["id"])
            changes.append((key, old_value, value))
        else:
            settings.insert({"uid": generate_uid(), "key": key, "value": value})
            changes.append((key, None, value))
    clear_settings_cache()
    logger.info(f"Admin {admin['username']} updated settings")
    for key, old_value, new_value in changes:
        audit.record(
            request,
            "admin.setting.update",
            user=admin,
            target_type="setting",
            target_uid=key,
            target_label=key,
            old_value=old_value,
            new_value=new_value,
            summary=f"admin {admin['username']} updated setting {key}",
            links=[audit.setting(key)],
        )
    return action_result(request, "/admin/settings")

