"""User activity reports API endpoints."""
from __future__ import annotations

import json
from datetime import datetime, timezone

from fastapi import APIRouter, HTTPException, Query, Request

from api.deps import (
    _effective_identity,
    _identity_user_id,
    _require_scope,
    _resolve_langfuse_settings_for_request,
    _record_audit,
)
from api.models import ReportGenerateRequest
from api.state import ROLE_LEVEL
from src.report_generator import (
    generate_daily_report,
    generate_weekly_report,
    generate_monthly_report,
)
from src.tools.helpers import compute_period_end
from src.tools.langfuse_fetch import (
    _build_langfuse_client,
    langfuse_settings_scope,
)
from src.user_store import (
    get_user_report,
    insert_user_report,
    list_user_reports,
    count_user_reports,
    delete_user_report,
)

router = APIRouter()


def _is_admin(request: Request) -> bool:
    identity = _effective_identity(request)
    role = str(identity.get("role") or "viewer")
    return ROLE_LEVEL.get(role, 0) >= ROLE_LEVEL.get("owner", 4)


# ---------------------------------------------------------------------------
# POST /api/reports/generate
# ---------------------------------------------------------------------------


@router.post("/api/reports/generate")
def api_generate_report(payload: ReportGenerateRequest, request: Request):
    _require_scope(request, "reports:write")
    identity = _effective_identity(request)
    caller_user_id = _identity_user_id(request) or str(identity.get("actor", ""))
    is_admin = _is_admin(request)

    # Non-admin can only generate reports for themselves
    if not is_admin and payload.target_user_id != caller_user_id:
        raise HTTPException(status_code=403, detail="Can only generate reports for yourself")

    # Resolve Langfuse settings
    lf_settings = _resolve_langfuse_settings_for_request(request, payload.project_id)

    try:
        with langfuse_settings_scope(lf_settings):
            if payload.period_type == "daily":
                client, cfg, err = _build_langfuse_client({})
                if err:
                    raise HTTPException(status_code=502, detail=f"Langfuse connection failed: {err}")

                report_data = generate_daily_report(
                    client=client,
                    target_user_id=payload.target_user_id,
                    date_str=payload.period_start,
                    project_id=payload.project_id,
                )

            elif payload.period_type == "weekly":
                report_data = generate_weekly_report(
                    owner_id=caller_user_id,
                    project_id=payload.project_id,
                    target_user_id=payload.target_user_id,
                    week_start=payload.period_start,
                )

            elif payload.period_type == "monthly":
                report_data = generate_monthly_report(
                    owner_id=caller_user_id,
                    project_id=payload.project_id,
                    target_user_id=payload.target_user_id,
                    month_start=payload.period_start,
                )
            else:
                raise HTTPException(status_code=400, detail=f"Invalid period_type: {payload.period_type}")

            period_end = compute_period_end(payload.period_start, payload.period_type)

            # Persist to DB
            report_id = insert_user_report(
                owner_id=caller_user_id,
                project_id=payload.project_id,
                target_user_id=payload.target_user_id,
                period_type=payload.period_type,
                period_start=payload.period_start,
                period_end=period_end,
                summary=json.dumps(report_data.get("summary", {}), ensure_ascii=False),
                sessions=json.dumps(report_data.get("sessions", []), ensure_ascii=False),
                model_usage=json.dumps(report_data.get("model_usage", {}), ensure_ascii=False),
                timeline=json.dumps(report_data.get("timeline", []), ensure_ascii=False),
                trace_count=report_data.get("trace_count", 0),
                total_cost=report_data.get("total_cost", 0.0),
                llm_analysis=report_data.get("llm_analysis", ""),
            )

        _record_audit(
            request,
            action="report.generate",
            resource_type="report",
            resource_id=str(report_id),
            detail={"period": payload.period_type, "target": payload.target_user_id, "start": payload.period_start},
        )

        report = get_user_report(report_id)
        return {"ok": True, "data": report}

    except HTTPException:
        raise
    except Exception as exc:
        import logging
        logging.getLogger(__name__).exception("Report generation failed")
        raise HTTPException(status_code=500, detail="Report generation failed")


# ---------------------------------------------------------------------------
# GET /api/reports
# ---------------------------------------------------------------------------


@router.get("/api/reports")
def api_list_reports(
    request: Request,
    target_user_id: str | None = Query(default=None),
    period_type: str | None = Query(default=None),
    project_id: int | None = Query(default=None),
    limit: int = Query(default=50, ge=1, le=200),
    offset: int = Query(default=0, ge=0),
):
    _require_scope(request, "reports:read")
    caller_user_id = _identity_user_id(request)
    is_admin = _is_admin(request)

    # Non-admin: can only see own reports
    if is_admin:
        owner_id = None  # admin sees all
    else:
        owner_id = caller_user_id

    reports = list_user_reports(
        owner_id=owner_id,
        target_user_id=target_user_id,
        period_type=period_type,
        project_id=project_id,
        limit=limit,
        offset=offset,
    )
    total = count_user_reports(
        owner_id=owner_id,
        target_user_id=target_user_id,
        period_type=period_type,
    )

    return {"ok": True, "data": {"items": reports, "total": total, "limit": limit, "offset": offset}}


# ---------------------------------------------------------------------------
# GET /api/reports/{report_id}
# ---------------------------------------------------------------------------


@router.get("/api/reports/{report_id}")
def api_get_report(report_id: int, request: Request):
    _require_scope(request, "reports:read")
    report = get_user_report(report_id)
    if not report:
        raise HTTPException(status_code=404, detail="Report not found")

    caller_user_id = _identity_user_id(request)
    is_admin = _is_admin(request)

    # Non-admin can only see own reports
    if not is_admin and report.get("owner_id") != caller_user_id:
        raise HTTPException(status_code=403, detail="Access denied")

    return {"ok": True, "data": report}


# ---------------------------------------------------------------------------
# DELETE /api/reports/{report_id}
# ---------------------------------------------------------------------------


@router.delete("/api/reports/{report_id}")
def api_delete_report(report_id: int, request: Request):
    _require_scope(request, "reports:admin")

    report = get_user_report(report_id)
    if not report:
        raise HTTPException(status_code=404, detail="Report not found")

    deleted = delete_user_report(report_id)
    if not deleted:
        raise HTTPException(status_code=500, detail="Failed to delete report")

    _record_audit(
        request,
        action="report.delete",
        resource_type="report",
        resource_id=str(report_id),
        detail={"target": report.get("target_user_id"), "period": report.get("period_type")},
    )

    return {"ok": True, "data": {"deleted": True, "report_id": report_id}}
