# retoor <retoor@molodetz.nl>

import logging
from typing import Annotated

from fastapi import APIRouter, Depends, Request

from devplacepy.database import (
    CONSENT_KINDS,
    consent_state,
    get_setting,
    get_table,
    list_consents,
    set_consent,
)
from devplacepy.dependencies import json_or_form
from devplacepy.models import ConsentForm, MaturePreferenceForm
from devplacepy.responses import action_result
from devplacepy.routers.profile.delete import _owner_only
from devplacepy.services.audit import record as audit
from devplacepy.utils import clear_user_cache

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

TRUTHY = ("1", "on", "true", "yes")

VERSION_KEYS = {"terms": "terms_version", "privacy": "privacy_version"}


def consent_view(owner_kind: str, owner_id: str) -> list[dict]:
    latest = {}
    for row in list_consents(owner_kind, owner_id):
        latest.setdefault(row["kind"], row)
    return [
        {
            "kind": kind,
            "label": label,
            "state": (latest.get(kind) or {}).get("state", "withdrawn"),
            "version": (latest.get(kind) or {}).get("version", ""),
            "granted_at": (latest.get(kind) or {}).get("granted_at", ""),
            "withdrawn_at": (latest.get(kind) or {}).get("withdrawn_at", ""),
        }
        for kind, label in CONSENT_KINDS.items()
    ]


def consent_version(kind: str) -> str:
    key = VERSION_KEYS.get(kind)
    return (get_setting(key, "1") or "1") if key else "1"


@router.post("/{username}/consent")
async def set_user_consent(
    request: Request,
    username: str,
    data: Annotated[ConsentForm, Depends(json_or_form(ConsentForm))],
):
    target, denied = _owner_only(
        request, username, "Only the account holder can change a consent"
    )
    if denied is not None:
        return denied
    granted = data.granted.strip().lower() in TRUTHY
    before = consent_state("user", target["uid"], data.kind)
    set_consent(
        "user", target["uid"], data.kind, granted, version=consent_version(data.kind)
    )
    logger.info(
        f"Consent {data.kind} {'granted' if granted else 'withdrawn'} for {target['username']}"
    )
    audit.record(
        request,
        "consent.grant" if granted else "consent.withdraw",
        target_type="user",
        target_uid=target["uid"],
        target_label=target["username"],
        old_value=(before or {}).get("state"),
        new_value="granted" if granted else "withdrawn",
        metadata={"kind": data.kind},
        summary=(
            f"{'granted' if granted else 'withdrew'} {data.kind} consent "
            f"for {target['username']}"
        ),
        links=[audit.target("user", target["uid"], target["username"])],
    )
    url = f"/profile/{target['username']}?tab=privacy"
    return action_result(
        request,
        url,
        data={"kind": data.kind, "state": "granted" if granted else "withdrawn"},
    )


@router.post("/{username}/mature-content")
async def set_mature_preference(
    request: Request,
    username: str,
    data: Annotated[MaturePreferenceForm, Depends(json_or_form(MaturePreferenceForm))],
):
    target, denied = _owner_only(
        request,
        username,
        "Only the account holder can change the mature-content preference",
    )
    if denied is not None:
        return denied
    opted_in = data.mature_opt_in.strip().lower() in TRUTHY
    get_table("users").update(
        {"uid": target["uid"], "mature_opt_in": 1 if opted_in else 0}, ["uid"]
    )
    clear_user_cache(target["uid"])
    audit.record(
        request,
        "profile.mature_content",
        target_type="user",
        target_uid=target["uid"],
        target_label=target["username"],
        new_value=1 if opted_in else 0,
        summary=(
            f"{'enabled' if opted_in else 'disabled'} mature content "
            f"for {target['username']}"
        ),
        links=[audit.target("user", target["uid"], target["username"])],
    )
    url = f"/profile/{target['username']}?tab=privacy"
    return action_result(request, url, data={"mature_opt_in": opted_in})
