import type { FulfillmentStatus, PurchaseStatus } from '@/types/db'

/**
 * Purchase lifecycle rules (2026-09-29 task §10, §16).
 *
 * Payment and fulfillment are two different things and never share a field.
 * `paid` can only be entered by a VERIFIED Synchron confirmation
 * (src/lib/data/purchases.ts → applyVerifiedPaymentEvent); no page, button or
 * return URL may set it. These tables are pure rules, no I/O.
 */

export const PURCHASE_STATUSES: readonly PurchaseStatus[] = [
  'draft', 'pending_checkout', 'pending_payment', 'paid', 'payment_failed', 'expired',
  'cancelled', 'refund_pending', 'partially_refunded', 'refunded',
] as const

export const FULFILLMENT_STATUSES: readonly FulfillmentStatus[] = [
  'awaiting_payment', 'ready_for_processing', 'submitted_to_synchron', 'processing',
  'needs_review', 'completed', 'failed', 'cancelled',
] as const

/** Buy More Permits step 2 (task §18). */
export type PaymentReadiness = 'checking' | 'card_on_file' | 'card_required' | 'setup_pending' | 'setup_failed' | 'unavailable'

const PURCHASE_TRANSITIONS: Record<PurchaseStatus, readonly PurchaseStatus[]> = {
  draft: ['pending_checkout', 'cancelled'],
  pending_checkout: ['pending_payment', 'cancelled', 'expired'],
  pending_payment: ['paid', 'payment_failed', 'cancelled', 'expired'],
  payment_failed: ['pending_checkout', 'pending_payment', 'cancelled'],
  expired: ['pending_checkout'],
  cancelled: [],
  paid: ['refund_pending', 'partially_refunded', 'refunded'],
  refund_pending: ['partially_refunded', 'refunded', 'paid'],
  partially_refunded: ['refunded'],
  refunded: [],
}

const FULFILLMENT_TRANSITIONS: Record<FulfillmentStatus, readonly FulfillmentStatus[]> = {
  awaiting_payment: ['ready_for_processing', 'cancelled'],
  ready_for_processing: ['submitted_to_synchron', 'failed', 'cancelled'],
  submitted_to_synchron: ['processing', 'needs_review', 'completed', 'failed'],
  processing: ['needs_review', 'completed', 'failed'],
  needs_review: ['processing', 'completed', 'failed', 'cancelled'],
  completed: [],
  failed: ['ready_for_processing', 'needs_review', 'cancelled'],
  cancelled: [],
}

export function canTransitionPurchase(from: PurchaseStatus, to: PurchaseStatus): boolean {
  return from === to || PURCHASE_TRANSITIONS[from].includes(to)
}

export function canTransitionFulfillment(from: FulfillmentStatus, to: FulfillmentStatus): boolean {
  return from === to || FULFILLMENT_TRANSITIONS[from].includes(to)
}

/** Statuses from which a customer may (re)open checkout. */
export function isCheckoutReopenable(status: PurchaseStatus): boolean {
  return status === 'pending_checkout' || status === 'pending_payment' || status === 'payment_failed' || status === 'expired'
}

/** Customer-facing wording (task §13, §14). */
export const PURCHASE_STATUS_LABELS: Record<PurchaseStatus, string> = {
  draft: 'Draft',
  pending_checkout: 'Awaiting checkout',
  pending_payment: 'Pending payment',
  paid: 'Paid',
  payment_failed: 'Payment failed',
  expired: 'Checkout expired',
  cancelled: 'Cancelled',
  refund_pending: 'Refund pending',
  partially_refunded: 'Partially refunded',
  refunded: 'Refunded',
}

export const FULFILLMENT_STATUS_LABELS: Record<FulfillmentStatus, string> = {
  awaiting_payment: 'Awaiting payment',
  ready_for_processing: 'Ready for processing',
  submitted_to_synchron: 'Submitted to Synchron',
  processing: 'Route processing',
  needs_review: 'Needs review',
  completed: 'Completed',
  failed: 'Failed',
  cancelled: 'Cancelled',
}

export const RETURN_COPY = {
  pending: "We're checking your payment status with Synchron Permits.",
  confirmed: 'Your payment was confirmed. Your routing request is being processed.',
  failed: 'Your payment was not completed. Please try again.',
  cancelled: 'Your purchase was not completed. Your route selections have been preserved.',
  delayed: 'Your purchase is awaiting payment confirmation. Please check again shortly.',
} as const

export type ReturnState = keyof typeof RETURN_COPY

/** What the checkout-return page shows for a purchase in this state. */
export function returnStateFor(status: PurchaseStatus, opts: { delayed: boolean }): ReturnState {
  if (status === 'paid' || status === 'refund_pending' || status === 'partially_refunded' || status === 'refunded') return 'confirmed'
  if (status === 'payment_failed') return 'failed'
  if (status === 'cancelled' || status === 'expired') return 'cancelled'
  return opts.delayed ? 'delayed' : 'pending'
}

/** Sum in integer cents; never floats. */
export function lineTotal(unitPriceCents: number, quantity: number): number {
  return unitPriceCents * quantity
}

/** Random, URL-safe HHA purchase token: `hhp_` + 20 base32 chars. Pure. */
export function purchaseReferenceFrom(bytes: Uint8Array): string {
  const alphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
  let out = 'hhp_'
  for (let i = 0; i < 20; i++) out += alphabet[bytes[i % bytes.length] % alphabet.length]
  return out
}
