import {
  ExecutorOperatorResultFrameSchema,
  ExecutorWorkerContinuityFrameSchema,
  PROTOCOL_VERSION,
  WorkerContinuityViewFrameSchema,
  type ExecutorServerFrame,
} from '@platform-modules/chatgpt-orchestrator-protocol';
import type { BackendContinuityView, UiRequest } from './ui-model.js';

export type OperatorResultFrame = Extract<ExecutorServerFrame, { type: 'operator.result' }>;
export type WorkerContinuityFrame = Extract<ExecutorServerFrame, { type: 'worker.continuity' }>;

export type ContinuityControlServerFrame =
  | { kind: 'operator-result'; frame: OperatorResultFrame }
  | { kind: 'worker-continuity'; frame: WorkerContinuityFrame };

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

export function parseBackendContinuityView(value: unknown): BackendContinuityView | null {
  const parsed = WorkerContinuityViewFrameSchema.safeParse(value);
  return parsed.success ? parsed.data : null;
}

export function parseContinuityControlServerFrame(value: unknown): ContinuityControlServerFrame | null {
  if (!isRecord(value)) return null;
  if (value.type === 'operator.result') {
    const parsed = ExecutorOperatorResultFrameSchema.safeParse(value);
    if (!parsed.success) throw new Error('Invalid operator.result frame.');
    return { kind: 'operator-result', frame: parsed.data };
  }
  if (value.type === 'worker.continuity') {
    const parsed = ExecutorWorkerContinuityFrameSchema.safeParse(value);
    if (!parsed.success) throw new Error('Invalid worker.continuity frame.');
    return { kind: 'worker-continuity', frame: parsed.data };
  }
  return null;
}

export function operatorActionFrame(
  executorId: string,
  requestId: string,
  request: Exclude<UiRequest, { action: 'snapshot' }>,
): Record<string, unknown> {
  const workerAction = 'workerId' in request;
  const action = request.action === 'continue-now' || request.action === 'continue-anyway'
    ? 'continue_now'
    : request.action === 'stop'
      ? 'cancel'
      : request.action === 'set-auto-resume'
        ? 'set_auto_resume'
        : request.action === 'set-run-auto-resume'
          ? 'set_run_auto_resume'
          : request.action === 'pause-run'
            ? 'pause_run'
            : request.action === 'resume-run'
              ? 'resume_run'
              : request.action === 'stop-run'
                ? 'cancel_run'
                : 'pause';
  return {
    protocolVersion: PROTOCOL_VERSION,
    type: 'operator.action',
    executorId,
    requestId,
    ...(workerAction ? { workerId: request.workerId } : { runId: request.runId }),
    action,
    ...((request.action === 'set-auto-resume' || request.action === 'set-run-auto-resume') ? { enabled: request.enabled } : {}),
    ...(request.action === 'continue-anyway' ? { overrideBlock: true } : {}),
    idempotencyKey: requestId,
  };
}
