# retoor <retoor@molodetz.nl>

import logging
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from devplacepy.database import (
    get_table,
    list_deleted,
    count_deleted,
    restore_event,
    purge_event,
    get_users_by_uids,
    resolve_object_url,
)
from devplacepy.attachments import _unlink_attachment_files
from devplacepy.project_files import _unlink_blob
from devplacepy.utils import require_admin, not_found
from devplacepy.seo import base_seo_context, site_url, website_schema
from devplacepy.responses import respond, action_result
from devplacepy.schemas import AdminTrashOut
from devplacepy.services.audit import record as audit

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

TRASH_TABLES = [
    {"key": "posts", "label": "Posts", "icon": "\U0001f4dd", "type": "post"},
    {"key": "comments", "label": "Comments", "icon": "\U0001f4ac", "type": "comment"},
    {"key": "gists", "label": "Gists", "icon": "\U0001f4cb", "type": "gist"},
    {"key": "projects", "label": "Projects", "icon": "\U0001f680", "type": "project"},
    {"key": "news", "label": "News", "icon": "\U0001f4f0", "type": "news"},
    {"key": "awards", "label": "Awards", "icon": "\U0001f3c6", "type": "award"},
    {"key": "quizzes", "label": "Quizzes", "icon": "\U0001f9e9", "type": "quiz"},
    {"key": "project_files", "label": "Project files", "icon": "\U0001f4c1", "type": None},
    {"key": "attachments", "label": "Attachments", "icon": "\U0001f4ce", "type": None},
]
_TRASH_KEYS = {entry["key"] for entry in TRASH_TABLES}
_TRASH_TYPE = {entry["key"]: entry["type"] for entry in TRASH_TABLES}


def _trash_label(table: str, row: dict) -> str:
    for field in ("title", "name", "path", "original_filename", "question", "content"):
        value = row.get(field)
        if value:
            return str(value)[:80]
    return row.get("slug") or row.get("uid", "")


def _trash_target_url(table: str, row: dict) -> str | None:
    target_type = _TRASH_TYPE.get(table)
    if target_type:
        return resolve_object_url(target_type, row["uid"])
    return None


@router.get("/trash", response_class=HTMLResponse)
async def admin_trash(request: Request, table: str = "posts", page: int = 1):
    admin = require_admin(request)
    if table not in _TRASH_KEYS:
        table = "posts"
    rows, pagination = list_deleted(table, page)
    actor_ids = [r.get("deleted_by") for r in rows if r.get("deleted_by")]
    actors = get_users_by_uids([a for a in actor_ids if a]) if actor_ids else {}
    items = []
    for row in rows:
        actor = actors.get(row.get("deleted_by"))
        items.append(
            {
                "uid": row["uid"],
                "table": table,
                "label": _trash_label(table, row),
                "deleted_at": row.get("deleted_at"),
                "deleted_by": actor["username"] if actor else row.get("deleted_by"),
                "target_url": _trash_target_url(table, row),
            }
        )
    tabs = [
        {**entry, "count": count_deleted(entry["key"]), "active": entry["key"] == table}
        for entry in TRASH_TABLES
    ]
    base = site_url(request)
    seo_ctx = base_seo_context(
        request,
        title="Trash - Admin",
        description="Restore or permanently remove soft-deleted content.",
        breadcrumbs=[
            {"name": "Home", "url": "/feed"},
            {"name": "Admin", "url": "/admin"},
            {"name": "Trash", "url": "/admin/trash"},
        ],
        schemas=[website_schema(base)],
        robots="noindex,nofollow",
    )
    return respond(
        request,
        "admin_trash.html",
        {
            **seo_ctx,
            "request": request,
            "user": admin,
            "items": items,
            "table": table,
            "tables": tabs,
            "pagination": pagination,
            "admin_section": "trash",
        },
        model=AdminTrashOut,
    )


@router.post("/trash/{table}/{uid}/restore")
async def admin_trash_restore(request: Request, table: str, uid: str):
    admin = require_admin(request)
    if table not in _TRASH_KEYS:
        raise not_found("Unknown trash table")
    row = get_table(table).find_one(uid=uid)
    if row and row.get("deleted_at"):
        restored = restore_event(row["deleted_at"])
        if table == "awards":
            from devplacepy.database.awards import recompute_user_award_stats

            recompute_user_award_stats(row.get("receiver_uid", ""))
        logger.info(
            f"Admin {admin['username']} restored {table} {uid} ({restored} rows)"
        )
        audit.record(
            request,
            "admin.trash.restore",
            user=admin,
            target_type=table,
            target_uid=uid,
            target_label=_trash_label(table, row),
            metadata={"table": table, "rows": restored},
            summary=f"{admin['username']} restored {table} {uid}",
        )
    return action_result(request, f"/admin/trash?table={table}")


@router.post("/trash/{table}/{uid}/purge")
async def admin_trash_purge(request: Request, table: str, uid: str):
    admin = require_admin(request)
    if table not in _TRASH_KEYS:
        raise not_found("Unknown trash table")
    row = get_table(table).find_one(uid=uid)
    if row and row.get("deleted_at"):
        purged = purge_event(row["deleted_at"])
        for purged_table, purged_rows in purged:
            if purged_table == "attachments":
                for attachment in purged_rows:
                    _unlink_attachment_files(attachment)
            elif purged_table == "project_files":
                for node in purged_rows:
                    if node.get("is_binary"):
                        _unlink_blob(node)
        logger.info(f"Admin {admin['username']} purged {table} {uid}")
        audit.record(
            request,
            "admin.trash.purge",
            user=admin,
            target_type=table,
            target_uid=uid,
            target_label=_trash_label(table, row),
            metadata={"table": table, "tables": [t for t, _ in purged]},
            summary=f"{admin['username']} permanently purged {table} {uid}",
        )
    return action_result(request, f"/admin/trash?table={table}")
