import { api, withApiBase } from './http';

export type WorkflowNodeType = 'agent' | 'skill' | 'http' | 'transform' | 'branch';

export interface WorkflowNode {
  id: string;
  type: WorkflowNodeType;
  name: string;
  config: Record<string, any>;
  next?: string;
  elseNext?: string;
}

export interface WorkflowGraph {
  entry: string;
  nodes: WorkflowNode[];
  variables?: Record<string, any>;
}

export interface Workflow {
  id: string;
  name: string;
  description: string;
  graph: WorkflowGraph;
  scheduleCron: string;
  scheduleEnabled: boolean;
  enabled: boolean;
  lastRunAt: number;
  runCount: number;
  createdAt: number;
  updatedAt: number;
}

export interface WorkflowRun {
  id: string;
  workflowId: string;
  trigger: 'manual' | 'cron' | 'api';
  status: 'running' | 'success' | 'failed' | 'aborted';
  error: string;
  startedAt: number;
  finishedAt: number;
  durationMs: number;
}

export interface WorkflowRunStep {
  id: string;
  nodeId: string;
  nodeType: string;
  stepIndex: number;
  status: 'running' | 'success' | 'failed' | 'skipped';
  input: any;
  output: any;
  error: string;
  startedAt: number;
  finishedAt: number;
  durationMs: number;
}

export interface WorkflowRunDetail extends WorkflowRun {
  input: any;
  output: any;
  steps: WorkflowRunStep[];
}

export const WorkflowAPI = {
  list: () => api.get<Workflow[]>('/workflows').then((r) => r.data),
  get: (id: string) => api.get<Workflow>(`/workflows/${id}`).then((r) => r.data),
  create: (payload: Partial<Workflow>) => api.post<{ id: string }>('/workflows', payload).then((r) => r.data),
  update: (id: string, payload: Partial<Workflow>) => api.put(`/workflows/${id}`, payload).then((r) => r.data),
  remove: (id: string) => api.delete(`/workflows/${id}`).then((r) => r.data),
  run: (id: string, input?: Record<string, any>) => api.post<{ runId: string }>(`/workflows/${id}/run`, { input }).then((r) => r.data),
  listRuns: (id: string, limit = 30) => api.get<WorkflowRun[]>(`/workflows/${id}/runs`, { params: { limit } }).then((r) => r.data),
  getRun: (runId: string) => api.get<WorkflowRunDetail>(`/workflows/runs/${runId}`).then((r) => r.data)
};

export function streamWorkflowRun(
  workflowId: string,
  input: Record<string, any> | undefined,
  handlers: {
    onReady?: (data: any) => void;
    onStepStart?: (data: any) => void;
    onStepFinish?: (data: any) => void;
    onRunFinish?: (data: any) => void;
    onError?: (msg: string) => void;
  }
): () => void {
  const qs = input ? `?input=${encodeURIComponent(JSON.stringify(input))}` : '';
  const url = withApiBase(`/workflows/${workflowId}/run-stream${qs}`);
  const es = new EventSource(url, { withCredentials: true } as any);
  es.addEventListener('ready', (e: any) => handlers.onReady?.(JSON.parse(e.data)));
  es.addEventListener('step_start', (e: any) => handlers.onStepStart?.(JSON.parse(e.data)));
  es.addEventListener('step_finish', (e: any) => handlers.onStepFinish?.(JSON.parse(e.data)));
  es.addEventListener('run_finish', (e: any) => {
    handlers.onRunFinish?.(JSON.parse(e.data));
    es.close();
  });
  es.addEventListener('error', () => {
    if (es.readyState === EventSource.CLOSED) return;
    handlers.onError?.('stream error');
    es.close();
  });
  return () => es.close();
}

