"""Agent BFF — proxies eda_agent with org and field checks."""

from __future__ import annotations

import uuid
from typing import Any

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

from aif_platform.server.api.deps import get_eda_client, get_normbase_client, get_org_context
from aif_platform.server.infra.upstream import EdaClient, NormbaseClient
from aif_platform.server.models.persistence import PlatformUser
from aif_platform.server.services.access import (
    active_fields_allowed_for_org,
    require_agent_in_org,
)

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


@router.get("")
async def list_agents(
    ctx: tuple[PlatformUser, uuid.UUID] = Depends(get_org_context),
    eda: EdaClient = Depends(get_eda_client),
    limit: int = Query(100, ge=1, le=500),
):
    _user, org_id = ctx
    raw = await eda.list_agents(limit=limit)
    if not isinstance(raw, list):
        return []
    return [a for a in raw if isinstance(a, dict) and a.get("org_id") and str(a["org_id"]) == str(org_id)]


@router.post("", status_code=201)
async def create_agent(
    body: dict[str, Any] = Body(...),
    ctx: tuple[PlatformUser, uuid.UUID] = Depends(get_org_context),
    eda: EdaClient = Depends(get_eda_client),
    nb: NormbaseClient = Depends(get_normbase_client),
):
    _user, org_id = ctx
    payload = {**body, "org_id": str(org_id)}
    active = payload.get("active_fields") or []
    if isinstance(active, list) and active:
        ok = await active_fields_allowed_for_org(
            nb,
            active_field_ids=[str(x) for x in active],
            org_id=org_id,
        )
        if not ok:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="active_fields must reference fields in the current organization.",
            )
    return await eda.create_agent(payload)


@router.get("/{agent_id}")
async def get_agent(
    agent_id: uuid.UUID,
    ctx: tuple[PlatformUser, uuid.UUID] = Depends(get_org_context),
    eda: EdaClient = Depends(get_eda_client),
):
    _user, org_id = ctx
    return await require_agent_in_org(eda, agent_id=agent_id, org_id=org_id)


@router.patch("/{agent_id}")
async def patch_agent(
    agent_id: uuid.UUID,
    body: dict[str, Any] = Body(...),
    ctx: tuple[PlatformUser, uuid.UUID] = Depends(get_org_context),
    eda: EdaClient = Depends(get_eda_client),
    nb: NormbaseClient = Depends(get_normbase_client),
):
    _user, org_id = ctx
    await require_agent_in_org(eda, agent_id=agent_id, org_id=org_id)
    payload = {**body}
    if "org_id" in payload and payload["org_id"] is not None:
        if str(payload["org_id"]) != str(org_id):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="org_id must stay within the current organization.",
            )
    if "active_fields" in payload and payload["active_fields"] is not None:
        af = payload["active_fields"]
        if isinstance(af, list) and af:
            ok = await active_fields_allowed_for_org(
                nb,
                active_field_ids=[str(x) for x in af],
                org_id=org_id,
            )
            if not ok:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="active_fields must reference fields in the current organization.",
                )
    return await eda.patch_agent(agent_id, payload)


@router.delete("/{agent_id}")
async def delete_agent(
    agent_id: uuid.UUID,
    ctx: tuple[PlatformUser, uuid.UUID] = Depends(get_org_context),
    eda: EdaClient = Depends(get_eda_client),
):
    _user, org_id = ctx
    await require_agent_in_org(eda, agent_id=agent_id, org_id=org_id)
    await eda.delete_agent(agent_id)
    return Response(status_code=status.HTTP_204_NO_CONTENT)
