import { CheckoutSession, TCheckoutSession } from './checkout-session';
import { Coupon, TCoupon } from './coupon';
import { Customer, TCustomer } from './customer';
import { Discount, TDiscount } from './discount';
import { Event, TEvent } from './event';
import { Invoice, TInvoice } from './invoice';
import { InvoiceItem, TInvoiceItem } from './invoice-item';
import { Job } from './job';
import { Lock } from './lock';
import { PaymentCurrency, TPaymentCurrency } from './payment-currency';
import { PaymentIntent, TPaymentIntent } from './payment-intent';
import { PaymentLink, TPaymentLink } from './payment-link';
import { PaymentMethod, TPaymentMethod } from './payment-method';
import { PaymentStat } from './payment-stat';
import { Payout, TPayout } from './payout';
import { Price, TPrice } from './price';
import { PricingTable, TPricingTable } from './pricing-table';
import { Product, TProduct } from './product';
import { PromotionCode, TPromotionCode } from './promotion-code';
import { Refund, TRefund } from './refund';
import { SetupIntent, TSetupIntent } from './setup-intent';
import { Subscription, TSubscription } from './subscription';
import { SubscriptionItem, TSubscriptionItem } from './subscription-item';
import { SubscriptionSchedule } from './subscription-schedule';
import type { LineItem, PriceCurrency, PricingTableItem } from './types';
import { TUsageRecord, UsageRecord } from './usage-record';
import { TWebhookAttempt, WebhookAttempt } from './webhook-attempt';
import { TWebhookEndpoint, WebhookEndpoint } from './webhook-endpoint';
import { Setting } from './setting';
import { CreditGrant, TCreditGrant } from './credit-grant';
import { CreditTransaction, TCreditTransaction } from './credit-transaction';
import { Meter, TMeter } from './meter';
import { MeterEvent, TMeterEvent } from './meter-event';
import { AutoRechargeConfig } from './auto-recharge-config';
import { ProductVendor } from './product-vendor';
import { TaxRate } from './tax-rate';
import { ExchangeRateProvider } from './exchange-rate-provider';
import { PriceQuote } from './price-quote';
import { ArchiveMetadata } from './archive-metadata';
import { ArchiveLock } from './archive-lock';
import { RevenueSnapshot } from './revenue-snapshot';

const models = {
  CheckoutSession,
  Coupon,
  Customer,
  Discount,
  Event,
  Invoice,
  InvoiceItem,
  PaymentCurrency,
  PaymentIntent,
  PaymentLink,
  PaymentStat,
  Payout,
  PaymentMethod,
  Price,
  PricingTable,
  Product,
  PromotionCode,
  Refund,
  SetupIntent,
  Subscription,
  SubscriptionItem,
  SubscriptionSchedule,
  UsageRecord,
  WebhookEndpoint,
  WebhookAttempt,
  Job,
  Lock,
  Setting,
  CreditGrant,
  CreditTransaction,
  Meter,
  MeterEvent,
  AutoRechargeConfig,
  ProductVendor,
  TaxRate,
  ExchangeRateProvider,
  PriceQuote,
  ArchiveMetadata,
  ArchiveLock,
  RevenueSnapshot,
};

export function initialize(sequelize: any) {
  Object.values(models).forEach((model) => {
    model.initialize(sequelize);
  });
  Object.values(models).forEach((model) => {
    if ('associate' in model) {
      (model as any).associate(models);
    }
  });
}

export default models;

export * from './checkout-session';
export * from './coupon';
export * from './customer';
export * from './discount';
export * from './event';
export * from './invoice';
export * from './invoice-item';
export * from './job';
export * from './lock';
export * from './payment-currency';
export * from './payment-intent';
export * from './payment-link';
export * from './payment-method';
export * from './payment-stat';
export * from './payout';
export * from './price';
export * from './pricing-table';
export * from './product';
export * from './promotion-code';
export * from './refund';
export * from './setup-intent';
export * from './subscription';
export * from './subscription-item';
export * from './subscription-schedule';
export * from './usage-record';
export * from './webhook-attempt';
export * from './webhook-endpoint';
export * from './types';
export * from './setting';
export * from './credit-grant';
export * from './credit-transaction';
export * from './meter';
export * from './meter-event';
export * from './auto-recharge-config';
export * from './product-vendor';
export * from './tax-rate';
export * from './exchange-rate-provider';
export * from './price-quote';
export * from './archive-metadata';
export * from './archive-lock';
export * from './revenue-snapshot';

export type TPriceExpanded = TPrice & {
  object: 'price';
  product: TProduct;
  currency: TPaymentCurrency;
  upsell?: {
    upsells_to: TPriceExpanded;
    upsells_to_id: string;
  };
  meter?: TMeter;
  currency_options?: (PriceCurrency & { currency?: TPaymentCurrency })[];
};

export type TLineItemExpanded = LineItem & {
  price: TPriceExpanded;
  upsell_price: TPriceExpanded;
  metadata?: Record<string, any>;
  [key: string]: any;
};

export type TProductExpanded = TProduct & {
  object: 'price';
  prices: TPriceExpanded[];
  default_price: TPriceExpanded;
  cross_sell?: {
    cross_sells_to: TProductExpanded;
    cross_sells_to_id: string;
  };
};

export type TPaymentLinkExpanded = TPaymentLink & { object: 'payment_link'; line_items: TLineItemExpanded[] };

