/**
 * inhouse(자체 스크래퍼 엔진) 어댑터 타입.
 *
 * 엔진(scraper-engine)의 HTTP API(`POST /api/certify`, `POST /api/treat`)를 호출해
 * CODEF/쿠콘/옥토버와 동일한 TreatScraper 계약으로 정규화한다.
 * 2-way 세션(엔진 sessionId)은 CODEF jti 자리에 base64(JSON)로 왕복 — 클라 계약 무변경.
 */

/** 엔진 표준 응답 envelope. */
export interface InhouseEnvelope<R = unknown> {
  ok: boolean;
  code: string; // INH-XXXX
  category: string; // TreatErrorCategory 문자열
  message: string;
  retryable: boolean;
  result?: R;
}

/** /api/certify result. */
export interface InhouseCertifyResult {
  sessionId: string;
  status: string;
  code: string;
  message?: string;
}

/** /api/treat result. data = CODEF byte-호환 {treatment, treatmentAuto, medicine}. */
export interface InhouseTreatResult {
  ok: boolean;
  code: string;
  note?: string;
  data?: { treatment?: unknown; treatmentAuto?: unknown; medicine?: unknown };
}

/** 2-way 세션 핸들 — jti에 base64(JSON)로 인코딩해 1차↔2차 왕복. */
export interface InhouseSession {
  sessionId: string;
  authType: 'simple' | 'mobile';
  //* ALB sticky 라우팅용 쿠키(`AWSALB`/`AWSALBCORS`). certify가 만든 박스로 treat을 보내려고
  //*   certify 응답의 Set-Cookie를 여기에 담아 jti로 왕복시킨다. 없으면(단일박스/스티키 미사용) 생략.
  //*   세션(jti)마다 고유하게 보관 → 전역 jar 없이 동시 사용자 격리. 라우팅용이라 PII 아님(로그 금지).
  albCookie?: string;
}

export function encodeInhouseSession(s: InhouseSession): string {
  return Buffer.from(JSON.stringify(s), 'utf-8').toString('base64');
}

export function decodeInhouseSession(jti?: string): InhouseSession | null {
  if (!jti) return null;
  try {
    return JSON.parse(Buffer.from(jti, 'base64').toString('utf-8'));
  } catch {
    return null;
  }
}

/**
 * 응답 Set-Cookie 헤더(axios: string[] | string)에서 ALB sticky 쿠키만 골라
 *   treat 요청 Cookie 헤더로 그대로 보낼 `name=value` 문자열로 합친다.
 *   - `AWSALB`/`AWSALBCORS` 두 쿠키만 대상(다른 쿠키/세션 토큰은 무시 → 불필요 누출 방지).
 *   - 하나도 없으면 undefined(하위호환: 단일박스/스티키 미사용 시 평소대로 동작).
 *   - 쿠키 값은 라우팅용이라 민감도 낮지만 호출부에서 로깅하지 않는다.
 */
export function extractAlbCookie(
  setCookie: string[] | string | undefined,
): string | undefined {
  if (!setCookie) return undefined;
  const lines = Array.isArray(setCookie) ? setCookie : [setCookie];
  const pairs: string[] = [];
  for (const line of lines) {
    //* Set-Cookie 한 줄: "AWSALB=xxx; Path=/; ..." → 맨 앞 name=value 만 취한다.
    const pair = String(line).split(';', 1)[0]?.trim();
    if (!pair) continue;
    const name = pair.split('=', 1)[0]?.trim();
    if (name === 'AWSALB' || name === 'AWSALBCORS') pairs.push(pair);
  }
  return pairs.length ? pairs.join('; ') : undefined;
}

/** 엔진 성공 코드(result-codes.ts). 1차=추가인증필요, 2차=수집완료. */
export const INH_CERTIFY_OK = 'INH-0001';
export const INH_TREAT_OK = 'INH-0000';

/**
 * 이 분류는 인프라/용량/기관 측 문제 → 어댑터가 throw하여 디스패처가 **다른 공급자로 폴백**하게 한다(블렌드).
 * (유저 입력/인증 오류는 폴백해도 동일 실패 → 그대로 사용자에게 반환.)
 */
export const FALLBACK_CATEGORIES = new Set([
  'BUSY',
  'SYSTEM_ERROR',
  'VENDOR_ERROR',
  'NETWORK_ERROR',
]);

/** inquiryType('0'건강 '1'자동차 '2'약) → 엔진 service / 결과 data 키. */
export const INQUIRY_TO_SERVICE: Record<string, 'diag' | 'diagAuto' | 'dur'> = {
  '0': 'diag',
  '1': 'diagAuto',
  '2': 'dur',
};
export const INQUIRY_TO_DATAKEY: Record<
  string,
  'treatment' | 'treatmentAuto' | 'medicine'
> = {
  '0': 'treatment',
  '1': 'treatmentAuto',
  '2': 'medicine',
};
