/**
 * 유저 단계 → 벤더별 API 단계 → 각 API 단계의 오류/정상 응답 (흐름/Flow 뷰용).
 *
 * 두 가지 단계 개념을 분리:
 *  - 개념단계(SCENARIO_META.stage): 유저가 그 실수를 하는 단계(중앙 유저단계 태그용). INPUT_INVALID=REQUEST(유저1) 등.
 *  - 표출단계(VENDOR_FLOWS step.scenarios): 그 native코드가 실제로 드러나는 벤더 API 단계.
 *    ⚠️ codef는 1차 certify가 입력검증 없이 CF-03002(성공)만 반환 → 입력오류 포함 모든 오류가 2차(treat)에서 표출.
 *       coocon은 본인인증(1차)에서 즉시 검증 → 1차에서 표출. (벤더마다 다름)
 */

export const USER_STEPS = [
  { step: 0, url: 'step1', label: '개인정보 동의', desc: '동의 화면 (API 호출 없음)' },
  { step: 1, url: 'step2', label: '개인정보 입력 · 인증요청', desc: '이름/주민/휴대폰 입력 후 인증 시작' },
  { step: 2, url: 'step3', label: '문자/승인 입력 · 인증확인', desc: 'SMS 입력 또는 앱 승인 후 확인' },
  { step: 3, url: 'step4', label: '인증완료 · 분석요청 완료', desc: '자료수집 트리거, 완료 화면' },
];

/** canonical 오류 시나리오. stage=개념단계(유저단계 태그용), category, authOnly */
export const SCENARIO_META: Record<string, { category: string; stage: string; authOnly?: 'sms' | 'simple'; hint?: string }> = {
  '이름 오입력': { category: 'INPUT_INVALID', stage: 'REQUEST' },
  '주민번호 오입력': { category: 'INPUT_INVALID', stage: 'REQUEST' },
  '휴대폰번호 오입력': { category: 'INPUT_INVALID', stage: 'REQUEST' },
  '이름-주민번호 불일치': { category: 'INPUT_INVALID', stage: 'REQUEST' },
  '통신사 불일치/미선택': { category: 'INPUT_INVALID', stage: 'REQUEST', authOnly: 'sms' },
  '앱 미설치 계정': { category: 'AUTH_APP_MISSING', stage: 'REQUEST', authOnly: 'simple' },
  '인증서 미보유': { category: 'AUTH_CERT', stage: 'REQUEST' },
  '만료/폐기 인증서': { category: 'AUTH_CERT', stage: 'REQUEST' },
  '미성년/연령 제한': { category: 'AGE_RESTRICTED', stage: 'REQUEST' },
  '기관 점검시간대': { category: 'VENDOR_ERROR', stage: 'REQUEST' },
  '간편 인증 거부/미승인': { category: 'AUTH_NOT_APPROVED', stage: 'CONFIRM', authOnly: 'simple' },
  'SMS 인증번호 오입력': { category: 'AUTH_CODE_WRONG', stage: 'CONFIRM', authOnly: 'sms' },
  '인증서 비밀번호 오류': { category: 'AUTH_CERT', stage: 'CONFIRM' },
  '인증 시간 초과(미응답)': { category: 'AUTH_TIMEOUT', stage: 'CONFIRM', hint: '간편인증을 승인(완료)한 뒤, 세션(인증서) 유효시간이 만료된 다음 2차(인증확인+자료수집)를 시도한 경우' },
  '2차 세션 만료 후': { category: 'AUTH_EXPIRED', stage: 'CONFIRM', hint: '인증요청만 하고(승인하지 않음) 인증 가능시간이 초과될 때까지 기다린 뒤 2차(인증확인+자료수집)를 시도한 경우' },
  '진료내역 없는 계정': { category: 'NO_DATA', stage: 'COLLECT' },
  '동일요청 중복': { category: 'DUPLICATE', stage: 'COLLECT' },
  '기관 장애/세션종료': { category: 'VENDOR_ERROR', stage: 'COLLECT' },
  '비정상 로그아웃': { category: 'VENDOR_ERROR', stage: 'FINALIZE' },
};

