"""Pipeline schedule update command implementation."""

import json
from typing import Annotated
from uuid import UUID

import typer

from alloy_runtime_types.dtos.schedule import UpdateScheduleRequest
from cli.commands.flag_utils import validate_uuid
from cli.commands.pipelines.schedules.update_presenter import present_update_result
from cli.infrastructure.command import async_command, authenticated_client


def pipelines_schedules_update_command(
    pipeline_id: str = typer.Argument(
        ...,
        help="Pipeline UUID",
    ),
    schedule_id: str = typer.Argument(
        ...,
        help="Schedule UUID",
    ),
    name: Annotated[
        str | None,
        typer.Option(
            "-n",
            "--name",
            help="New schedule name",
        ),
    ] = None,
    description: Annotated[
        str | None,
        typer.Option(
            "-d",
            "--description",
            help="New schedule description",
        ),
    ] = None,
    input_params: Annotated[
        str | None,
        typer.Option(
            "--input-params",
            "-i",
            help="Input parameters as JSON string",
        ),
    ] = None,
    timeout: Annotated[
        int | None,
        typer.Option(
            "--timeout",
            "-t",
            help="Execution timeout in seconds (1-3600)",
            min=1,
            max=3600,
        ),
    ] = None,
    enable: Annotated[
        bool | None,
        typer.Option(
            "--enable/--disable",
            help="Enable or disable the schedule",
        ),
    ] = None,
    allow_concurrent: Annotated[
        bool | None,
        typer.Option(
            "--allow-concurrent/--no-concurrent",
            help="Allow or disallow concurrent executions",
        ),
    ] = None,
    max_failures: Annotated[
        int | None,
        typer.Option(
            "--max-failures",
            help="Auto-disable after this many consecutive failures (0 = never)",
            min=0,
        ),
    ] = None,
) -> None:
    """Update a pipeline schedule.

    Examples:
        alloy pipelines schedules update 123e4567... 456e7890... -n 'New Name'
        alloy pipelines schedules update 123e4567... 456e7890... --disable
        alloy pipelines schedules update 123e4567... 456e7890... --timeout 600
    """
    p_uuid = validate_uuid(pipeline_id, "pipeline")
    s_uuid = validate_uuid(schedule_id, "schedule")

    params = None
    if input_params:
        try:
            params = json.loads(input_params)
        except json.JSONDecodeError as e:
            raise typer.BadParameter(f"Invalid JSON for --input-params: {e}")

    # Check at least one update flag was provided
    if all(
        v is None
        for v in [
            name,
            description,
            input_params,
            timeout,
            enable,
            allow_concurrent,
            max_failures,
        ]
    ):
        raise typer.BadParameter(
            "At least one update flag required: --name, --description, --input-params, "
            "--timeout, --enable/--disable, --allow-concurrent/--no-concurrent, --max-failures"
        )

    request = UpdateScheduleRequest(
        name=name,
        description=description,
        input_parameters=params,
        timeout_seconds=timeout,
        is_enabled=enable,
        allow_concurrent=allow_concurrent,
        max_consecutive_failures=max_failures,
    )

    _execute_update(pipeline_id=p_uuid, schedule_id=s_uuid, request=request)


@async_command
async def _execute_update(
    pipeline_id: UUID, schedule_id: UUID, request: UpdateScheduleRequest
) -> None:
    """Execute update schedule operation."""
    async with authenticated_client() as (_config, client):
        response = await client.update_pipeline_schedule(
            pipeline_id, schedule_id, request
        )

    present_update_result(response)
