import uuid
from datetime import datetime, timedelta, timezone

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

from api.database import get_session
from api.models.legacy_meter import LegacyInterface
from api.schemas.legacy_meter import (
    LegacyInterfacePatch,
    LegacyInterfaceRead,
    LegacyInterfaceRegister,
    LegacyUsageRecord,
    LegacyUsageSummary,
    LegacyWeeklyReview,
)
from api.services.legacy_meter import (
    LegacyUsageIdentity,
    get_legacy_interface_by_key,
    legacy_usage_summary,
    legacy_weekly_review,
    list_legacy_interfaces,
    patch_legacy_interface,
    record_legacy_usage,
    register_legacy_interface,
)

router = APIRouter(prefix="/legacy-meter", tags=["legacy-meter"])


@router.post(
    "/interfaces",
    response_model=LegacyInterfaceRead,
    status_code=status.HTTP_201_CREATED,
)
async def register_interface(
    body: LegacyInterfaceRegister,
    session: AsyncSession = Depends(get_session),
) -> LegacyInterface:
    try:
        return await register_legacy_interface(session, **body.model_dump())
    except ValueError as exc:
        raise HTTPException(status_code=422, detail=str(exc)) from exc


@router.get("/interfaces", response_model=list[LegacyInterfaceRead])
async def list_interfaces(
    session: AsyncSession = Depends(get_session),
) -> list[LegacyInterface]:
    return await list_legacy_interfaces(session)


@router.get("/interfaces/by-key", response_model=LegacyInterfaceRead)
async def get_interface_by_key(
    interface_key: str = Query(...),
    session: AsyncSession = Depends(get_session),
) -> LegacyInterface:
    interface = await get_legacy_interface_by_key(session, interface_key)
    if interface is None:
        raise HTTPException(status_code=404, detail=f"Legacy interface '{interface_key}' not found")
    return interface


@router.patch("/interfaces/{interface_id}", response_model=LegacyInterfaceRead)
async def patch_interface(
    interface_id: uuid.UUID,
    body: LegacyInterfacePatch,
    session: AsyncSession = Depends(get_session),
) -> LegacyInterface:
    interface = await session.get(LegacyInterface, interface_id)
    if interface is None:
        raise HTTPException(status_code=404, detail=f"Legacy interface '{interface_id}' not found")
    try:
        return await patch_legacy_interface(
            session,
            interface,
            body.model_dump(exclude_unset=True),
        )
    except ValueError as exc:
        raise HTTPException(status_code=422, detail=str(exc)) from exc


@router.post("/usage", response_model=LegacyInterfaceRead, status_code=status.HTTP_201_CREATED)
async def record_usage(
    body: LegacyUsageRecord,
    session: AsyncSession = Depends(get_session),
) -> LegacyInterface:
    try:
        return await record_legacy_usage(
            session,
            interface_key=body.interface_key,
            interface_kind=body.interface_kind,
            replacement_ref=body.replacement_ref,
            owner_component=body.owner_component,
            replacement_verified=body.replacement_verified,
            identity=LegacyUsageIdentity(
                tenant_key=body.tenant_key or "unknown",
                user_key=body.user_key or "unknown",
                component_key=body.component_key or "unknown",
            ),
            observed_at=body.observed_at,
            call_count=body.call_count,
        )
    except ValueError as exc:
        raise HTTPException(status_code=422, detail=str(exc)) from exc


@router.get("/summary", response_model=LegacyUsageSummary)
async def usage_summary(
    days: int = Query(7, ge=1, le=366),
    window_start: datetime | None = None,
    window_end: datetime | None = None,
    session: AsyncSession = Depends(get_session),
) -> LegacyUsageSummary:
    end = window_end or datetime.now(tz=timezone.utc)
    start = window_start or (end - timedelta(days=days))
    return await legacy_usage_summary(session, window_start=start, window_end=end)


@router.get("/weekly-review", response_model=LegacyWeeklyReview)
async def weekly_review(
    days: int = Query(7, ge=1, le=366),
    window_start: datetime | None = None,
    window_end: datetime | None = None,
    session: AsyncSession = Depends(get_session),
) -> LegacyWeeklyReview:
    end = window_end or datetime.now(tz=timezone.utc)
    start = window_start or (end - timedelta(days=days))
    return await legacy_weekly_review(session, window_start=start, window_end=end)
