import { UUID } from '../../../../shared/types/primitive.types';

export type AdminOrderStatus = 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
export type AdminOrderPaymentStatus = 'unpaid' | 'paid' | 'refund_requested' | 'refunded';

/**
 * Single source of truth for which statuses are terminal. Enforced at the
 * facade layer (not just the page component's dropdown filtering) so any
 * caller - a different admin surface, a future API route - can't move a
 * cancelled/refunded order back to an active status.
 */
export const TERMINAL_ORDER_STATUSES: readonly AdminOrderStatus[] = ['cancelled', 'refunded'];

export interface AdminOrderCustomer {
  name: string;
  email: string;
  phone: string;
}

export interface AdminOrderPayment {
  method: string;
  status: AdminOrderPaymentStatus;
  amount: number;
  currency: string;
}

export interface AdminOrderShipping {
  address: string;
  method: string;
  trackingNumber: string;
}

export interface AdminOrderItem {
  productId: string;
  name: string;
  quantity: number;
  price: number;
  /**
   * Reconstructs the charged total per PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md
   * §5.3 / §4 - all optional, since orders placed before this field existed
   * (or any order the backend hasn't populated it for yet) have none of it.
   * Absence must render as "not available", never as a fabricated 0 or 1:1 rate.
   */
  unitPriceMinor?: number;
  lineTotalMinor?: number;
  priceSnapshotId?: string;
  discountMinor?: number;
}

export type AdminOrderTimelineEventKey = 'created' | 'statusChanged' | 'refundRequested';

export interface AdminOrderTimelineEntry {
  status: AdminOrderStatus;
  timestamp: string;
  eventKey: AdminOrderTimelineEventKey;
  actor: string;
}

export interface AdminOrder {
  id: string;
  orderNumber: string;
  status: AdminOrderStatus;
  customer: AdminOrderCustomer;
  payment: AdminOrderPayment;
  shipping: AdminOrderShipping;
  items: AdminOrderItem[];
  total: number;
  currency: string;
  notes: string;
  internalNotes: string;
  timeline: AdminOrderTimelineEntry[];
  archived: boolean;
  createdAt: string;
  updatedAt: string;
  /**
   * Future optional seller ownership (Seller Management preparation).
   * Absent means marketplace-owned, exactly like every order today -
   * nothing reads this field yet, no behavior change.
   */
  sellerId?: UUID;
  /** FX quote used to compute the total, when the order was priced cross-currency. */
  fxQuoteId?: string;
  /** Delivery cost, minor units - see AdminOrder.total = formula in the panel this feeds. */
  deliveryMinor?: number;
  /**
   * PARTNER-PROVISIONING-API-CONTRACT.md §7 - which payment point the money
   * actually landed on. Optional: not every order flows through a partner-
   * provisioned hierarchy.
   */
  routing?: {
    companyId: string;
    routingPath: string[];
    leafNodeId: string;
    environment: 'TEST' | 'LIVE';
    merchantReference: string;
    providerPaymentId: string;
  };
}

export interface AdminOrderListFilters {
  search: string;
  status: 'all' | AdminOrderStatus;
  page: number;
  pageSize: number;
}

export interface AdminOrdersListResult {
  items: AdminOrder[];
  total: number;
  page: number;
  pageSize: number;
}
