import { CertifyResponseDto, TreatmentMultipleResponseDto } from '@lib/codef/src/codef.dto';
import { TreatmentMultipleItemDto } from '@lib/codef/src/codef.interface';

/**
 * 진료내역 스크래핑 공급자 공통 계약.
 * CODEF(헥토)·쿠콘이 동일 시그니처를 만족하여 TreatService가 공급자 무관하게 호출한다.
 * (provider 스위치: configuration.ts treatProvider)
 */
export interface TreatScraper {
  //* reqQueueId: 대기열 재요청 시 기존 큐 ID. 멀티 디스패처만 사용(만석 시 순번 유지),
  //* 단일 공급자 구현체는 무시(optional이라 시그니처 호환).
  fetchCertifyMultiple(
    items: TreatmentMultipleItemDto[],
    reqQueueId?: string,
  ): Promise<CertifyResponseDto>;
  fetchTreatmentMultiple(
    items: TreatmentMultipleItemDto[],
    oddId: number,
  ): Promise<TreatmentMultipleResponseDto>;
}

/**
 * 쿠콘 1차(본인인증) 성공 후 2차(OTP→내진료정보열람)까지 이어가기 위해 유지해야 하는 세션 핸들.
 * CODEF의 twoWayInfo(jti 등) 자리에 base64(JSON)로 인코딩하여 클라이언트 계약(GetCertifyResponseDto/TreatDto) 변경 없이 왕복시킨다.
 */
export interface CooconSession {
  /** 거래일련번호 */
  trSeq: string;
  /** SS 서버 거래키값 (로그인 성공 후 본거래에 재사용) */
  sasSessionId: string;
  /** SS 서버 번호 */
  ssSysNo: string;
  /** SS 서버 거래번호 */
  threadNo: string;
  /** LBS 서버 번호 */
  lbsNo: string;
  /** API 서버 번호 (로그아웃 등 후속 거래 Common에 필요) */
  gwSysNo?: string;
  /** 본인인증 응답의 OTP 콜백 토큰 (Result.req.Input.req) */
  otpReq?: string;
  /** 인증 유형: 'simple'(간편) | 'mobile'(휴대폰/문자) — 2차 분기에 사용 */
  authType?: 'simple' | 'mobile';
  /** 본인인증 응답의 다음 단계 Job (CallBackfunc: 'OTP' | '휴대폰인증_1' | '휴대폰인증_2') */
  callBackFunc?: string;
}

/** 쿠콘 공통부(Common) — Dsnc/SAS_SessionID는 Common 밖 최상위 (가이드 샘플·[참조2] 기준) */
export interface CooconCommon {
  Auth_key: string;
  Tr_seq: string;
  Gw_sys_no?: string;
  Ss_sys_no?: string;
  Auth_req?: string;
  Thread_no?: string;
  Lbs_no?: string;
}

/** 게이트웨이 요청 봉투 (평문 호출 시 본문) — 공식 포스트맨 샘플 기준 */
export interface CooconEnvelope {
  /** "S": 세션유지, "E": 로그아웃(조회완료 후 필수) */
  Dsnc: 'S' | 'E';
  SAS_SessionID: string;
  /** 스크래핑 각 Step 1개당 타임아웃(초). 미입력시 30초 → 무거운 구간이 30초에 끊겨 8000F101 유발 (가이드 1.0.3) */
  TimeoutStep: string;
  /** 공식 샘플 최상위 필드 (기본 "") */
  TimeoutRuntime: string;
  Common: CooconCommon;
  InputList: CooconJobRequest[];
}

/** 쿠콘 개별부 1건 ({Module,Class,Job,Input}) — InputList 요소 */
export interface CooconJobRequest {
  Module: 'hira';
  Class: '민원신청조회' | '요양기관서비스';
  Job: string;
  Input: Record<string, any>;
}

/** 게이트웨이 호출 결과 정규화 */
export interface CooconGatewayResult {
  /** 개별부 ErrorCode ("00000000" 정상) */
  errorCode: string;
  errorMessage: string;
  /** 개별부 Result 객체 */
  result: any;
  /** 다음 단계 Job 명 (본인인증 응답의 CallBackfunc, 예: "OTP") */
  callBackFunc?: string;
  /** OTP 콜백 토큰 */
  otpReq?: string;
  /** 응답 Common에서 추출한 세션 (이후 호출에 재사용) */
  session: CooconSession;
}

/**
 * 우리 loginTypeLevel(간편인증 상세구분) → 쿠콘 인증수단 코드.
 * (CertiftDto loginTypeLevel 기준: 1카카오/2페이코/3삼성패스/4KB/5PASS/6네이버/7신한/8토스)
 */
export const LOGIN_LEVEL_TO_COOCON: Record<string, string> = {
  '1': 'KAKAO',
  '2': 'PAYCO',
  '3': 'SAMSUNG',
  '4': 'KB',
  '5': 'PASS',
  '6': 'NAVER',
  '7': 'SHINHAN',
  '8': 'TOSS',
};

/** 우리 telecom(0SKT/1KT/2LGU+/3~5알뜰) → 쿠콘 휴대폰인증_통신사(01/02/03/11~13) */
export const TELECOM_TO_COOCON: Record<string, string> = {
  '0': '01',
  '1': '02',
  '2': '03',
  '3': '11',
  '4': '12',
  '5': '13',
};

/** 세션 핸들 ↔ jti 문자열 인코딩 (클라이언트 계약 무변경 목적) */
export function encodeCooconSession(s: CooconSession): string {
  return Buffer.from(JSON.stringify(s), 'utf-8').toString('base64');
}

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