"""Content reports router — public submission + admin management.

Public:
  POST /reports              Submit a content issue report

Admin:
  GET  /admin/reports        List reports (filterable by status, content_type)
  GET  /admin/reports/{id}   Get single report detail
  PATCH /admin/reports/{id}  Update status / add admin notes
"""

import logging
import uuid
from datetime import datetime, timezone
from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from database import get_session
from models import ContentReport, ReportStatus
from schemas import (
    ContentReportCreate,
    ContentReportListResponse,
    ContentReportRead,
    ContentReportUpdate,
)

logger = logging.getLogger("chrysopedia.reports")

router = APIRouter(tags=["reports"])


# ── Public ───────────────────────────────────────────────────────────────────

@router.post("/reports", response_model=ContentReportRead, status_code=201)
async def submit_report(
    body: ContentReportCreate,
    db: AsyncSession = Depends(get_session),
):
    """Submit a content issue report (public, no auth)."""
    report = ContentReport(
        content_type=body.content_type,
        content_id=body.content_id,
        content_title=body.content_title,
        report_type=body.report_type,
        description=body.description,
        page_url=body.page_url,
    )
    db.add(report)
    await db.commit()
    await db.refresh(report)

    logger.info(
        "New content report: id=%s type=%s content=%s/%s",
        report.id, report.report_type, report.content_type, report.content_id,
    )
    return report


# ── Admin ────────────────────────────────────────────────────────────────────

@router.get("/admin/reports", response_model=ContentReportListResponse)
async def list_reports(
    status: Annotated[str | None, Query(description="Filter by status")] = None,
    content_type: Annotated[str | None, Query(description="Filter by content type")] = None,
    offset: Annotated[int, Query(ge=0)] = 0,
    limit: Annotated[int, Query(ge=1, le=100)] = 50,
    db: AsyncSession = Depends(get_session),
):
    """List content reports with optional filters."""
    stmt = select(ContentReport)

    if status:
        stmt = stmt.where(ContentReport.status == status)
    if content_type:
        stmt = stmt.where(ContentReport.content_type == content_type)

    # Count
    count_stmt = select(func.count()).select_from(stmt.subquery())
    total = (await db.execute(count_stmt)).scalar() or 0

    # Fetch page
    stmt = stmt.order_by(ContentReport.created_at.desc())
    stmt = stmt.offset(offset).limit(limit)
    result = await db.execute(stmt)
    items = result.scalars().all()

    return {"items": items, "total": total, "offset": offset, "limit": limit}


@router.get("/admin/reports/{report_id}", response_model=ContentReportRead)
async def get_report(
    report_id: uuid.UUID,
    db: AsyncSession = Depends(get_session),
):
    """Get a single content report by ID."""
    result = await db.execute(
        select(ContentReport).where(ContentReport.id == report_id)
    )
    report = result.scalar_one_or_none()
    if not report:
        raise HTTPException(status_code=404, detail="Report not found")
    return report


@router.patch("/admin/reports/{report_id}", response_model=ContentReportRead)
async def update_report(
    report_id: uuid.UUID,
    body: ContentReportUpdate,
    db: AsyncSession = Depends(get_session),
):
    """Update report status and/or admin notes."""
    result = await db.execute(
        select(ContentReport).where(ContentReport.id == report_id)
    )
    report = result.scalar_one_or_none()
    if not report:
        raise HTTPException(status_code=404, detail="Report not found")

    if body.status is not None:
        # Validate status value
        try:
            ReportStatus(body.status)
        except ValueError:
            raise HTTPException(
                status_code=422,
                detail=f"Invalid status: {body.status}. Must be one of: open, acknowledged, resolved, dismissed",
            )
        report.status = body.status
        if body.status in ("resolved", "dismissed"):
            report.resolved_at = datetime.now(timezone.utc).replace(tzinfo=None)
        elif body.status == "open":
            report.resolved_at = None

    if body.admin_notes is not None:
        report.admin_notes = body.admin_notes

    await db.commit()
    await db.refresh(report)

    logger.info(
        "Report updated: id=%s status=%s",
        report.id, report.status,
    )
    return report
