import type { InferSelectModel } from 'drizzle-orm';
import type { promoCodes } from '@/server/db/schema.js';
import type { PromoFunder } from '@/lib/enums/promo-funder';
import type { PromoKind } from '@/lib/enums/promo-kind';

export type PromoCode = InferSelectModel<typeof promoCodes>;

export type PromoRules =
  | { scope: { kind: 'all' }; eligibility: Eligibility }
  | { scope: { kind: 'deals'; dealIds: string[] }; eligibility: Eligibility }
  | {
      scope: { kind: 'categories'; categoryIds: string[] };
      eligibility: Eligibility;
    }
  | { scope: { kind: 'tags'; tagIds: string[] }; eligibility: Eligibility }
  | { scope: { kind: 'vendor'; vendorId: string }; eligibility: Eligibility };

export interface Eligibility {
  firstPurchaseOnly?: boolean;
  clubOnly?: boolean;
  userAllowlist?: string[];
}

export type PromoRejectReason =
  | 'NOT_FOUND'
  | 'INACTIVE'
  | 'NOT_YET_VALID'
  | 'EXPIRED'
  | 'OUT_OF_QUOTA'
  | 'USER_QUOTA_EXCEEDED'
  | 'SUBTOTAL_TOO_LOW'
  | 'SUBTOTAL_TOO_HIGH'
  | 'SCOPE_MISMATCH'
  | 'NEW_USERS_ONLY'
  | 'CLUB_ONLY'
  | 'NOT_IN_ALLOWLIST'
  | 'PLATFORM_FUND_INSUFFICIENT'
  | 'VENDOR_FUND_INSUFFICIENT';

export interface ResolvedCartLine {
  lineId: string; // cartItem.id at preview; purchase.id at reserve/finalize
  dealId: string;
  vendorId: string;
  categoryIds: string[]; // from deal
  tagIds: string[]; // from deal
  quantity: number;
  unitPriceAgorot: number;
  lineSubtotalAgorot: number; // unitPrice * quantity
  /** Quantity-break tiers for this line's SKU; empty = no qty-tier feature. */
  qtyTiers: { minQty: number; discountPercent: number }[];
}

export interface ResolvedCart {
  userId: string;
  lines: ResolvedCartLine[];
  totalAgorot: number;
}

export interface DiscountBreakdownLine {
  lineId: string;
  vendorId: string;
  amountAgorot: number;
}

export interface DiscountBreakdown {
  totalDiscountAgorot: number;
  perLine: DiscountBreakdownLine[];
  funder: PromoFunder;
  kind: PromoKind;
}

export interface PromoClaim {
  promoCodeId: string;
  codeSnapshot: string;
  discountAgorot: number; // amount applied to THIS purchase (per-PI slice)
  funder: PromoFunder;
  userId: string;
}

export type PreviewResult =
  | {
      ok: true;
      totalDiscountAgorot: number;
      perVendor: {
        vendorId: string;
        dealIds: string[];
        discountAgorot: number;
        funder: PromoFunder;
      }[];
      kind: PromoKind;
    }
  | { ok: false; reason: PromoRejectReason };
