# retoor <retoor@molodetz.nl>

from __future__ import annotations

from ..actions.spec import Action, Param
from .schedule import MAX_LIFETIME_DAYS, MAX_MAX_RUNS, MIN_INTERVAL_SECONDS


def field(
    name: str, description: str, required: bool = False, kind: str = "string"
) -> Param:
    return Param(
        name=name,
        location="body",
        description=description,
        required=required,
        type=kind,
    )


SCHEDULE_FIELDS: tuple[Param, ...] = (
    field(
        "kind",
        "Schedule type: 'once' (run a single time), 'interval' (repeat every N seconds), "
        "or 'cron' (5-field cron expression).",
        required=True,
    ),
    field(
        "run_at",
        "For kind=once: absolute UTC time in ISO 8601, e.g. 2026-06-09T14:30:00.",
    ),
    field(
        "delay_seconds",
        "For kind=once: run this many seconds from now.",
        kind="integer",
    ),
    field(
        "every_seconds",
        f"For kind=interval: number of seconds between runs. Minimum {MIN_INTERVAL_SECONDS}.",
        kind="integer",
    ),
    field(
        "start_at",
        "For kind=interval: optional ISO 8601 UTC time of the first run. "
        "Defaults to one interval from now.",
    ),
    field(
        "cron",
        "For kind=cron: a 5-field cron expression 'minute hour day-of-month month day-of-week'. "
        "Supports *, ranges (1-5), lists (1,3,5) and steps (*/15). Two consecutive fires must be "
        f"at least {MIN_INTERVAL_SECONDS} seconds apart.",
    ),
    field(
        "max_runs",
        "Maximum number of executions; the task disables itself afterwards. A recurring task "
        f"without one gets a default, and the ceiling is {MAX_MAX_RUNS}.",
        kind="integer",
    ),
    field(
        "expires_at",
        "Absolute UTC time in ISO 8601 after which the task stops for good. Defaults to "
        f"{MAX_LIFETIME_DAYS} days after the first run, which is also the maximum.",
    ),
)

TASK_ACTIONS: tuple[Action, ...] = (
    Action(
        name="current_time",
        method="LOCAL",
        path="",
        summary="Get the exact current UTC time, to the second",
        description=(
            "The CURRENT TIME line in the system prompt is rounded to the hour to stay "
            "cache-friendly. Call this tool first whenever you need the precise current time - "
            "in particular before computing any absolute run_at for create_task/update_task from "
            "a relative phrase you cannot express via delay_seconds. For an ordinary relative "
            "delay ('in 40 seconds', 'in 2 hours'), you do not need this: delay_seconds is applied "
            "against the server's own clock at creation time and is always exact regardless."
        ),
        handler="task",
        requires_auth=False,
        params=(),
    ),
    Action(
        name="create_task",
        method="LOCAL",
        path="",
        summary="Queue a prompt to run autonomously on a schedule with full tool access",
        description=(
            "The prompt is executed later by a fresh agent that has every tool available, "
            "running inside the current authenticated session. Two rolling 24-hour quotas apply "
            "per account: how many tasks may be created, and how many task runs may execute. "
            "Every recurring task also stops by itself. While a task run is executing, members "
            "may not schedule further work from inside it; administrators may."
        ),
        handler="task",
        requires_auth=True,
        params=(
            field(
                "prompt",
                "A complete, self-contained instruction the future agent will execute when the "
                "task fires (it has no other context). Write an imperative command, not a "
                "description: e.g. 'Create a post in the fun topic about raccoons with a short "
                "funny text, then verify it appears.'",
                required=True,
            ),
            field("label", "Optional short human-readable label for the task."),
            field(
                "notify",
                "Set true for a REMINDER: when the task fires, the user is sent an in-app "
                "notification and live toast carrying the result, so it reaches them even when "
                "the Devii terminal is closed. Leave false for silent background automation.",
                kind="boolean",
            ),
            *SCHEDULE_FIELDS,
        ),
    ),
    Action(
        name="list_tasks",
        method="LOCAL",
        path="",
        summary="List queued tasks and their schedules and last results",
        handler="task",
        requires_auth=False,
        params=(
            field("enabled_only", "Only return enabled tasks.", kind="boolean"),
            field(
                "status", "Filter by status: pending, running, done, error, disabled."
            ),
        ),
    ),
    Action(
        name="get_task",
        method="LOCAL",
        path="",
        summary="Get a single task including its full last result",
        handler="task",
        requires_auth=False,
        params=(field("uid", "Uid of the task.", required=True),),
    ),
    Action(
        name="update_task",
        method="LOCAL",
        path="",
        summary="Update a task's prompt, label, enabled state, or schedule",
        description=(
            "Provide schedule fields together with kind to reschedule the task. Enabling a task "
            "from inside a running task is refused for members."
        ),
        handler="task",
        requires_auth=True,
        params=(
            field("uid", "Uid of the task.", required=True),
            field("prompt", "New prompt."),
            field("label", "New label."),
            field("enabled", "Enable or disable the task.", kind="boolean"),
            field(
                "notify",
                "Enable or disable the in-app reminder notification when this task fires.",
                kind="boolean",
            ),
            field("kind", "New schedule type when rescheduling."),
            field("run_at", "New absolute run time for kind=once."),
            field("delay_seconds", "New relative delay for kind=once.", kind="integer"),
            field("every_seconds", "New interval for kind=interval.", kind="integer"),
            field("start_at", "New first-run time for kind=interval."),
            field("cron", "New cron expression for kind=cron."),
            field("max_runs", "New maximum number of executions.", kind="integer"),
            field("expires_at", "New absolute UTC expiry in ISO 8601."),
        ),
    ),
    Action(
        name="delete_task",
        method="LOCAL",
        path="",
        summary="Delete a queued task",
        handler="task",
        requires_auth=False,
        params=(field("uid", "Uid of the task.", required=True),),
    ),
    Action(
        name="run_task_now",
        method="LOCAL",
        path="",
        summary="Trigger a task to execute immediately on the next scheduler tick",
        description=(
            "The run still consumes a slot of the account's rolling 24-hour run quota, and is "
            "postponed when that quota is spent."
        ),
        handler="task",
        requires_auth=True,
        params=(field("uid", "Uid of the task.", required=True),),
    ),
)
