import type { ActionDefinition } from "../../core/types.ts";

import { s } from "../../core/json-schema.ts";
import { defineProviderAction } from "../../core/provider-definition.ts";

const service = "ffhub";

const taskStatusSchema = s.stringEnum("FFHub task status.", ["pending", "running", "completed", "failed"]);
const rawMetadataSchema = s.nullable(
  s.record(s.unknown("One raw ffprobe metadata value returned by FFHub."), {
    description: "Raw ffprobe metadata object returned by FFHub when requested.",
  }),
);
const outputFileSchema = s.requiredObject("Single FFHub output file.", {
  filename: s.string("Output file name."),
  url: s.string("Output file URL."),
  size: s.nullable(s.integer("Output file size in bytes when available.")),
  metadata: rawMetadataSchema,
});
const taskSchema = s.requiredObject("Normalized FFHub task.", {
  taskId: s.string("FFHub task ID."),
  userId: s.nullable(s.string("FFHub customer identifier when returned.")),
  status: taskStatusSchema,
  progress: s.nullable(s.integer("Task progress percentage when returned.")),
  error: s.nullable(s.string("Task error message when the task failed.")),
  elapsed: s.nullable(s.string("Worker execution time in seconds when returned.")),
  totalElapsed: s.nullable(s.string("Total elapsed time from creation to completion in seconds when returned.")),
  createdAt: s.nullable(s.string("Task creation timestamp.")),
  finishedAt: s.nullable(s.string("Task completion timestamp, or null when pending.")),
  outputs: s.array("Output files generated by the task.", outputFileSchema),
});

export const ffhubActions: ActionDefinition[] = [
  defineProviderAction(service, {
    name: "create_ffmpeg_task",
    description:
      "Create a new FFHub FFmpeg transcoding task from a full FFmpeg command or argument-only command string.",
    followUpActions: ["ffhub.get_ffmpeg_task"],
    inputSchema: s.object(
      "Input parameters for creating an FFHub FFmpeg task.",
      {
        command: s.string(
          "Full FFmpeg command or argument-only command string accepted by FFHub, including remote input URLs and output file names.",
          { minLength: 1 },
        ),
        webhook: s.url("Optional callback URL that receives the same payload as get_ffmpeg_task."),
        withMetadata: s.boolean("Whether FFHub should collect ffprobe metadata for generated output files."),
      },
      { required: ["command"], optional: ["webhook", "withMetadata"] },
    ),
    outputSchema: s.requiredObject("Identifier for the created FFHub task.", {
      taskId: s.string("Created FFHub task ID."),
    }),
  }),
  defineProviderAction(service, {
    name: "get_ffmpeg_task",
    description: "Get the current status, timing, error, and output files for one FFHub FFmpeg task.",
    inputSchema: s.requiredObject("Identifier of the FFHub task to retrieve.", {
      taskId: s.string("FFHub task ID to retrieve.", { minLength: 1 }),
    }),
    outputSchema: s.requiredObject("Single FFHub task detail.", {
      task: taskSchema,
    }),
  }),
  defineProviderAction(service, {
    name: "list_ffmpeg_tasks",
    description: "List FFHub FFmpeg tasks with optional customer, status, limit, and offset filters.",
    inputSchema: s.object(
      "Filters for listing FFHub FFmpeg tasks.",
      {
        userId: s.string("Optional FFHub customer identifier.", { minLength: 1 }),
        status: taskStatusSchema,
        limit: s.integer("Maximum number of tasks to return, from 1 to 100.", {
          minimum: 1,
          maximum: 100,
        }),
        offset: s.integer("Number of tasks to skip before reading the current page.", { minimum: 0 }),
      },
      { optional: ["userId", "status", "limit", "offset"] },
    ),
    outputSchema: s.requiredObject("Paginated FFHub task list.", {
      tasks: s.array("Normalized FFHub tasks.", taskSchema),
      total: s.integer("Total number of matching FFHub tasks.", { minimum: 0 }),
    }),
  }),
];

export type FfhubActionName = "create_ffmpeg_task" | "get_ffmpeg_task" | "list_ffmpeg_tasks";
