export interface LoyaltySettings {
  restaurant_id: string;
  enabled: boolean;
  earn_mode: 'per_dollar' | 'per_order' | 'per_item';
  earn_rate: number;
  redeem_points_per_unit: number;
  redeem_unit_value: number;
  expiry_months: number | null;
  min_redeem_points: number;
  eligibility_order_types: string[];
  eligibility_channels: string[];
  tier_threshold_mode: 'lifetime_points' | 'rolling_12mo_spend';
  notify_on_earn: boolean;
  notify_on_tier_up: boolean;
}

export interface LoyaltyTier {
  id: string;
  restaurant_id: string;
  name: string;
  threshold: number;
  earn_multiplier: number;
  auto_discount_pct: number;
  free_delivery: boolean;
  perks_text: string | null;
  badge_color: string | null;
  display_order: number;
}

export interface CustomerLoyaltyView {
  enabled: boolean;
  settings: LoyaltySettings | null;
  wallet: {
    customer_id: string;
    restaurant_id: string;
    balance: number;
    lifetime_points: number;
    rolling_12mo_spend: number;
    tier_id: string | null;
  } | null;
  tier: LoyaltyTier | null;
  next_tier: LoyaltyTier | null;
  progress_to_next: number;
  ledger?: LedgerRow[];
}

export interface LedgerRow {
  id: string;
  type: 'earn' | 'redeem' | 'adjust' | 'expire' | 'reverse';
  points: number;
  order_id: string | null;
  reason: string | null;
  expires_at: string | null;
  created_at: string;
}

async function apiFetch<T>(url: string, options?: RequestInit): Promise<T> {
  const res = await fetch(url, { credentials: 'include', ...options });
  const json = (await res.json().catch(() => ({}))) as Record<string, unknown>;
  if (!res.ok) throw new Error((json.error as string) || `Request failed: ${res.status}`);
  return json as T;
}

export async function getLoyaltyConfig(): Promise<{ settings: LoyaltySettings; tiers: LoyaltyTier[] }> {
  return apiFetch('/api/loyalty/settings');
}

export async function updateLoyaltySettings(body: Partial<LoyaltySettings>): Promise<{ settings: LoyaltySettings }> {
  return apiFetch('/api/loyalty/settings', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
}

export async function listLoyaltyTiers(): Promise<{ tiers: LoyaltyTier[] }> {
  return apiFetch('/api/loyalty/tiers');
}

export async function createLoyaltyTier(body: Partial<LoyaltyTier> & { name: string }): Promise<{ tier: LoyaltyTier }> {
  return apiFetch('/api/loyalty/tiers', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
}

export async function updateLoyaltyTier(id: string, body: Partial<LoyaltyTier>): Promise<{ tier: LoyaltyTier }> {
  return apiFetch(`/api/loyalty/tiers/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
}

export async function deleteLoyaltyTier(id: string): Promise<{ success: boolean }> {
  return apiFetch(`/api/loyalty/tiers/${id}`, { method: 'DELETE' });
}

export async function getCustomerLoyalty(customerId: string): Promise<CustomerLoyaltyView> {
  return apiFetch(`/api/loyalty/customers/${customerId}`);
}

export async function adjustCustomerPoints(
  customerId: string,
  delta: number,
  reason: string,
): Promise<{ delta: number; balance: number }> {
  return apiFetch(`/api/loyalty/customers/${customerId}/adjust`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ delta, reason }),
  });
}

export type LoyaltyStatsPeriod = 'today' | 'week' | 'month' | '3months';

export interface LoyaltyStats {
  enabled: boolean;
  period: LoyaltyStatsPeriod;
  currentStart: string;
  totals: {
    points_outstanding: number;
    wallets: number;
    points_earned: number;
    points_redeemed: number;
    points_expired: number;
    points_adjusted: number;
    points_reversed: number;
    net_points_change: number;
  };
  redemption: {
    total_orders: number;
    redeemed_orders: number;
    redemption_rate: number;
    total_discount: number;
    avg_discount_per_redemption: number;
    redemptions_count: number;
  };
  rolling: {
    last_30_days: { points_earned: number; points_redeemed: number };
    last_90_days: { points_earned: number; points_redeemed: number };
  };
  repeat_lift: {
    member_customers: number;
    member_repeat_customers: number;
    member_repeat_rate: number;
    nonmember_customers: number;
    nonmember_repeat_customers: number;
    nonmember_repeat_rate: number;
    lift_ratio: number | null;
    lift_pct: number | null;
  };
  tier_distribution: Array<{
    tier_id: string | null;
    tier_name: string;
    badge_color: string | null;
    customers: number;
    threshold: number;
    display_order: number;
  }>;
  top_customers: Array<{
    customer_id: string;
    name: string | null;
    email: string | null;
    phone: string | null;
    tier_id: string | null;
    tier_name: string | null;
    badge_color: string | null;
    balance: number;
    lifetime_points: number;
    last_visit: string | null;
  }>;
}

export async function getLoyaltyStats(period: LoyaltyStatsPeriod = 'month'): Promise<LoyaltyStats> {
  return apiFetch(`/api/loyalty/stats?period=${period}`);
}

export async function listCustomerLedger(
  customerId: string,
  page = 1,
  limit = 50,
): Promise<{ data: LedgerRow[]; total: number; page: number; limit: number; pages: number }> {
  return apiFetch(`/api/loyalty/customers/${customerId}/ledger?page=${page}&limit=${limit}`);
}
