"""FastAPI router for delegation lifecycle.

Endpoints (originally from llm-principal-broker, now in-process):
  POST   /delegations/                  create_delegation       §8.1
  POST   /delegations/{id}/revoke       revoke_delegation       §8.2
  GET    /delegations/{id}              get_delegation          §8.3
  GET    /delegations/                  list_delegations        §8.4
"""

from datetime import datetime

from fastapi import APIRouter, Header, HTTPException

from .lifecycle import DelegationManager
from .models import (
    ActiveDelegation,
    AgentListResponse,
    DelegationInfo,
    DelegationRequest,
    DelegationResponse,
    DelegationStatus,
    RevokeRequest,
    RevokeResponse,
)
from .storage import get_active_delegations, get_delegation as db_get

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

# A single DelegationManager instance is shared across requests. It holds the
# AgentRegistrar (Keycloak/Entra/Stub) and is constructed once at import time.
manager = DelegationManager()


@router.post("/", response_model=DelegationResponse)
async def create_delegation(
    request: DelegationRequest,
    x_delegator_did: str = Header(..., alias="X-Delegator-DID"),
):
    """Request delegation of authority to an AI agent (§8.1)."""
    try:
        return await manager.create_delegation(request, x_delegator_did)
    except RuntimeError as e:
        raise HTTPException(status_code=502, detail=str(e))


@router.post("/{delegation_id}/revoke", response_model=RevokeResponse)
async def revoke_delegation(
    delegation_id: str,
    request: RevokeRequest = RevokeRequest(),
):
    """Revoke an active delegation (§8.2)."""
    success = await manager.revoke_delegation(delegation_id, request.reason)
    if not success:
        raise HTTPException(status_code=404, detail="Delegation not found or not active")
    return RevokeResponse(delegation_id=delegation_id, reason=request.reason)


@router.get("/{delegation_id}", response_model=DelegationInfo)
async def get_delegation(delegation_id: str):
    """Query delegation status (§8.3)."""
    d = await db_get(delegation_id)
    if not d:
        raise HTTPException(status_code=404, detail="Delegation not found")

    now = datetime.utcnow()
    ttl_remaining = max(0, int((d.expires_at - now).total_seconds()))

    return DelegationInfo(
        delegation_id=d.delegation_id,
        status=DelegationStatus(d.status),
        agent_did=d.agent_did,
        agent_type=d.agent_type,
        delegator_did=d.delegator_did,
        commands_executed=d.commands_executed,
        commands_remaining=max(0, d.max_commands - d.commands_executed),
        ttl_remaining_seconds=ttl_remaining,
        created_at=d.created_at.isoformat(),
        expires_at=d.expires_at.isoformat(),
    )


@router.get("/", response_model=AgentListResponse)
async def list_delegations():
    """List all active agent delegations (§8.4)."""
    active = await get_active_delegations()
    now = datetime.utcnow()

    return AgentListResponse(
        active_delegations=[
            ActiveDelegation(
                delegation_id=d.delegation_id,
                agent_type=d.agent_type,
                delegator=d.delegator_did,
                commands_executed=d.commands_executed,
                ttl_remaining_seconds=max(
                    0, int((d.expires_at - now).total_seconds())
                ),
                status=d.status,
            )
            for d in active
        ],
        total_active=len(active),
    )
