import {
  getInstance as getApiClientInstance,
  getSunoSessionId,
} from '@/lib/apiClient';

const extendSessionRetryTimes = 1;
let callLockPromise: Promise<void> | null = null;
let resolveCallLock: (() => void) | null = null;

const acquireLock = async (): Promise<void> => {
  if (callLockPromise) {
    await callLockPromise;
  }

  callLockPromise = new Promise<void>((resolve) => {
    resolveCallLock = resolve;
  });
};

const releaseLock = (): void => {
  if (resolveCallLock) {
    resolveCallLock();
    callLockPromise = null;
    resolveCallLock = null;
  }
};

export const extendAnalyticsSessionId = async (
  user_id: string | null | undefined,
  seed: string,
  start: number,
  retries: number = extendSessionRetryTimes
): Promise<string | null | undefined> => {
  try {
    await acquireLock();
    const sunoSessionId = getSunoSessionId();
    if (sunoSessionId) {
      return sunoSessionId;
    }
    const { data } = await getApiClientInstance().GET(
      '/api/user/get_user_session_id/',
      {}
    );
    if (!data || !data.session_id) {
      throw new Error(`request failed`);
    }
    return data.session_id;
  } catch (error) {
    if (retries > 0) {
      // wait for delay and retry
      const delay = Math.floor(Math.random() * (2000 - 1000 + 1)) + 1000; // random delay between 1 and 2 seconds
      await new Promise((resolve) => setTimeout(resolve, delay));
      return extendAnalyticsSessionId(user_id, seed, start, retries - 1);
    } else {
      // No retries left, throw the error
      console.log('Error in extending analytics session id', error);
      return null;
    }
  } finally {
    releaseLock();
  }
};
