"""
ABI Server Configuration API
Manage external ABI servers per workspace.
"""

from datetime import datetime, timezone
from uuid import uuid4

from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel, Field
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.database import get_db
from app.models import ABIServerModel
from app.api.endpoints.auth import User, get_current_user_required, require_workspace_access
from app.api.endpoints.secrets import _encrypt, _decrypt

router = APIRouter()


# ============ Pydantic Schemas ============

class ABIServer(BaseModel):
    """ABI Server model."""
    id: str
    workspace_id: str
    name: str
    endpoint: str
    enabled: bool
    created_at: datetime
    updated_at: datetime


class ABIServerCreate(BaseModel):
    """Create ABI server request."""
    name: str = Field(..., min_length=1, max_length=255)
    endpoint: str = Field(..., min_length=1)
    api_key: str | None = None


class ABIServerUpdate(BaseModel):
    """Update ABI server request."""
    name: str | None = Field(None, min_length=1, max_length=255)
    endpoint: str | None = Field(None, min_length=1)
    api_key: str | None = None
    enabled: bool | None = None


# ============ Helpers ============

def _to_abi_server(row: ABIServerModel) -> ABIServer:
    return ABIServer(
        id=row.id,
        workspace_id=row.workspace_id,
        name=row.name,
        endpoint=row.endpoint,
        enabled=row.enabled,
        created_at=row.created_at,
        updated_at=row.updated_at,
    )


# ============ Endpoints ============

@router.get("/workspaces/{workspace_id}/abi-servers")
async def list_abi_servers(
    workspace_id: str,
    current_user: User = Depends(get_current_user_required),
    db: AsyncSession = Depends(get_db),
) -> list[ABIServer]:
    """List all ABI servers for a workspace."""
    await require_workspace_access(current_user.id, workspace_id)
    
    result = await db.execute(
        select(ABIServerModel).where(ABIServerModel.workspace_id == workspace_id)
    )
    return [_to_abi_server(row) for row in result.scalars().all()]


@router.post("/workspaces/{workspace_id}/abi-servers")
async def create_abi_server(
    workspace_id: str,
    server: ABIServerCreate,
    current_user: User = Depends(get_current_user_required),
    db: AsyncSession = Depends(get_db),
) -> ABIServer:
    """Create a new ABI server for a workspace."""
    await require_workspace_access(current_user.id, workspace_id)
    
    # Check if endpoint already exists for this workspace
    existing = await db.execute(
        select(ABIServerModel).where(
            ABIServerModel.workspace_id == workspace_id,
            ABIServerModel.endpoint == server.endpoint,
        )
    )
    if existing.scalar_one_or_none():
        raise HTTPException(status_code=400, detail="ABI server with this endpoint already exists")
    
    now = datetime.now(timezone.utc).replace(tzinfo=None)
    server_id = f"abi-{uuid4().hex[:12]}"
    
    row = ABIServerModel(
        id=server_id,
        workspace_id=workspace_id,
        name=server.name,
        endpoint=server.endpoint,
        api_key=_encrypt(server.api_key) if server.api_key else None,
        enabled=True,
        created_at=now,
        updated_at=now,
    )
    
    db.add(row)
    await db.commit()
    
    return _to_abi_server(row)


@router.get("/workspaces/{workspace_id}/abi-servers/{server_id}")
async def get_abi_server(
    workspace_id: str,
    server_id: str,
    current_user: User = Depends(get_current_user_required),
    db: AsyncSession = Depends(get_db),
) -> ABIServer:
    """Get a specific ABI server."""
    await require_workspace_access(current_user.id, workspace_id)
    
    result = await db.execute(
        select(ABIServerModel).where(
            ABIServerModel.id == server_id,
            ABIServerModel.workspace_id == workspace_id,
        )
    )
    row = result.scalar_one_or_none()
    if not row:
        raise HTTPException(status_code=404, detail="ABI server not found")
    
    return _to_abi_server(row)


@router.put("/workspaces/{workspace_id}/abi-servers/{server_id}")
async def update_abi_server(
    workspace_id: str,
    server_id: str,
    updates: ABIServerUpdate,
    current_user: User = Depends(get_current_user_required),
    db: AsyncSession = Depends(get_db),
) -> ABIServer:
    """Update an ABI server."""
    await require_workspace_access(current_user.id, workspace_id)
    
    result = await db.execute(
        select(ABIServerModel).where(
            ABIServerModel.id == server_id,
            ABIServerModel.workspace_id == workspace_id,
        )
    )
    row = result.scalar_one_or_none()
    if not row:
        raise HTTPException(status_code=404, detail="ABI server not found")
    
    now = datetime.now(timezone.utc).replace(tzinfo=None)
    
    if updates.name is not None:
        row.name = updates.name
    if updates.endpoint is not None:
        row.endpoint = updates.endpoint
    if updates.api_key is not None:
        row.api_key = _encrypt(updates.api_key) if updates.api_key else None
    if updates.enabled is not None:
        row.enabled = updates.enabled
    
    row.updated_at = now
    await db.commit()
    
    return _to_abi_server(row)


@router.delete("/workspaces/{workspace_id}/abi-servers/{server_id}")
async def delete_abi_server(
    workspace_id: str,
    server_id: str,
    current_user: User = Depends(get_current_user_required),
    db: AsyncSession = Depends(get_db),
) -> dict[str, str]:
    """Delete an ABI server."""
    await require_workspace_access(current_user.id, workspace_id)
    
    result = await db.execute(
        select(ABIServerModel).where(
            ABIServerModel.id == server_id,
            ABIServerModel.workspace_id == workspace_id,
        )
    )
    row = result.scalar_one_or_none()
    if not row:
        raise HTTPException(status_code=404, detail="ABI server not found")
    
    await db.delete(row)
    await db.commit()
    
    return {"status": "deleted"}
