from __future__ import annotations

import json

from fastapi import APIRouter, Request
from fastapi.responses import RedirectResponse

from app.core.templating import templates
from app.core.db.common import CommonSessionLocal
from app.core.security.csrf import get_or_create_csrf_token
from app.core.security.session_auth import get_current_user
from app.modules.core.audit.service import parse_details, search_audit_logs
from app.modules.core.iam.scope import build_scope
from app.modules.core.iam.services import paginate_list
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
from app.modules.core.rbac.permission_guard import require_permission

router = APIRouter(prefix="/system-settings/audit-logs", tags=["audit-ui"])


def _is_system_admin(db, user) -> bool:
    return "System Admin" in get_user_roles(db, user.id)


def _is_firm_admin(db, user) -> bool:
    return "Firm Admin" in get_user_roles(db, user.id)


@router.get("")
def logs(request: Request, q: str = "", page: int = 1, per_page: int = 20):
    db = CommonSessionLocal()
    try:
        user = get_current_user(request, db=db)
        if not user:
            return RedirectResponse(url="/login", status_code=303)

        try:
            require_permission(db, user, "audit.view")
        except Exception:
            return RedirectResponse(url="/system-settings", status_code=303)

        if not _is_system_admin(db, user) and not _is_firm_admin(db, user):
            return RedirectResponse(url="/system-settings", status_code=303)

        scope = build_scope(db, user)
        rows = search_audit_logs(db, scope, q=q)

        # Enforce final matrix explicitly:
        # - System Admin: all logs
        # - Firm Admin: own tenant logs only
        # - others: none
        if _is_firm_admin(db, user) and not _is_system_admin(db, user):
            rows = [r for r in rows if getattr(r, "target_tenant_id", None) == user.tenant_id]

        paged = paginate_list(rows, page=page, per_page=per_page)
        decorated = []
        for row in paged.items:
            pretty = json.dumps(parse_details(row), indent=2, ensure_ascii=False, default=str)
            setattr(row, "pretty_details", pretty)
            decorated.append(row)

        return templates.TemplateResponse(
            "modules/core/audit/templates/logs.html",
            {
                "request": request,
                "current_user": user,
                "current_user_roles": get_user_roles(db, user.id),
                "current_user_permissions": get_user_permissions(db, user.id),
                "csrf_token": get_or_create_csrf_token(request),
                "title": "Audit Logs",
                "logs": decorated,
                "logs_page": paged,
                "filters": {"q": (q or "").strip(), "per_page": paged.per_page},
            },
        )
    finally:
        db.close()