"""Env management endpoints for creating ENV_INSPECT and ENV_UPDATE tasks."""

import uuid

from fastapi import APIRouter, HTTPException, status
from sqlalchemy import select

from app.db import AsyncSessionDep
from app.models.agent import Agent
from app.models.task import Task, TaskStatus
from app.models.tenant import Tenant
from app.schemas.env import EnvInspectRequest, EnvUpdateRequest
from app.schemas.task import TaskResponse

router = APIRouter(prefix="/agents/{agent_id}/env", tags=["Env Management"])


# --- Helper functions ---


async def get_tenant_by_id(db: AsyncSessionDep, tenant_id: uuid.UUID) -> Tenant | None:
    """Retrieve a tenant by ID."""
    result = await db.execute(select(Tenant).where(Tenant.id == tenant_id))
    return result.scalar_one_or_none()


async def get_agent_by_id(db: AsyncSessionDep, agent_id: uuid.UUID) -> Agent | None:
    """Retrieve an agent by ID."""
    result = await db.execute(select(Agent).where(Agent.id == agent_id))
    return result.scalar_one_or_none()


# --- Route handlers ---


@router.post(
    "/inspect",
    response_model=TaskResponse,
    status_code=status.HTTP_201_CREATED,
)
async def inspect_env(
    agent_id: uuid.UUID,
    request: EnvInspectRequest,
    db: AsyncSessionDep,
) -> Task:
    """
    Create an ENV_INSPECT task to read env file contents.

    The SysAdmin Agent will execute this task and return the env file
    key-value pairs in the task result.

    ## Request Body
    - **tenant_id**: UUID of the tenant
    - **path**: Path to the env file (e.g., `/opt/letsbe/env/chatwoot.env`)
    - **keys**: Optional list of specific keys to inspect (returns all if omitted)

    ## Response
    Returns the created Task with type="ENV_INSPECT" and status="pending".
    """
    # Validate tenant exists
    tenant = await get_tenant_by_id(db, request.tenant_id)
    if tenant is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Tenant {request.tenant_id} not found",
        )

    # Validate agent exists
    agent = await get_agent_by_id(db, agent_id)
    if agent is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Agent {agent_id} not found",
        )

    # Build payload
    payload: dict = {"path": request.path}
    if request.keys is not None:
        payload["keys"] = request.keys

    # Create the task
    task = Task(
        tenant_id=request.tenant_id,
        agent_id=agent_id,
        type="ENV_INSPECT",
        payload=payload,
        status=TaskStatus.PENDING.value,
    )

    db.add(task)
    await db.commit()
    await db.refresh(task)

    return task


@router.post(
    "/update",
    response_model=TaskResponse,
    status_code=status.HTTP_201_CREATED,
)
async def update_env(
    agent_id: uuid.UUID,
    request: EnvUpdateRequest,
    db: AsyncSessionDep,
) -> Task:
    """
    Create an ENV_UPDATE task to modify env file contents.

    The SysAdmin Agent will execute this task to update or remove
    key-value pairs in the specified env file.

    ## Request Body
    - **tenant_id**: UUID of the tenant
    - **path**: Path to the env file (e.g., `/opt/letsbe/env/chatwoot.env`)
    - **updates**: Optional dict of key-value pairs to set or update
    - **remove_keys**: Optional list of keys to remove from the env file

    ## Response
    Returns the created Task with type="ENV_UPDATE" and status="pending".
    """
    # Validate tenant exists
    tenant = await get_tenant_by_id(db, request.tenant_id)
    if tenant is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Tenant {request.tenant_id} not found",
        )

    # Validate agent exists
    agent = await get_agent_by_id(db, agent_id)
    if agent is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Agent {agent_id} not found",
        )

    # Build payload
    payload: dict = {"path": request.path}
    if request.updates is not None:
        payload["updates"] = request.updates
    if request.remove_keys is not None:
        payload["remove_keys"] = request.remove_keys

    # Create the task
    task = Task(
        tenant_id=request.tenant_id,
        agent_id=agent_id,
        type="ENV_UPDATE",
        payload=payload,
        status=TaskStatus.PENDING.value,
    )

    db.add(task)
    await db.commit()
    await db.refresh(task)

    return task
