/*
 * M9 정산·결제 실 API 클라이언트 — 공용 client(../../api/client)의 api 만 사용.
 * 정본: 백엔드 com.zioinfo.kintex.settlement (SettlementController) 시그니처.
 *
 * ★ 금액은 서버 계산이 권위 — 프론트는 서버가 준 원 단위(long)를 표시만 한다(재계산 없음).
 * ★ 결제는 PG 위임 고지 패턴 — 실 PG 연동 없음. 수납은 매니저 수동 기록으로 상태만 전이.
 */
import { api } from '../../api/client';

export type InvoiceStatus = 'pending' | 'invoiced' | 'paid' | 'overdue' | 'cancelled';
/** 정산 유형(F084) — rental(임대·유틸) | auction_fee(옥션 수수료). */
export type InvoiceCategory = 'rental' | 'auction_fee';

export interface StatusBucket {
  status: InvoiceStatus;
  count: number;
  totalAmount: number;
  paidAmount: number;
}

export interface SettlementDashboard {
  eventId: string;
  billed: number;
  collected: number;
  outstanding: number;
  invoiceCount: number;
  overdueCount: number;
  collectionRate: number;
  statusDistribution: StatusBucket[];
  paymentNote: string;
}

export interface InvoiceSummary {
  id: string;
  eventId: string;
  invoiceNo: string;
  exhibitorName: string;
  subtotal: number;
  vat: number;
  total: number;
  paidAmount: number;
  outstanding: number;
  status: InvoiceStatus;
  dueDate: string | null;
  issuedAt: string | null;
  category: InvoiceCategory;
}

export interface LineItem {
  category: string; // RENTAL | UTILITY | OTHER
  description: string;
  quantity: number;
  unitPrice: number;
  amount: number;
}

export interface PaymentRecord {
  id: string;
  amount: number;
  method: string; // manual | transfer | card
  memo: string | null;
  recordedAt: string;
}

export interface InvoiceDetail {
  id: string;
  eventId: string;
  invoiceNo: string;
  exhibitorName: string;
  subtotal: number;
  vat: number;
  total: number;
  paidAmount: number;
  outstanding: number;
  status: InvoiceStatus;
  dueDate: string | null;
  issuedAt: string | null;
  paidAt: string | null;
  note: string | null;
  category: InvoiceCategory;
  lineItems: LineItem[];
  payments: PaymentRecord[];
  canManage: boolean;
}

export interface PageResponse<T> {
  items: T[];
  page: number;
  size: number;
  total: number;
}

export interface GenerateResult {
  eventId: string;
  created: number;
  skipped: number;
  invoices: InvoiceSummary[];
}

export interface RecordPaymentInput {
  amount: number;
  method?: 'manual' | 'transfer' | 'card';
  memo?: string;
}

// ── F085 환불·취소 ────────────────────────────────────────────────────────────
/** 환불 산정 미리보기/확정 근거. 금액은 서버 계산 권위. base = 실 납입액 기준. */
export interface RefundQuote {
  invoiceId: string;
  invoiceNo: string;
  status: InvoiceStatus;
  total: number;
  baseAmount: number;
  refundRatePercent: number;
  refundAmount: number;
  forfeitAmount: number;
  daysBeforeEvent: number | null;
  bracketLabel: string;
  eventStartDate: string | null;
  dateResolved: boolean;
  rulesetVersion: string;
  pgNote: string;
}

export interface CancelResult {
  invoice: InvoiceDetail;
  refund: RefundQuote;
}

// ── F083 세금계산서 ──────────────────────────────────────────────────────────
export interface TaxInvoice {
  id: string;
  invoiceId: string;
  eventId: string;
  taxInvoiceNo: string;
  supplierName: string;
  supplierBizNo: string | null;
  supplierCeo: string | null;
  supplierAddr: string | null;
  buyerName: string;
  supplyAmount: number;
  vat: number;
  total: number;
  itemSummary: string | null;
  status: string; // issued | void
  issuedAt: string;
  issueNote: string;
}

// ── 정산 리포트 ──────────────────────────────────────────────────────────────
export interface ReportGroup {
  key: string;
  invoiceCount: number;
  billed: number;
  collected: number;
  outstanding: number;
  collectionRate: number;
}

export interface ReportRow {
  invoiceNo: string;
  exhibitorName: string;
  category: string;
  status: string;
  subtotal: number;
  vat: number;
  total: number;
  paidAmount: number;
  outstanding: number;
  dueDate: string | null;
}

export interface SettlementReport {
  eventId: string;
  eventName: string | null;
  generatedAt: string;
  totalBilled: number;
  totalCollected: number;
  totalOutstanding: number;
  collectionRate: number;
  invoiceCount: number;
  byCategory: ReportGroup[];
  byStatus: ReportGroup[];
  rows: ReportRow[];
}

export const settlementApi = {
  dashboard: (eventId: string) =>
    api.get<SettlementDashboard>(`/api/settlement/dashboard?eventId=${encodeURIComponent(eventId)}`),

  invoices: (eventId: string, status: string | null, page: number, size: number) => {
    const params = new URLSearchParams({ eventId, page: String(page), size: String(size) });
    if (status) params.set('status', status);
    return api.get<PageResponse<InvoiceSummary>>(`/api/settlement/invoices?${params.toString()}`);
  },

  detail: (id: string) => api.get<InvoiceDetail>(`/api/settlement/invoices/${encodeURIComponent(id)}`),

  generate: (eventId: string) =>
    api.post<GenerateResult>(`/api/settlement/invoices/generate?eventId=${encodeURIComponent(eventId)}`),

  issue: (id: string) =>
    api.post<InvoiceDetail>(`/api/settlement/invoices/${encodeURIComponent(id)}/issue`),

  recordPayment: (id: string, input: RecordPaymentInput) =>
    api.post<InvoiceDetail>(`/api/settlement/invoices/${encodeURIComponent(id)}/payments`, input),

  // F085 환불·취소
  refundQuote: (id: string, cancelDate?: string) => {
    const q = cancelDate ? `?cancelDate=${encodeURIComponent(cancelDate)}` : '';
    return api.get<RefundQuote>(`/api/settlement/invoices/${encodeURIComponent(id)}/refund-quote${q}`);
  },
  cancel: (id: string, body: { reason?: string; cancelDate?: string }) =>
    api.post<CancelResult>(`/api/settlement/invoices/${encodeURIComponent(id)}/cancel`, body),

  // F083 세금계산서 (없으면 data=null)
  getTaxInvoice: (id: string) =>
    api.get<TaxInvoice | null>(`/api/settlement/invoices/${encodeURIComponent(id)}/tax-invoice`),
  issueTaxInvoice: (id: string) =>
    api.post<TaxInvoice>(`/api/settlement/invoices/${encodeURIComponent(id)}/tax-invoice`),

  // 정산 리포트
  report: (eventId: string) =>
    api.get<SettlementReport>(`/api/settlement/report?eventId=${encodeURIComponent(eventId)}`),
};
