import { DBOS } from "@dbos-inc/dbos-sdk";
import {
  DbosSdkRuntime,
  type DbosNativeStatus,
  type DbosSdkSurface,
  type DbosWorkflowRegistry,
} from "./dbos-bridge.js";

/** Bind the structural Lane C bridge to the pinned DBOS TypeScript SDK. */
export function createNativeDbosRuntime(registry: DbosWorkflowRegistry): DbosSdkRuntime {
  const surface: DbosSdkSurface = {
    startWorkflow: (target, params) => async (input) => {
      const handle = await DBOS.startWorkflow(target, {
        workflowID: params.workflowID,
        workflowAttributes: { ...params.workflowAttributes },
      })(input);
      return {
        workflowID: () => handle.workflowID,
        getStatus: async () => {
          const status = await handle.getStatus();
          return status ? normalizeStatus(status) : null;
        },
      };
    },
    getWorkflowStatus: async (workflowId) => {
      const status = await DBOS.getWorkflowStatus(workflowId);
      return status ? normalizeStatus(status) : null;
    },
    cancelWorkflow: async (workflowId, options) => {
      await DBOS.cancelWorkflow(workflowId, options);
    },
  };
  return new DbosSdkRuntime(surface, registry);
}

interface NativeWorkflowStatusLike {
  readonly workflowID: string;
  readonly workflowName: string;
  readonly status: string;
  readonly createdAt: number;
  readonly updatedAt?: number;
  readonly output?: unknown;
  readonly error?: unknown;
}

function normalizeStatus(status: NativeWorkflowStatusLike) {
  return {
    workflowID: status.workflowID,
    workflowName: status.workflowName,
    status: normalizeNativeStatus(status.status),
    createdAt: new Date(status.createdAt).toISOString(),
    ...(status.updatedAt === undefined
      ? {}
      : { updatedAt: new Date(status.updatedAt).toISOString() }),
    ...(status.output === undefined ? {} : { output: status.output }),
    ...(status.error === undefined ? {} : { error: status.error }),
  };
}

function normalizeNativeStatus(status: string): DbosNativeStatus {
  switch (status) {
    case "ENQUEUED":
    case "DELAYED":
    case "PENDING":
    case "SUCCESS":
    case "ERROR":
    case "CANCELLED":
    case "MAX_RECOVERY_ATTEMPTS_EXCEEDED":
      return status;
    default:
      throw new Error(`Unsupported DBOS workflow status: ${status}`);
  }
}
