export type PaymentGateway = 'stripe' | 'mock' | 'payfast';

export type SubscriptionStatus =
  | 'pending'
  | 'active'
  | 'expired'
  | 'cancelled';

export type PackageTierType = 'payg' | 'bundle' | 'subscription';
export type BillingCycle = 'one_time' | 'monthly' | 'yearly';
export const CANONICAL_PACKAGE_SLUGS = [
  'pay-as-you-go',
  'credit-bundles',
  'subscription',
] as const;

/** A subscription package available for purchase. */
export interface Package {
  id: string;
  name: string;
  slug: string;
  description: string | null;
  priceMinor: number;
  currency: string;
  durationDays: number;
  /** null = unlimited consultations within the duration window. */
  maxConsultations: number | null;
  maxEmrRecords: number | null;
  maxDevices: number | null;
  addonAppointmentPrice: number;
  addonEmrPrice: number;
  features: string[];
  isActive: boolean;
  sortOrder: number;
  // Tier configuration
  tierType: PackageTierType;
  registrationFeeMinor: number;
  maxFamilyMembers: number;
  extraFamilyMemberFeeMinor: number;
  maxExtraFamilyMembers: number;
  bundleAppointmentCount: number | null;
  bundleDiscountPercent: number | null;
  billingCycle: BillingCycle;
  minCommitmentMonths: number;
  firstMonthFeeWaived: boolean;
}

export interface FamilyMember {
  id: string;
  subscriptionId: string;
  firstName: string;
  lastName: string;
  relation: string | null;
  email: string | null;
  linkedUserId: string | null;
  status: 'invited' | 'active' | 'removed';
  isExtra: boolean;
  removedAt: string | null;
  createdAt: string;
}

export interface FamilyCapacity {
  maxFamilyMembers: number;
  maxExtraFamilyMembers: number;
  activeMembers: number;
  activeExtras: number;
  remainingFree: number;
  remainingExtras: number;
  extraFeeMinor: number;
}

export interface AddFamilyMemberRequest {
  firstName: string;
  lastName: string;
  relation?: string;
  email?: string;
}

/**
 * The current subscription returned by `GET /me/subscription`. The backend
 * returns the raw Subscription entity (no `package` relation eagerly loaded),
 * so `packageName` is optional — derive from the packages list when needed.
 */
export interface Subscription {
  id: string;
  userId: string;
  packageId: string;
  packageName?: string;
  status: SubscriptionStatus;
  startsAt: string | null;
  expiresAt: string | null;
  consultationsUsed: number;
  addonConsultations: number;
  emrRecordsUsed: number;
  addonEmrRecords: number;
  autoRenew: boolean;
  cancelledAt: string | null;
  cancelReason: string | null;
  latestTransactionId: string | null;
}

export interface CheckoutSessionRequest {
  packageId: string;
  gateway: PaymentGateway;
}

export interface CheckoutSession {
  sessionId: string;
  redirectUrl: string;
  gateway: PaymentGateway;
  transactionId?: string;
}

export interface MockCompleteRequest {
  sessionId: string;
  succeed: boolean;
}

export interface CancelSubscriptionRequest {
  reason?: string;
}

export interface SubscriptionCredits {
  consultationsUsed: number;
  consultationsTotal: number | null;
  emrRecordsUsed: number;
  emrRecordsTotal: number | null;
}

/**
 * Format a minor-unit integer (paisa/cents) into a display string with the
 * currency prefix and grouped thousands. Always uses this helper — never
 * `.toFixed()` on raw minor units.
 */
export function formatMinor(amount: number, currency = 'PKR'): string {
  const major = amount / 100;
  // Use en-PK locale's grouping; fall back to en-US if unsupported.
  const formatted = new Intl.NumberFormat('en-PK', {
    minimumFractionDigits: major % 1 === 0 ? 0 : 2,
    maximumFractionDigits: 2,
  }).format(major);
  return `${currency} ${formatted}`;
}

export function displayPackages(packages: Package[]): Package[] {
  const canonical = new Set<string>(CANONICAL_PACKAGE_SLUGS);
  const hasFullCatalog = CANONICAL_PACKAGE_SLUGS.every((slug) =>
    packages.some((pkg) => pkg.slug === slug),
  );
  if (!hasFullCatalog) return packages;
  return packages.filter((pkg) => canonical.has(pkg.slug));
}
