/**
 * Forge Schedules — types (V3)
 *
 * trigger + body + action. body is one of pipeline / prompt.
 * action is one of none / chat / email / telegram.
 */

export type ScheduleKind = 'period' | 'once' | 'cron' | 'manual';
export type ScheduleRunStatus = 'started' | 'done' | 'failed' | 'cancelled';
export type ScheduleRunTrigger = 'schedule' | 'manual';

export type ScheduleBodyKind = 'pipeline' | 'prompt';
export type ScheduleActionKind = 'none' | 'chat' | 'email' | 'telegram';
export type ScheduleActionStatus = 'pending' | 'done' | 'failed' | 'skipped';

/** Persisted Schedule config. status is NOT here — computed on read. */
export interface Schedule {
  id: string;
  name: string;
  enabled: boolean;

  // Body — what to run when this schedule fires.
  body_kind: ScheduleBodyKind;
  /** Reference depends on body_kind:
   *   pipeline → pipeline name (flows/<name>.yaml)
   *   prompt   → prompt name (prompts/<name>.yaml) */
  body_ref: string;
  /** Input params; shape depends on body_kind. */
  input: Record<string, unknown>;

  /** Extra Forge skills attached to the dispatched body. For body=pipeline
   *  these are forwarded to startPipeline({skills}) → every task gets the
   *  --append-system-prompt block. For body=prompt they're merged with the
   *  prompt yaml's executor.skills and installed before dispatch. */
  skills: string[];

  // Action — what to do with body's output. action_config JSON shape
  // is kind-specific (see help doc 13-schedules.md).
  action_kind: ScheduleActionKind;
  action_config: Record<string, unknown>;
  action_skip_on_empty: boolean;

  // Trigger
  schedule_kind: ScheduleKind;
  schedule_interval_minutes: number;
  schedule_at: string | null;
  schedule_cron: string | null;
  next_run_at: string | null;
  last_run_at: string | null;

  created_at: string;
  updated_at: string;
}

/** UI-facing schedule with computed state fields. */
export type ActiveState = 'idle' | 'running' | 'last_failed' | 'paused';

export interface DecoratedSchedule extends Schedule {
  /** Number of schedule_runs.status='started' for this schedule. */
  inflight_count: number;
  /** Most recent terminal run's status, null if never run. */
  last_status: ScheduleRunStatus | null;
  /** Computed from enabled + inflight + last_status. */
  active_state: ActiveState;
}

export interface ScheduleRun {
  id: string;
  schedule_id: string;
  /** ID of the dispatched body — pipeline_id for body=pipeline,
   *  task_id for body=prompt. */
  target_id: string;
  trigger: ScheduleRunTrigger;
  status: ScheduleRunStatus;
  /** Captured output of the body — fed into action. May be null
   *  while body is still running, or if body produced no output. */
  body_output: string | null;
  action_status: ScheduleActionStatus | null;
  action_error: string | null;
  started_at: string;
  finished_at: string | null;
  error: string | null;
}

export interface CreateScheduleInput {
  name: string;
  body_kind?: ScheduleBodyKind;
  body_ref: string;
  input?: Record<string, unknown>;
  skills?: string[];
  action_kind?: ScheduleActionKind;
  action_config?: Record<string, unknown>;
  action_skip_on_empty?: boolean;
  enabled?: boolean;
  schedule_kind?: ScheduleKind;
  schedule_interval_minutes?: number;
  schedule_at?: string | null;
  schedule_cron?: string | null;
}

export interface UpdateScheduleInput {
  name?: string;
  input?: Record<string, unknown>;
  skills?: string[];
  enabled?: boolean;
  action_kind?: ScheduleActionKind;
  action_config?: Record<string, unknown>;
  action_skip_on_empty?: boolean;
  schedule_kind?: ScheduleKind;
  schedule_interval_minutes?: number;
  schedule_at?: string | null;
  schedule_cron?: string | null;
}
