type PendingTask = {
  resolve: (payload: any) => void;
  reject: (error: Error) => void;
  timeout: NodeJS.Timeout;
};

const pendingTasks = new Map<string, PendingTask>();
const recentPayloads = new Map<string, any>();
const RECENT_PAYLOAD_TTL_MS = 15 * 60 * 1000;

function cleanupRecent(taskId: string): void {
  setTimeout(() => {
    recentPayloads.delete(taskId);
  }, RECENT_PAYLOAD_TTL_MS).unref();
}

export function registerKieTask(taskId: string, timeoutMs: number): Promise<any> {
  const existing = recentPayloads.get(taskId);
  if (existing) {
    return Promise.resolve(existing);
  }

  return new Promise((resolve, reject) => {
    const timeout = setTimeout(() => {
      pendingTasks.delete(taskId);
      reject(new Error(`Kie callback timeout for task ${taskId}`));
    }, timeoutMs);

    pendingTasks.set(taskId, { resolve, reject, timeout });
  });
}

export function resolveKieTask(taskId: string, payload: any): void {
  recentPayloads.set(taskId, payload);
  cleanupRecent(taskId);

  const pending = pendingTasks.get(taskId);
  if (!pending) return;

  clearTimeout(pending.timeout);
  pendingTasks.delete(taskId);
  pending.resolve(payload);
}

export function rejectKieTask(taskId: string, error: Error): void {
  const pending = pendingTasks.get(taskId);
  if (!pending) return;

  clearTimeout(pending.timeout);
  pendingTasks.delete(taskId);
  pending.reject(error);
}

export function extractKieTaskId(payload: any): string | null {
  if (!payload || typeof payload !== 'object') return null;

  return (
    payload.taskId ||
    payload.task_id ||
    payload.id ||
    payload.data?.taskId ||
    payload.data?.task_id ||
    payload.data?.id ||
    null
  );
}

