"""API key management routes for integrations."""
from __future__ import annotations

import uuid
from typing import List, Optional

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

from normbase.api.deps_auth import RequireInternalToken
from normbase.db.connection import get_db
from normbase.schemas import (
    APIKeyIssueRequest,
    APIKeyIssueResponse,
    APIKeyListItem,
    APIKeyResolveRequest,
    APIKeyResolveResponse,
)
from security.auth.api_keys import mask_api_key
from normbase.services.key_service import KeyService

router = APIRouter(prefix="/keys", tags=["keys"])
_key_service = KeyService()


@router.post(
    "/issue",
    response_model=APIKeyIssueResponse,
    status_code=status.HTTP_201_CREATED,
    dependencies=[RequireInternalToken],
)
async def issue_api_key(
    request: APIKeyIssueRequest,
    db: AsyncSession = Depends(get_db),
):
    issued = await _key_service.issue_api_key(
        db,
        agent_id=request.agent_id,
        name=request.name,
        expires_at=request.expires_at,
        scopes=request.scopes,
    )
    record = issued.record
    plain = issued.plain_key
    return APIKeyIssueResponse(
        key_id=str(record.id),
        agent_id=_key_service.agent_uuid_or_500(record.agent_id),
        name=record.name,
        api_key=plain,
        key_preview=mask_api_key(plain),
        scopes=list(record.scopes or []),
        is_active=record.is_active,
        expires_at=record.expires_at,
        created_at=record.created_at,
    )


@router.get("", response_model=List[APIKeyListItem], dependencies=[RequireInternalToken])
async def list_api_keys(
    agent_id: Optional[uuid.UUID] = Query(None, description="Filter by agent_id (UUID)"),
    include_inactive: bool = Query(False),
    db: AsyncSession = Depends(get_db),
):
    rows = await _key_service.list_api_keys(
        db,
        agent_id=agent_id,
        include_inactive=include_inactive,
    )
    return [
        APIKeyListItem(
            key_id=str(item.id),
            agent_id=_key_service.agent_uuid_or_500(item.agent_id) if item.agent_id else None,
            name=item.name,
            key_preview="***",
            scopes=list(item.scopes or []),
            is_active=item.is_active,
            expires_at=item.expires_at,
            created_at=item.created_at,
        )
        for item in rows
    ]


@router.post("/{key_id}/revoke", response_model=APIKeyListItem, dependencies=[RequireInternalToken])
async def revoke_api_key(
    key_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
):
    row = await _key_service.revoke_api_key(db, key_id=key_id)
    return APIKeyListItem(
        key_id=str(row.id),
        agent_id=_key_service.agent_uuid_or_500(row.agent_id) if row.agent_id else None,
        name=row.name,
        key_preview="***",
        scopes=list(row.scopes or []),
        is_active=row.is_active,
        expires_at=row.expires_at,
        created_at=row.created_at,
    )


@router.post("/{key_id}/rotate", response_model=APIKeyIssueResponse, dependencies=[RequireInternalToken])
async def rotate_api_key(
    key_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
):
    issued = await _key_service.rotate_api_key(db, key_id=key_id)
    row = issued.record
    plain = issued.plain_key
    return APIKeyIssueResponse(
        key_id=str(row.id),
        agent_id=_key_service.agent_uuid_or_500(row.agent_id),
        name=row.name,
        api_key=plain,
        key_preview=mask_api_key(plain),
        scopes=list(row.scopes or []),
        is_active=row.is_active,
        expires_at=row.expires_at,
        created_at=row.created_at,
    )


@router.post("/resolve", response_model=APIKeyResolveResponse, dependencies=[RequireInternalToken])
async def resolve_api_key(
    request: APIKeyResolveRequest,
    db: AsyncSession = Depends(get_db),
):
    row = await _key_service.resolve_api_key_from_plain(
        db,
        plain_api_key=request.api_key,
    )
    return APIKeyResolveResponse(
        key_id=str(row.id),
        agent_id=_key_service.agent_uuid_or_500(row.agent_id),
        scopes=list(row.scopes or []),
        is_active=row.is_active,
        expires_at=row.expires_at,
    )


@router.get("/introspect", response_model=APIKeyResolveResponse)
async def introspect_api_key(
    authorization: Optional[str] = Header(default=None),
    x_api_key: Optional[str] = Header(default=None),
    db: AsyncSession = Depends(get_db),
):
    plain = (x_api_key or "").strip() or _key_service.extract_bearer(authorization)
    if not plain:
        raise HTTPException(status_code=401, detail="Missing API key")
    row = await _key_service.resolve_api_key_from_plain(db, plain_api_key=plain)
    return APIKeyResolveResponse(
        key_id=str(row.id),
        agent_id=_key_service.agent_uuid_or_500(row.agent_id),
        scopes=list(row.scopes or []),
        is_active=row.is_active,
        expires_at=row.expires_at,
    )