/**
 * 벤더별 인증 대기/세션 만료 시간 (문서·코드 근거). 미기재는 테스트로 측정.
 * '인증 시간 초과(미응답)' = authWait, '2차 세션 만료 후' = session 에 대응.
 */
export const VENDOR_TIMEOUTS: Record<string, { authWait: string; session: string }> = {
  codef: {
    authWait: 'SMS 제한시간 기본 170s(30~170s, timeout 파라미터) · 보안숫자(캡차) 60s · 간편=인증앱 자체 대기',
    session: '간편 로그인세션(id 기반) — 별도 만료시간 문서 미명시(2차 요청 timeout 동안 유효)',
  },
  coocon: {
    authWait: '프론트 카운트다운 170s (twoWayTimestamp+170s)',
    session: '스크래핑 세션 300s(우리 TimeoutRuntime 설정) · 쿠콘 디폴트 150s → 초과 시 80002F20 세션종료',
  },
  octover: {
    authWait: '문서 미기재 → 테스트로 측정 필요',
    session: 'encInput 세션 만료시간 문서 미기재 → 테스트로 측정',
  },
  hyphen: {
    authWait: '문서 미기재(B0002 진료) → 테스트로 측정',
    session: 'step_data/userData 세션 만료 미기재 → 테스트 (초과 시 I0001-010 세션종료)',
  },
};
//* 공통: 우리 HTTP treat 요청 timeout 300s · 멀티 디스패처 슬롯 TTL 600s(실측 OTP승인+수집 ~3.4분)

export interface FlowStep {
  seq: number;
  userStep: number;
  api: string;
  note: string;
  hidden?: boolean;
  /** 이 단계의 정상/진행 응답 코드 (오류 아님) */
  success?: { code: string; label: string };
  /** 이 단계에서 표출되는 오류 시나리오: 명시 배열 | 'ALL'(전 오류, 로그아웃 제외) | 'NONE'(정상만) */
  scenarios: string[] | 'ALL' | 'NONE';
}

