from __future__ import annotations

import re

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

from app.core.db.common import CommonSessionLocal
from app.core.http_responses import ui_access_denied
from app.core.security.csrf import get_or_create_csrf_token
from app.core.security.session_auth import get_current_user
from app.core.templating import templates
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
from app.modules.peer_review_export.service import (
    build_peer_review_evidence,
    build_peer_review_zip,
    can_view_peer_review_export,
    list_peer_review_engagements,
)

router = APIRouter(prefix="/peer-review", tags=["peer-review-evidence-export-ui"])


def _ctx(request: Request, db, user, **extra):
    base = {
        "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": "Peer Review Evidence Export",
    }
    base.update(extra)
    return base


def _safe_filename(value: str) -> str:
    value = re.sub(r"[^A-Za-z0-9._-]+", "_", str(value or "").strip())
    value = value.strip("._")
    return value or "peer_review_evidence"


@router.get("/evidence")
def evidence_index(request: Request, financial_year: str = "", q: str = ""):
    db = CommonSessionLocal()
    try:
        user = get_current_user(request, db=db)
        if not user:
            return RedirectResponse(url="/login", status_code=303)
        if not can_view_peer_review_export(db, user):
            return ui_access_denied()
        payload = list_peer_review_engagements(db, request, user, financial_year=financial_year, q=q)
        return templates.TemplateResponse(
            "modules/peer_review_export/templates/peer_review_export/index.html",
            _ctx(request, db, user, **payload),
        )
    finally:
        db.close()


@router.get("/evidence/{subscription_id}")
def evidence_detail(request: Request, subscription_id: int):
    db = CommonSessionLocal()
    try:
        user = get_current_user(request, db=db)
        if not user:
            return RedirectResponse(url="/login", status_code=303)
        if not can_view_peer_review_export(db, user):
            return ui_access_denied()
        try:
            payload = build_peer_review_evidence(db, request, user, subscription_id)
        except ValueError:
            return ui_access_denied()
        return templates.TemplateResponse(
            "modules/peer_review_export/templates/peer_review_export/detail.html",
            _ctx(request, db, user, **payload),
        )
    finally:
        db.close()


@router.get("/evidence/{subscription_id}/export.zip")
def evidence_export_zip(request: Request, subscription_id: int):
    db = CommonSessionLocal()
    try:
        user = get_current_user(request, db=db)
        if not user:
            return RedirectResponse(url="/login", status_code=303)
        if not can_view_peer_review_export(db, user):
            return ui_access_denied()
        try:
            payload = build_peer_review_evidence(db, request, user, subscription_id)
            data = build_peer_review_zip(db, request, user, subscription_id)
        except ValueError:
            return ui_access_denied()
        sub = payload["subscription"]
        client_name = sub.client.client_name if sub.client else "client"
        service_name = sub.catalogue.service_name if sub.catalogue else "service"
        filename = _safe_filename(f"peer_review_{client_name}_{service_name}_{sub.financial_year or 'fy'}_{sub.id}.zip")
        return StreamingResponse(
            iter([data]),
            media_type="application/zip",
            headers={"Content-Disposition": f'attachment; filename="{filename}"'},
        )
    finally:
        db.close()
