/** 계정 간의 지연 시간(ms)을 무작위로 설정하여, 사람이 활동하는 것처럼 보이게 하고 인스타그램의 속도 제한을 피합니다. */
export interface CollectPacing {
  minMs: number;
  maxMs: number;
}

/** 
 * '가벼운 새로고침(Light-refresh)' 계정 간의 기본 간격입니다. 
 * 처리량을 절반으로 줄여 경쟁 서비스(ChannelFinder)와 맞췄습니다. 
 * 실제 사용자 계정이 약 30분당 50회 속도로 수집하다가 차단된 경험을 바탕으로 조정했습니다.
 * 계정당 스크래핑 시간은 약 20초이므로, 40~60초의 간격을 두면 계정당 총 ~70초가 소요됩니다.
 * (과거 8~20초 간격일 때는 계정당 ~35초 소요, 경쟁사보다 2배 빠름. 간격을 넓힐수록 계정 차단 위험이 현저히 낮아집니다.) 
 */
export const LIGHT_PACING : CollectPacing = { minMs: 40000, maxMs: 60000 };

/** 각 계정 수집 후 호출되는 진행 상태 콜백: (완료된 수, 전체 수) */
export type CollectProgress = (done: number, total: number) => void;

const sleep = (ms: number): Promise => new Promise((r) => setTimeout(r, ms));
const jitter = (p: CollectPacing): number => Math.floor(p.minMs + Math.random() * (p.maxMs - p.minMs));

/** 
 * `signal`이 중간에 취소(abort)되면 즉시 종료되는 sleep(ms) 함수입니다. 
 * 이를 통해 '중지(Stop)' 버튼을 누르면 다음 계정까지 40~60초를 기다리지 않고 즉시 멈출 수 있습니다. 
 */
export async function abortableSleep(ms: number, signal?: AbortSignal): Promise {
  if (!signal) return sleep(ms);
  if (signal.aborted) return Promise.resolve();
  return new Promise((resolve) => {
    const onAbort = (): void => { clearTimeout(t); resolve(); };
    const t = setTimeout(() => { signal.removeEventListener('abort', onAbort); resolve(); }, ms);
    signal.addEventListener('abort', onAbort, { once : true });
  });
}

/** 
 * 연속된 속도 제한(429/302 에러) 발생 시 수집을 중단하는 기준입니다. 
 * 활성 상태인 429/302 에러를 계속 먹이면 계정 제재(Flag)가 심해지기 때문입니다. 
 * 일일 가벼운 패스(runDailyLight)와 수동/다중 수집(collectMany) 모두에서 공유됩니다. 
 */
export const RATE_LIMIT_ABORT = 4;

/** 
 * 모든 종류의 연속 실패(소프트 블록/형식 오류/계정 정지 등) 발생 시 수집을 중단하는 기준입니다. 
 * 소프트 스로틀(인스타그램이 빈 껍데기 화면을 주는 경우)은 IgRateLimitError가 아닌 일반 에러로 나타나서 
 * RATE_LIMIT_ABORT가 작동하지 않아 500개 계정을 다 돌며 계정 상태를 망가뜨릴 수 있습니다. 
 * 이 안전장치는 에러 원인과 상관없이 중단시킵니다. RATE_LIMIT_ABORT보다 크게 설정하여, 
 * 가끔 있는 비활성 계정 때문에 정상적인 수집이 멈추지 않게 하되, N번 연속 실패하면 시스템에 문제가 있다고 판단합니다. 
 */
export const FAIL_ABORT = 6;