export interface AutomationTrigger {
  /**
   * Trigger kind. Known values are the schedule aliases "cron" / "schedule"
   * (time-based) and "event" (webhook/event-driven). Kept as `string` rather
   * than a closed union on purpose: the backend emits more than one
   * scheduled-trigger alias and may introduce new kinds, so UI code branches
   * on `type === "event"` and treats every other value as a schedule.
   */
  type: string;
  /** Cron expression (schedule triggers only). */
  schedule?: string;
  /** Human-readable schedule description (schedule triggers only). */
  schedule_human?: string;
  /** IANA timezone name (schedule triggers only). */
  timezone?: string;
  /** Event source, e.g. "github" (event triggers only). */
  source?: string;
  /** Event key pattern(s) to match, e.g. "pull_request.opened" or ["push", "release.*"]. */
  on?: string | string[];
  /** JMESPath filter expression evaluated against the raw webhook payload. */
  filter?: string;
}

export interface Automation {
  id: string;
  name: string;
  trigger: AutomationTrigger;
  enabled: boolean;
  repository?: string;
  /** LLM/model profile name used for automation runs. */
  model?: string | null;
  /**
   * Maximum run time in seconds. `null`/omitted uses the server default
   * (600s, 10 min); the deployment reports the maximum it accepts.
   */
  timeout?: number | null;

  created_at: string;
  updated_at: string;
  prompt: string | null;
  branch?: string;
  plugins?: string[];
  notification?: string;
  timezone?: string;
  last_triggered_at?: string | null;
  /**
   * Service-owned preset state, returned verbatim. The GUI reads only the
   * `template` provenance block inside it ({id, version, config}, written at
   * setup time), and only through the guarded helper in
   * `#/utils/automation-catalog`.
   */
  preset_metadata?: Record<string, unknown> | null;
}

export type AutomationSpec = Omit<
  Automation,
  "id" | "created_at" | "updated_at" | "last_triggered_at" | "preset_metadata"
>;

/** The envelope constants come from the interface manifest's import/export spec. */
export interface AutomationExportFile {
  version: number;
  kind: string;
  spec: AutomationSpec;
}

export interface AutomationsResponse {
  automations: Automation[];
  total: number;
}

/** Mirrors `RunStatus` in the automation service's OpenAPI schema. */
export enum AutomationRunStatus {
  PENDING = "PENDING",
  RUNNING = "RUNNING",
  COMPLETED = "COMPLETED",
  FAILED = "FAILED",
  CANCELLED = "CANCELLED",
  SKIPPED = "SKIPPED",
}

export interface AutomationRun {
  id: string;
  status: AutomationRunStatus;
  conversation_id: string | null;
  /**
   * ID of the bash command that ran the automation inside the agent-server
   * sandbox. Used to fetch run logs from
   * `/api/bash/bash_events/{bash_command_id}` and the matching
   * `BashOutput` events. Null when the run failed before a command was
   * dispatched (e.g. sandbox provisioning errors).
   */
  bash_command_id: string | null;
  error_detail: string | null;
  /**
   * Accumulated LLM cost of the run in USD, reported by the SDK in the
   * completion callback. `null` means unknown — the run predates cost
   * tracking, or ended without a callback (cancelled, watchdog timeout).
   * Absent entirely when the automation service is older than the release
   * that added the field, hence optional.
   */
  cost?: number | null;
  /**
   * Machine-readable code for the run's current or last-known phase (e.g.
   * "sandbox_provisioning"). `null` means nothing has reported one; absent
   * entirely against an automation service that predates phase reporting.
   * Code and label are one value, always written together.
   */
  phase_code?: string | null;
  /**
   * Author-supplied description of the phase (at most 200 characters, no
   * control or separator characters, emoji and non-Latin text allowed).
   * Data, not translatable interface copy.
   */
  phase_label?: string | null;
  /** UTC datetime the phase was last written. Same nullability as `phase_code`. */
  phase_updated_at?: string | null;
  started_at: string;
  completed_at: string | null;
}

export interface AutomationRunsResponse {
  runs: AutomationRun[];
  total: number;
  /**
   * Lifetime run counts by status, unaffected by pagination. Sparse — a
   * status with no runs has no key, so when the field is present a missing
   * key means zero. Absent entirely when the automation service is older
   * than the release that added it.
   */
  status_counts?: Partial<Record<AutomationRunStatus, number>>;
}

export type ActivityLogExportFormat = "json" | "csv";

/** Client-built Activity Log export row (from list runs + automation detail). */
export interface AutomationRunExportRow {
  run_id: string;
  automation_id: string;
  automation_name: string;
  trigger: AutomationTrigger | Record<string, unknown>;
  start_time: string | null;
  end_time: string | null;
  duration_seconds: number | null;
  status: AutomationRunStatus;
  conversation_id: string | null;
  conversation_url: string | null;
  error: string | null;
  /**
   * Accumulated LLM cost in USD, or null when unknown. Unlike
   * `AutomationRun["cost"]` this is always present: the row normalizes a
   * missing field to null so every exported record has the same shape.
   */
  cost: number | null;
  /**
   * The raw `phase_code`, like `status`, falling back to `phase_label` for a
   * phase reported without a code. Null only when the run has no phase.
   */
  phase: string | null;
}
