"""Field API keys BFF — normbase keys/field/* with field/org checks."""

from __future__ import annotations

import uuid
from typing import Any

from fastapi import APIRouter, Body, Depends, HTTPException, Query, status

from aif_platform.server.api.deps import get_normbase_client, get_org_context
from aif_platform.server.infra.upstream import NormbaseClient
from aif_platform.server.models.persistence import PlatformUser
from aif_platform.server.services.access import require_field_in_org

router = APIRouter(prefix="/field-keys", tags=["field-keys"])


async def _key_belongs_to_field(nb: NormbaseClient, *, key_id: uuid.UUID, field_id: uuid.UUID) -> bool:
    rows = await nb.list_keys({"field_id": str(field_id), "include_inactive": "true"})
    if not isinstance(rows, list):
        return False
    for row in rows:
        if isinstance(row, dict) and str(row.get("key_id")) == str(key_id):
            return True
    return False


@router.post("/issue", status_code=201)
async def issue_field_key(
    body: dict[str, Any] = Body(...),
    ctx: tuple[PlatformUser, uuid.UUID] = Depends(get_org_context),
    nb: NormbaseClient = Depends(get_normbase_client),
):
    _user, org_id = ctx
    fid = body.get("field_id")
    if not fid:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="field_id is required.",
        )
    field_uuid = uuid.UUID(str(fid))
    await require_field_in_org(nb, field_id=field_uuid, org_id=org_id)
    return await nb.issue_field_key(body)


@router.get("")
async def list_field_keys(
    ctx: tuple[PlatformUser, uuid.UUID] = Depends(get_org_context),
    nb: NormbaseClient = Depends(get_normbase_client),
    field_id: uuid.UUID = Query(..., description="List keys for this field (must be in your org)."),
    include_inactive: bool = Query(False),
):
    _user, org_id = ctx
    await require_field_in_org(nb, field_id=field_id, org_id=org_id)
    return await nb.list_keys(
        {"field_id": str(field_id), "include_inactive": include_inactive}
    )


@router.post("/{key_id}/revoke")
async def revoke_field_key(
    key_id: uuid.UUID,
    ctx: tuple[PlatformUser, uuid.UUID] = Depends(get_org_context),
    nb: NormbaseClient = Depends(get_normbase_client),
    field_id: uuid.UUID = Query(...),
):
    _user, org_id = ctx
    await require_field_in_org(nb, field_id=field_id, org_id=org_id)
    if not await _key_belongs_to_field(nb, key_id=key_id, field_id=field_id):
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Key not found for field.")
    return await nb.revoke_key(key_id)


@router.post("/{key_id}/rotate", status_code=201)
async def rotate_field_key(
    key_id: uuid.UUID,
    ctx: tuple[PlatformUser, uuid.UUID] = Depends(get_org_context),
    nb: NormbaseClient = Depends(get_normbase_client),
    field_id: uuid.UUID = Query(...),
):
    _user, org_id = ctx
    await require_field_in_org(nb, field_id=field_id, org_id=org_id)
    if not await _key_belongs_to_field(nb, key_id=key_id, field_id=field_id):
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Key not found for field.")
    return await nb.rotate_key(key_id)
