/*
 * 공개 입장권(티켓) API 클라이언트 — 전 경로 비인증 공개(/api/public/tickets/**).
 * 백엔드: com.zioinfo.kintex.ticket (V50). 응답은 ApiResponse.data 로 언랩됨.
 * 보안: 응답의 구매자 정보는 서버 마스킹 필드만 소비(원문 없음).
 */
import { api } from '../../api/client';

/** 판매 상품 — remaining/onSale/soldOut 은 서버 권위. */
export interface TicketProduct {
  id: string;
  eventId: string;
  code: string;
  kind: string; // GENERAL/STUDENT/GROUP/VIP/BUYER
  name: string;
  description: string | null;
  price: number;
  currency: string;
  saleStart: string | null;
  saleEnd: string | null;
  totalQty: number;
  remaining: number;
  maxPerOrder: number;
  onSale: boolean;
  soldOut: boolean;
  sortOrder: number;
}

export interface IssuedTicket {
  ticketCode: string;
  seq: number;
  used: boolean;
}

export interface TicketOrderRequest {
  productId: string;
  qty: number;
  buyerName: string;
  buyerContact: string;
  buyerEmail?: string;
  agreePrivacy: boolean;
  payMethod?: string; // card/easy/bank (무료권은 서버가 free 처리)
}

export interface TicketOrderResult {
  orderNo: string;
  status: string; // PAID
  eventId: string;
  productName: string;
  qty: number;
  unitPrice: number;
  totalAmount: number;
  payMethod: string | null;
  approvalNo: string | null;
  buyerNameMasked: string | null;
  buyerContactMasked: string | null;
  buyerEmailMasked: string | null;
  orderedAt: string | null;
  tickets: IssuedTicket[];
}

export interface TicketLookupResult {
  orderNo: string;
  status: string;
  eventId: string;
  productName: string;
  qty: number;
  unitPrice: number;
  totalAmount: number;
  payMethod: string | null;
  buyerNameMasked: string | null;
  buyerContactMasked: string | null;
  buyerEmailMasked: string | null;
  orderedAt: string | null;
  paidAt: string | null;
  tickets: IssuedTicket[];
}

// ── F-B2 취소·환불 다구간(서버 권위) ──
export interface RefundBracket {
  minDaysBefore: number;
  refundRatePercent: number;
  label: string;
}
export interface RefundQuote {
  orderNo: string;
  status: string; // PAID/CANCELLED
  productName: string;
  qty: number;
  ticketAmount: number;
  bookingFee: number;
  daysBefore: number;
  refundRatePercent: number;
  bracketLabel: string;
  ticketRefund: number;
  adminFee: number;
  bookingFeeRefund: number;
  refundAmount: number;
  forfeitAmount: number;
  policyVersion: string;
  cancellable: boolean;
  brackets: RefundBracket[];
}

// ── F-B1 스마트티켓(회전 QR) ──
export interface SmartActivateResult {
  ticketCode: string;
  activated: boolean;
  windowSeconds: number;
}
export interface RotatingToken {
  ticketCode: string;
  token: string;
  qrPayload: string; // ticketCode|token — QR 인코딩 대상
  windowSeconds: number;
  remainingSeconds: number;
}
export interface SmartVerifyResult {
  valid: boolean;
  ticketCode: string | null;
  reason: string;
}

const opt = { anonymous: true } as const;

export const ticketApi = {
  /** 행사 판매중 상품 목록(잔여수량·판매기간 서버 권위). */
  listProducts: (eventId: string) =>
    api.get<TicketProduct[]>(`/api/public/tickets/${encodeURIComponent(eventId)}`, opt),

  /** 예매(재고차감→PG승인→발권). 실패 시 봉투 error(code)로 강등. */
  createOrder: (eventId: string, payload: TicketOrderRequest) =>
    api.post<TicketOrderResult>(
      `/api/public/tickets/${encodeURIComponent(eventId)}/orders`,
      payload,
      opt,
    ),

  /** 예매 조회 — 주문번호 + 연락처(하이픈 무관). 불일치·부재는 NOT_FOUND. */
  lookup: (orderNo: string, contact: string) =>
    api.get<TicketLookupResult>(
      `/api/public/tickets/lookup?orderNo=${encodeURIComponent(orderNo)}&contact=${encodeURIComponent(contact)}`,
      opt,
    ),

  // ── F-B2 취소·환불 ──
  /** 취소 전 예상 환불 산정(조회만, 서버 권위). */
  refundQuote: (orderNo: string, contact: string) =>
    api.post<RefundQuote>('/api/public/tickets/refund-quote', { orderNo, contact }, opt),
  /** 실제 취소 처리(상태 전이·재고 원복·환불 스냅샷). */
  cancel: (orderNo: string, contact: string) =>
    api.post<RefundQuote>('/api/public/tickets/cancel', { orderNo, contact }, opt),

  // ── F-B1 스마트티켓(회전 QR) ──
  /** 스마트티켓 활성화(디바이스 바인딩) — 예매번호+연락처 본인확인. */
  smartActivate: (orderNo: string, contact: string, ticketCode: string, deviceId: string) =>
    api.post<SmartActivateResult>(
      '/api/public/tickets/smart/activate',
      { orderNo, contact, ticketCode, deviceId },
      opt,
    ),
  /** 현재 회전 토큰(QR 페이로드) — 바인딩 기기에서만. */
  smartToken: (ticketCode: string, deviceId: string) =>
    api.get<RotatingToken>(
      `/api/public/tickets/smart/token?ticketCode=${encodeURIComponent(ticketCode)}&deviceId=${encodeURIComponent(deviceId)}`,
      opt,
    ),
  /** 게이트 QR 검증(회전 토큰). */
  smartVerify: (qrPayload: string) =>
    api.post<SmartVerifyResult>('/api/public/tickets/smart/verify', { qrPayload }, opt),
};