export type TPaymentMethodExpanded = TPaymentMethod & {
  object: 'payment_method';
  payment_currencies: TPaymentCurrency[];
};

export type TPaymentCurrencyExpanded = TPaymentCurrency & {
  object: 'payment_currency';
  paymentMethod: TPaymentMethod;
};

export type TCheckoutSessionExpanded = TCheckoutSession & {
  object: 'checkout_session';
  line_items: TLineItemExpanded[];
  payment_link?: TPaymentLink;
  payment_intent?: TPaymentIntent;
  subscription?: TSubscription;
  customer?: TCustomer;
  subscriptions?: TSubscription[];
};

export type TPaymentIntentExpanded = TPaymentIntent & {
  object: 'payment_intent';
  customer: TCustomer;
  paymentCurrency: TPaymentCurrency;
  paymentMethod: TPaymentMethod;
  checkoutSession?: TCheckoutSession;
  subscription?: TSubscription;
  invoice?: TInvoice;
  refund?: {
    amount: string;
    totalAmount: string;
  };
};

export type TSubscriptionExpanded = TSubscription & {
  object: 'subscription';
  customer: TCustomer;
  paymentCurrency: TPaymentCurrency;
  paymentMethod: TPaymentMethod;
  items: TSubscriptionItemExpanded[];
  serviceType: 'credit' | 'standard';
};

export type TSubscriptionItemExpanded = TSubscriptionItem & {
  object: 'subscription';
  price: TPriceExpanded;
};

export type TCustomerExpanded = TCustomer & {
  object: 'subscription';
  payments: TPaymentIntent[];
  subscriptions: TSubscription[];
  invoices: TInvoice[];
};

export type TInvoiceExpanded = TInvoice & {
  object: 'invoice';
  customer: TCustomer;
  paymentCurrency: TPaymentCurrency;
  paymentMethod: TPaymentMethod;
  paymentIntent: TPaymentIntent;
  subscription?: TSubscription;
  lines: TInvoiceItemExpanded[];
};

export type TInvoiceItemExpanded = TInvoiceItem & {
  object: 'invoice_item';
  price: TPriceExpanded;
};

export type TEventExpanded = TEvent & {
  object: 'event';
  webhooks: TWebhookEndpointExpanded[];
};

export type TWebhookAttemptExpanded = TWebhookAttempt & {
  object: 'webhook_attempt';
  event: TEvent;
  endpoint: TWebhookEndpoint;
};

export type TWebhookEndpointExpanded = TWebhookEndpoint & {
  object: 'webhook_endpoint';
  attempts: TWebhookAttemptExpanded[];
};

export type TUsageRecordExpanded = TUsageRecord & {
  object: 'usage_record';
};

export type TUsageRecordSummary = {
  object: 'usage_record_summary';
  livemode: boolean;
  invoice_id: string;
  subscription_item_id: string;
  total_usage: number;
  period: {
    start: number;
    end: number;
  };
};

export type TSetupIntentExpanded = TSetupIntent & {
  object: 'setup_intent';
};

export type TPricingTableItem = PricingTableItem & {
  object: 'pricing_table_item';
  price: TPrice;
  product: TProduct;
  is_selected?: boolean;
  is_disabled?: boolean;
};

export type TPricingTableExpanded = TPricingTable & {
  object: 'pricing_table';
  items: TPricingTableItem[];
  currency: TPaymentCurrency;
};

export type TRefundExpanded = TRefund & {
  object: 'refund';
  customer: TCustomer;
  paymentCurrency: TPaymentCurrency;
  paymentMethod: TPaymentMethod;
  paymentIntent: TPaymentIntent;
  invoice?: TInvoice;
  subscription?: TSubscription;
};

export type TPayoutExpanded = TPayout & {
  object: 'price';
  paymentCurrency: TPaymentCurrency;
  paymentMethod: TPaymentMethod;
  paymentIntent: TPaymentIntent;
  customer: TCustomer;
};

export type TCreditGrantExpanded = TCreditGrant & {
  object: 'credit_grant';
  customer: TCustomer;
  paymentCurrency: TPaymentCurrency;
  paymentMethod: TPaymentMethod;
  items?: TLineItemExpanded[];
};

export type TCreditTransactionExpanded = TCreditTransaction & {
  object: 'credit_transaction';
  customer: TCustomer;
  paymentCurrency: TPaymentCurrency;
  paymentMethod?: TPaymentMethod;
  creditGrant: TCreditGrant & { paymentCurrency?: TPaymentCurrency };
  meter: TMeter;
  subscription: TSubscription;
  meterEvent?: TMeterEvent;
};

export type TMeterEventExpanded = TMeterEvent & {
  object: 'meter_event';
  customer: Customer;
  subscription?: TSubscription;
  meter: TMeter;
  paymentCurrency: TPaymentCurrency;
};

export type CreditGrantSummary = {
  paymentCurrency: TPaymentCurrency;
  totalAmount: string;
  remainingAmount: string;
  grantCount: number;
};

export type TCouponExpanded = TCoupon & {
  object: 'coupon';
  applied_products?: TProduct[];
  promotion_codes?: TPromotionCode[];
  currency?: TPaymentCurrency;
};

export type TPromotionCodeExpanded = TPromotionCode & {
  object: 'promotion_code';
  coupon?: TCoupon;
};

export type TDiscountExpanded = TDiscount & {
  object: 'discount';
  coupon?: TCouponExpanded;
  promotionCode?: TPromotionCodeExpanded;
};
