# retoor <retoor@molodetz.nl>

import logging
from typing import Annotated

from fastapi import APIRouter, Depends, Request
from fastapi.responses import HTMLResponse

from devplacepy.database import (
    REPORTABLE_TARGETS,
    REPORT_SEVERITIES,
    REPORT_STATUSES,
    report_reason_options,
)
from devplacepy.dependencies import json_or_form
from devplacepy.models import ReportForm
from devplacepy.responses import action_result, json_error, respond
from devplacepy.schemas import ReportListOut, ReportReasonsOut
from devplacepy.seo import base_seo_context, site_url, website_schema
from devplacepy.services.audit import record as audit
from devplacepy.services.moderation import queue, sla
from devplacepy.utils import create_notification, get_current_user, require_user

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


@router.get("/reasons")
async def report_reasons(request: Request):
    base = site_url(request)
    return respond(
        request,
        "report_reasons.html",
        {
            **base_seo_context(
                request,
                title="Report reasons",
                description="The categories DevPlace accepts content reports under.",
                breadcrumbs=[
                    {"name": "Home", "url": "/feed"},
                    {"name": "Report reasons", "url": "/reports/reasons"},
                ],
                schemas=[website_schema(base)],
            ),
            "request": request,
            "user": get_current_user(request),
            "reasons": report_reason_options(),
            "severities": list(REPORT_SEVERITIES),
        },
        model=ReportReasonsOut,
    )


@router.get("/mine", response_class=HTMLResponse)
async def my_reports(request: Request, status: str = "", page: int = 1):
    user = require_user(request)
    if status not in REPORT_STATUSES:
        status = ""
    reports, pagination = queue.list_reports(
        status=status, reporter_uid=user["uid"], page=page
    )
    base = site_url(request)
    seo_ctx = base_seo_context(
        request,
        title="Your reports",
        description="The reports you filed and the outcome of each.",
        robots="noindex,nofollow",
        breadcrumbs=[
            {"name": "Home", "url": "/feed"},
            {"name": "Your reports", "url": "/reports/mine"},
        ],
        schemas=[website_schema(base)],
    )
    return respond(
        request,
        "reports_mine.html",
        {
            **seo_ctx,
            "request": request,
            "user": user,
            "reports": reports,
            "pagination": pagination,
            "status": status,
            "reasons": report_reason_options(),
        },
        model=ReportListOut,
    )


@router.post("/{target_type}/{target_uid}")
async def submit_report(
    request: Request,
    target_type: str,
    target_uid: str,
    data: Annotated[ReportForm, Depends(json_or_form(ReportForm))],
):
    user = require_user(request)
    if target_type not in REPORTABLE_TARGETS:
        return json_error(400, "Unknown report target")
    owner_uid = queue.owner_uid_for(target_type, target_uid)
    if owner_uid and owner_uid == user["uid"]:
        return json_error(400, "You cannot report your own content")
    report = queue.raise_report(
        target_type=target_type,
        target_uid=target_uid,
        reporter_uid=user["uid"],
        reason=data.reason,
        detail=data.detail,
        origin="member",
    )
    if not report:
        return json_error(400, "Report could not be filed")
    hours = sla.sla_hours()
    logger.info(
        f"{user['username']} reported {target_type} {target_uid} as {data.reason}"
    )
    audit.record(
        request,
        "report.create",
        user=user,
        target_type=target_type,
        target_uid=target_uid,
        metadata={"reason": data.reason, "severity": report["severity"]},
        summary=f"{user['username']} reported {target_type} {target_uid} as {data.reason}",
        links=[audit.target(target_type, target_uid)],
    )
    create_notification(
        user["uid"],
        "moderation",
        f"Report received. A moderator reviews it within {hours} hours.",
        user["uid"],
        "/reports/mine",
    )
    return action_result(
        request,
        "/reports/mine",
        data={
            "uid": report["uid"],
            "status": report["status"],
            "severity": report["severity"],
            "sla_hours": hours,
        },
    )
