const accountExecutionTails = new Map<string, Promise<void>>();

function normalizeAccountId(accountId: string) {
  return String(accountId ?? "").trim() || "__unknown_1688_account__";
}

export function isSearchAccountExecutionLocked(accountId: string) {
  return accountExecutionTails.has(normalizeAccountId(accountId));
}

export async function withSearchAccountExecutionLock<T>(
  accountId: string,
  fn: () => Promise<T>,
): Promise<T> {
  const key = normalizeAccountId(accountId);
  const previousTail = accountExecutionTails.get(key);
  let releaseCurrent!: () => void;
  const currentLock = new Promise<void>((resolve) => {
    releaseCurrent = resolve;
  });
  const waitForPrevious = previousTail?.catch(() => {}) ?? null;
  const nextTail = (waitForPrevious ?? Promise.resolve()).then(() => currentLock);
  accountExecutionTails.set(key, nextTail);

  if (waitForPrevious) {
    await waitForPrevious;
  }

  try {
    return await fn();
  } finally {
    releaseCurrent();
    if (accountExecutionTails.get(key) === nextTail) {
      accountExecutionTails.delete(key);
    }
  }
}
