"""Schedule commands for manta-client CLI."""

from __future__ import annotations

import asyncio
from typing import Any

import typer

from manta_client.api.agent.schedule import get_schedule_api
from manta_client.api.client import APIError
from manta_client.exitcodes import exit_code_for_api_error
from manta_client.output import (
    console,
    is_quiet,
    print_error,
    print_json,
    print_success,
    print_table,
)

app = typer.Typer(help="Schedule management")


@app.command("list")
def list_schedules(
    limit: int = typer.Option(20, "--limit", "-l", help="Max results"),
    json_output: bool = typer.Option(False, "--json", "-j", help="Output as JSON"),
) -> None:
    """List schedules."""

    async def _list():
        api = get_schedule_api()
        return await api.list_schedules(limit=limit)

    try:
        result = asyncio.run(_list())
    except APIError as e:
        print_error(e.message)
        raise typer.Exit(exit_code_for_api_error(e.code)) from None

    items = result.get("items", [])
    total = result.get("total", 0)

    if json_output:
        print_json(result)
        return

    if not items:
        if not is_quiet():
            console.print("[dim]No schedules found.[/dim]")
        return

    if is_quiet():
        for item in items:
            print(item.get("id", ""))
        return

    columns = [
        ("id", "ID"),
        ("name", "Name"),
        ("agent", "Agent"),
        ("cron_expr", "Cron"),
        ("status", "Status"),
    ]
    print_table(items, columns=columns, title=f"Schedules ({total})")


@app.command("create")
def create_schedule(
    name: str = typer.Option(..., "--name", "-n", help="Schedule name"),
    agent: str = typer.Option(..., "--agent", "-a", help="Agent name"),
    cron_expr: str = typer.Option(..., "--cron", help="Cron expression (5-field)"),
    prompt: str = typer.Option(None, "--prompt", "-p", help="Default prompt"),
    model: str = typer.Option(
        None,
        "--model",
        "-M",
        help="LLM model (e.g., claude-sonnet-4-5, opus)",
    ),
    skill: list[str] = typer.Option(  # noqa: B008
        None,
        "--skill",
        "-s",
        help="Skill slug for prompt injection (repeatable)",
    ),
    json_output: bool = typer.Option(False, "--json", "-j", help="Output as JSON"),
) -> None:
    """Create a new schedule."""
    data: dict[str, Any] = {"name": name, "agent": agent, "cron_expr": cron_expr}
    if prompt:
        data["prompt"] = prompt
    if model:
        data["model"] = model
    if skill:
        data["skill_slugs"] = skill

    async def _create():
        api = get_schedule_api()
        return await api.create_schedule(data)

    try:
        result = asyncio.run(_create())
    except APIError as e:
        print_error(e.message)
        raise typer.Exit(exit_code_for_api_error(e.code)) from None

    if json_output:
        print_json(result)
    elif is_quiet():
        print(result.get("id", ""))
    else:
        print_success(f"Schedule created: {result.get('name')} (ID: {result.get('id')})")


@app.command("update")
def update_schedule(
    pk: int = typer.Argument(..., help="Schedule ID"),
    cron_expr: str = typer.Option(None, "--cron", help="Cron expression (5-field)"),
    prompt: str = typer.Option(None, "--prompt", "-p", help="Prompt"),
    model: str = typer.Option(None, "--model", "-M", help="LLM model"),
    status: str = typer.Option(None, "--status", help="Status (enabled/disabled)"),
    skill: list[str] = typer.Option(  # noqa: B008
        None, "--skill", "-s", help="Skill slug (repeatable, replaces all)"
    ),
    json_output: bool = typer.Option(False, "--json", "-j", help="Output as JSON"),
) -> None:
    """Update an existing schedule."""
    data: dict[str, Any] = {}
    if cron_expr is not None:
        data["cron_expr"] = cron_expr
    if prompt is not None:
        data["prompt"] = prompt
    if model is not None:
        data["model"] = model
    if status is not None:
        data["status"] = status
    if skill is not None:
        data["skill_slugs"] = skill

    if not data:
        print_error("No fields to update. Use --cron, --prompt, --model, --status, or --skill.")
        raise typer.Exit(1)

    async def _update():
        api = get_schedule_api()
        return await api.update_schedule(pk, data)

    try:
        result = asyncio.run(_update())
    except APIError as e:
        print_error(e.message)
        raise typer.Exit(exit_code_for_api_error(e.code)) from None

    if json_output:
        print_json(result)
    elif is_quiet():
        print(result.get("id", ""))
    else:
        print_success(f"Schedule {pk} updated.")


@app.command("delete")
def delete_schedule(
    pk: int = typer.Argument(..., help="Schedule ID"),
) -> None:
    """Delete a schedule."""

    async def _delete():
        api = get_schedule_api()
        return await api.delete_schedule(pk)

    try:
        asyncio.run(_delete())
        if is_quiet():
            print("deleted")
        else:
            print_success(f"Schedule {pk} deleted.")
    except APIError as e:
        print_error(e.message)
        raise typer.Exit(exit_code_for_api_error(e.code)) from None