export const VENDOR_FLOWS: Record<string, Record<'sms' | 'simple', FlowStep[]>> = {
  coocon: {
    sms: [
      { seq: 1, userStep: 1, api: '본인인증', note: '인증 시작(MOBILE) — 입력 즉시 검증', success: { code: '00000000', label: '본인인증 성공' },
        scenarios: ['이름 오입력', '주민번호 오입력', '휴대폰번호 오입력', '이름-주민번호 불일치', '통신사 불일치/미선택', '인증서 미보유', '만료/폐기 인증서', '미성년/연령 제한'] },
      { seq: 2, userStep: 1, api: '휴대폰인증_1', note: '보안문자 자동통과 + SMS 발송', success: { code: '00000000', label: 'SMS 발송' },
        scenarios: ['기관 점검시간대'] },
      { seq: 3, userStep: 2, api: '휴대폰인증_2', note: 'SMS 인증번호 확인', success: { code: '00000000', label: '인증 확인' },
        scenarios: ['SMS 인증번호 오입력', '인증 시간 초과(미응답)', '2차 세션 만료 후'] },
      { seq: 4, userStep: 3, api: '내진료정보열람', note: '진료정보 요청', success: { code: '00000000', label: '수집 성공' },
        scenarios: ['진료내역 없는 계정', '동일요청 중복', '기관 장애/세션종료'] },
      { seq: 5, userStep: 3, api: '로그아웃', note: '세션 종료(필수)', hidden: true, success: { code: '00000000', label: '로그아웃' },
        scenarios: ['비정상 로그아웃'] },
    ],
    simple: [
      { seq: 1, userStep: 1, api: '본인인증', note: '인증 시작(간편사) → 앱 푸시, 입력 즉시 검증', success: { code: '00000000', label: '본인인증 성공' },
        scenarios: ['이름 오입력', '주민번호 오입력', '이름-주민번호 불일치', '앱 미설치 계정', '인증서 미보유', '만료/폐기 인증서', '미성년/연령 제한'] },
      { seq: 2, userStep: 2, api: 'OTP', note: '앱 승인 확인', success: { code: '00000000', label: '승인 확인' },
        scenarios: ['간편 인증 거부/미승인', '인증서 비밀번호 오류', '인증 시간 초과(미응답)', '2차 세션 만료 후'] },
      { seq: 3, userStep: 3, api: '내진료정보열람', note: '진료정보 요청', success: { code: '00000000', label: '수집 성공' },
        scenarios: ['진료내역 없는 계정', '동일요청 중복', '기관 장애/세션종료'] },
      { seq: 4, userStep: 3, api: '로그아웃', note: '세션 종료(필수)', hidden: true, success: { code: '00000000', label: '로그아웃' },
        scenarios: ['비정상 로그아웃'] },
    ],
  },
  codef: {
    sms: [
      { seq: 1, userStep: 1, api: 'certify(1차)', note: '⚠️ 입력검증 없이 CF-03002만 반환 — 오류는 2차에서 표출', success: { code: 'CF-03002', label: '추가인증 필요(1차 성공)' }, scenarios: 'NONE' },
      { seq: 2, userStep: 2, api: 'treat(2차)', note: '입력·인증·수집 오류가 모두 여기서 표출(유저1·2·3 통합)', success: { code: 'CF-00000', label: '수집 성공' }, scenarios: 'ALL' },
    ],
    simple: [
      { seq: 1, userStep: 1, api: 'certify(1차)', note: '⚠️ 입력검증 없이 CF-03002만 반환 → 앱 푸시. 오류는 2차에서 표출', success: { code: 'CF-03002', label: '추가인증 필요(1차 성공)' }, scenarios: 'NONE' },
      { seq: 2, userStep: 2, api: 'treat(2차)', note: '입력·인증·수집 오류가 모두 여기서 표출(유저1·2·3 통합)', success: { code: 'CF-00000', label: '수집 성공' }, scenarios: 'ALL' },
    ],
  },
  octover: {
    sms: [
      { seq: 1, userStep: 1, api: 'phoneVerify(1차)', note: '본인인증 요청 → SMS (1차 검증여부 테스트확인)', success: { code: '1000200', label: '본인인증 성공' }, scenarios: 'NONE' },
      { seq: 2, userStep: 2, api: 'phoneVerifyResult + AB001(체인)', note: '인증확인+자료수집 한 요청에 체인(유저2·3 통합)', success: { code: '1000200', label: '수집 성공' }, scenarios: 'ALL' },
    ],
    simple: [
      { seq: 1, userStep: 1, api: 'simpleAuthLogin(1차)', note: '본인인증 요청 → 앱 푸시 (1차 검증여부 테스트확인)', success: { code: '1000200', label: '본인인증 성공' }, scenarios: 'NONE' },
      { seq: 2, userStep: 2, api: 'simpleAuthLoginResult + AB001(체인)', note: '인증확인+자료수집 한 요청에 체인(유저2·3 통합)', success: { code: '1000200', label: '수집 성공' }, scenarios: 'ALL' },
    ],
  },
  hyphen: {
    sms: [
      { seq: 1, userStep: 1, api: 'captchaPass(1차)', note: '보안문자 자동통과 + SMS 발송 (1차 검증여부 테스트확인)', success: { code: '0000', label: '발송 성공' }, scenarios: 'NONE' },
      { seq: 2, userStep: 2, api: 'identityCheck(2차)', note: '인증확인+자료수집 한 요청(유저2·3 통합), 업무오류=errMsg', success: { code: '0000', label: '수집 성공' }, scenarios: 'ALL' },
    ],
    simple: [
      { seq: 1, userStep: 1, api: 'EASY(1차)', note: '간편 인증요청 → 앱 푸시 (1차 검증여부 테스트확인)', success: { code: '0000', label: '요청 성공' }, scenarios: 'NONE' },
      { seq: 2, userStep: 2, api: 'step_data(2차)', note: '인증확인+자료수집 한 요청(유저2·3 통합), 업무오류=errMsg', success: { code: '0000', label: '수집 성공' }, scenarios: 'ALL' },
    ],
  },
};
