import { IgRateLimitError, IgLoginRequiredError, IgAccountNotFoundError, IgPrivateAccountError } from './errors.js';

/** IG's 404 shell for a deleted/renamed account. Distinct from the throttle shell
 *  ("문제가 발생했습니다" / "Something went wrong"), so it's safe to treat as permanent. */
export function isNotFoundPage(bodyText: string): boolean {
  return /페이지를 사용할 수 없습니다|Sorry, this page (?:isn.?t|is not) available/i.test(bodyText);
}

/** IG's private-profile shell (exists, but no posts for a non-follower). Specific phrasing
 *  to avoid matching a public bio that merely mentions "비공개". */
export function isPrivatePage(bodyText: string): boolean {
  return /이 계정은 비공개|비공개 계정입니다|This account is private|This Account is Private/i.test(bodyText);
}

/**
 * Decide why a logged-in timeline scrape produced no posts. Returns the Error to
 * throw, or null if it actually succeeded (timeline matched). Pure — unit-tested.
 */
export function classifyTimelineFailure(s: {
  timelineMatched: number;
  sawHomeRedirect: boolean;
  sawLoginRedirect: boolean;
  loginWall: boolean;
  notFoundPage: boolean;
  privatePage: boolean;
  graphqlSeen: number;
  username: string;
}): Error | null {
  if (s.timelineMatched > 0) return null;
  // Throttle/session signals take priority — never mark a channel dead/private during a block.
  if (s.loginWall || s.sawLoginRedirect) {
    return new IgLoginRequiredError(`@${s.username} 수집 차단 — 로그인 필요 (세션 만료/체크포인트). 다시 로그인해 주세요.`);
  }
  if (s.sawHomeRedirect) {
    return new IgRateLimitError(`@${s.username} IG가 프로필 조회를 일시 차단했어요(레이트리밋). 계속되면 네트워크를 바꾸거나 계정을 잠시 쉬게 해야 할 수 있어요 (재로그인은 도움 안 됨).`);
  }
  if (s.notFoundPage) {
    return new IgAccountNotFoundError(`@${s.username} 계정을 찾을 수 없어요 (삭제되었거나 사용자명이 변경됨) — 수집 대상에서 제외했어요.`);
  }
  if (s.privatePage) {
    return new IgPrivateAccountError(`@${s.username} 비공개 계정이라 게시물을 수집할 수 없어요 — 공개로 전환되면 자동으로 다시 수집해요.`);
  }
  return new Error(`@${s.username} 타임라인 응답을 찾지 못함 (graphql=${s.graphqlSeen}) — IG 포맷 변경 가능.`);
}

/**
 * Diagnostic-only: from the profile page's visible text + reCAPTCHA iframe count,
 * decide whether IG served a soft-block / bot-challenge shell (the state where the
 * timeline GraphQL is withheld but there's no login-wall or 302, so the scrape sees
 * `graphql=1, timelineMatches=0, blocked=false`). Pure so it can be unit-tested;
 * used to LOG why a timeline miss happened, not (yet) to change classification.
 */
export function detectSoftBlock(s: { bodyText: string; recaptchaCount: number }): { hit: boolean; reason: string } {
  const reasons: string[] = [];
  if (s.recaptchaCount > 0) reasons.push('recaptcha');
  if (/로봇이 아닙니다|자동화된 동작|일시적으로 차단|잠시 후 다시 시도|활동이 제한|계정이 제한/i.test(s.bodyText)) reasons.push('ko-restrict');
  if (/please wait a few minutes|try again later|temporarily (?:blocked|restricted)|suspicious activity|we restrict certain activity/i.test(s.bodyText)) reasons.push('en-restrict');
  if (/challenge_required|checkpoint_required/i.test(s.bodyText)) reasons.push('challenge');
  return { hit: reasons.length > 0, reason: reasons.join('+') || 'none' };
}
