"""Workspace instance API endpoints."""

import uuid

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

from src.auth.dependencies import get_current_user_id, get_db_session
from src.models import GitRepository
from src.models import ToolInstance
from src.models import Workspace
from src.schemas.tool import CreateInstanceRequest, CreateWorkspaceInstanceRequest
from src.services.tool.instance_service import create_tool_instance

router = APIRouter(prefix="/workspaces/{workspace_id}/instances")


async def _get_workspace(
    session: AsyncSession,
    workspace_id: uuid.UUID,
    user_id: uuid.UUID,
) -> Workspace:
    result = await session.execute(
        select(Workspace).where(
            Workspace.id == workspace_id,
            Workspace.user_id == user_id,
        )
    )
    workspace = result.scalar_one_or_none()
    if not workspace:
        raise HTTPException(status_code=404, detail="Workspace not found")
    return workspace


@router.post(
    "/",
    summary="Create instance from workspace",
    description="Create a new tool instance mounted on this workspace.",
    status_code=status.HTTP_201_CREATED,
)
async def create_workspace_instance(
    workspace_id: uuid.UUID,
    data: CreateWorkspaceInstanceRequest,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> dict:
    """Create a tool instance directly on a workspace."""
    workspace = await _get_workspace(session, workspace_id, user_id)

    repo = await session.get(GitRepository, workspace.repo_id)
    if repo is None:
        raise HTTPException(status_code=404, detail="Repository not found")
    if repo.project_id is None:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Repository is not associated with a project",
        )

    request = CreateInstanceRequest(
        tool_type_id=data.tool_type_id,
        display_name=data.display_name,
        workspace_id=str(workspace.id),
        config_profile_id=data.config_profile_id,
        ssh_key_ids=data.ssh_key_ids,
    )

    try:
        instance = await create_tool_instance(
            session, user_id, repo.project_id, repo.id, request
        )
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc))
    except RuntimeError as exc:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc)
        )

    return {
        "id": str(instance.id),
        "name": instance.name,
        "display_name": instance.display_name,
        "tool_type_id": str(instance.tool_type_id),
        "status": instance.status,
        "workspace_id": str(instance.workspace_id) if instance.workspace_id else None,
        "selected_config_profile_id": str(instance.selected_config_profile_id)
        if instance.selected_config_profile_id
        else None,
        "created_at": instance.created_at.isoformat(),
    }


@router.get("/")
async def list_workspace_instances(
    workspace_id: uuid.UUID,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> list[dict]:
    """List tool instances using this workspace."""
    await _get_workspace(session, workspace_id, user_id)
    result = await session.execute(
        select(ToolInstance)
        .where(ToolInstance.workspace_id == workspace_id)
        .order_by(ToolInstance.created_at.desc())
    )
    instances = result.scalars().all()

    return [
        {
            "id": str(i.id),
            "name": i.name,
            "display_name": i.display_name,
            "status": i.status,
            "tool_type_id": str(i.tool_type_id),
            "url": i.url,
            "port": i.port,
            "created_at": i.created_at.isoformat() if i.created_at else None,
        }
        for i in instances
    ]
