"""Regression test routes — capture / list / replay / archive / delete.

Every mutation records an activity event via the activity middleware so
the user always sees their own curation history in /activity.
"""

from __future__ import annotations

from dataclasses import asdict

from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel

router = APIRouter(prefix="/regressions", tags=["regressions"])


class CaptureRequest(BaseModel):
    correlation_id: str
    name: str
    description: str = ""


class ArchiveRequest(BaseModel):
    archived: bool = True


def _service(request: Request):
    svc = getattr(request.app.state, "regressions", None)
    if svc is None:
        raise HTTPException(status_code=503, detail="regression service not configured")
    return svc


@router.post("/capture")
async def capture(request: Request, body: CaptureRequest) -> dict:
    """Capture a correlation chain as a regression baseline."""
    svc = _service(request)
    try:
        test = await svc.capture(
            correlation_id=body.correlation_id,
            name=body.name,
            description=body.description,
        )
    except ValueError as exc:
        raise HTTPException(status_code=400, detail=str(exc)) from exc
    return asdict(test)


@router.get("")
async def list_regressions(
    request: Request,
    archived: bool = False,
    limit: int = 50,
    offset: int = 0,
) -> dict:
    svc = _service(request)
    tests = await svc.list(archived=archived, limit=limit, offset=offset)
    total = await svc.count(archived=archived)
    return {
        "tests": [asdict(t) for t in tests],
        "total": total,
        "archived": archived,
        "limit": limit,
        "offset": offset,
    }


@router.get("/{regression_id}")
async def get_regression(request: Request, regression_id: int) -> dict:
    svc = _service(request)
    test = await svc.get(regression_id)
    if test is None:
        raise HTTPException(status_code=404, detail="regression not found")
    return asdict(test)


@router.post("/{regression_id}/replay")
async def replay(request: Request, regression_id: int) -> dict:
    svc = _service(request)
    result = await svc.replay(regression_id)
    if result.get("status") == "not_found":
        raise HTTPException(status_code=404, detail="regression not found")
    return result


@router.patch("/{regression_id}")
async def update_archive(
    request: Request, regression_id: int, body: ArchiveRequest,
) -> dict:
    svc = _service(request)
    ok = await svc.set_archived(regression_id, body.archived)
    if not ok:
        raise HTTPException(status_code=404, detail="regression not found")
    return {"status": "ok", "regression_id": regression_id, "archived": body.archived}


@router.delete("/{regression_id}")
async def delete_regression(request: Request, regression_id: int) -> dict:
    svc = _service(request)
    ok = await svc.delete(regression_id)
    if not ok:
        raise HTTPException(status_code=404, detail="regression not found")
    return {"status": "ok", "regression_id": regression_id}
