"""Pipeline approval checkpoint decide command implementation."""

import json
from typing import Any, Optional
from uuid import UUID

import typer

from cli.commands.flag_utils import validate_uuid
from cli.commands.pipelines.approvals.presenter import present_approval_checkpoint
from cli.infrastructure.command import async_command, authenticated_client


def pipelines_approvals_decide_command(
    execution_id: str = typer.Argument(
        ...,
        help="Pipeline execution UUID",
    ),
    approval_key: str = typer.Argument(
        ...,
        help="Approval checkpoint key",
    ),
    approve: bool = typer.Option(
        ...,
        "--approve/--reject",
        help="Approve or reject the checkpoint",
    ),
    data: Optional[str] = typer.Option(
        None,
        "-d",
        "--data",
        help='Decision data as JSON string (e.g. \'{"reason": "looks good"}\')',
    ),
) -> None:
    """Submit a decision on an approval checkpoint.

    Examples:
        alloy pipelines approvals decide 123e4567... pe:123:approval:review --approve
        alloy pipelines approvals decide 123e4567... pe:123:approval:review --reject
        alloy pipelines approvals decide 123e4567... pe:123:approval:review --approve -d '{"reason": "LGTM"}'
    """
    e_uuid = validate_uuid(execution_id, "execution")

    decision_data: dict[str, Any] | None = None
    if data:
        try:
            decision_data = json.loads(data)
        except json.JSONDecodeError as e:
            raise typer.BadParameter(f"Invalid JSON for --data: {e}")
        if not isinstance(decision_data, dict):
            raise typer.BadParameter("--data must be a JSON object")

    _execute_decide(
        execution_id=e_uuid,
        approval_key=approval_key,
        approved=approve,
        decision_data=decision_data,
    )


@async_command
async def _execute_decide(
    execution_id: UUID,
    approval_key: str,
    approved: bool,
    decision_data: dict[str, Any] | None,
) -> None:
    """Execute decide approval checkpoint operation."""
    async with authenticated_client() as (_config, client):
        checkpoint = await client.decide_approval(
            execution_id,
            approval_key,
            approved=approved,
            decision_data=decision_data,
        )

    present_approval_checkpoint(checkpoint)
