import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  OneToMany,
  Index,
} from 'typeorm';
import { CouponRedemption } from './coupon-redemption.entity';

export enum CouponStatus {
  ACTIVE = 'active',
  INACTIVE = 'inactive',
  EXPIRED = 'expired',
  DEPLETED = 'depleted',
}

export enum CouponType {
  PERCENTAGE = 'percentage',
  FIXED_AMOUNT = 'fixed_amount',
  FREE_SHIPPING = 'free_shipping',
  FREE_PRODUCT = 'free_product',
}

export enum CouponScope {
  ORDER = 'order',
  PRODUCT = 'product',
  CATEGORY = 'category',
  SHIPPING = 'shipping',
}

@Entity('coupons', { schema: 'retail' })
@Index(['tenantId', 'code'], { unique: true })
@Index(['tenantId', 'status', 'validFrom', 'validUntil'])
@Index(['tenantId', 'campaignId'])
export class Coupon {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ name: 'tenant_id', type: 'uuid' })
  @Index()
  tenantId: string;

  @Column({ length: 50, unique: true })
  code: string;

  @Column({ length: 100 })
  name: string;

  @Column({ type: 'text', nullable: true })
  description: string;

  @Column({
    type: 'enum',
    enum: CouponType,
  })
  type: CouponType;

  @Column({
    type: 'enum',
    enum: CouponScope,
    default: CouponScope.ORDER,
  })
  scope: CouponScope;

  @Column({
    type: 'enum',
    enum: CouponStatus,
    default: CouponStatus.ACTIVE,
  })
  status: CouponStatus;

  // Discount value
  @Column({ name: 'discount_percent', type: 'decimal', precision: 5, scale: 2, nullable: true })
  discountPercent: number;

  @Column({ name: 'discount_amount', type: 'decimal', precision: 15, scale: 2, nullable: true })
  discountAmount: number;

  @Column({ name: 'max_discount', type: 'decimal', precision: 15, scale: 2, nullable: true })
  maxDiscount: number;

  // Free product
  @Column({ name: 'free_product_id', type: 'uuid', nullable: true })
  freeProductId: string;

  @Column({ name: 'free_product_quantity', type: 'int', default: 1 })
  freeProductQuantity: number;

  // Validity
  @Column({ name: 'valid_from', type: 'timestamp with time zone' })
  validFrom: Date;

  @Column({ name: 'valid_until', type: 'timestamp with time zone', nullable: true })
  validUntil: Date;

  // Usage limits
  @Column({ name: 'max_uses', type: 'int', nullable: true })
  maxUses: number;

  @Column({ name: 'max_uses_per_customer', type: 'int', default: 1 })
  maxUsesPerCustomer: number;

  @Column({ name: 'current_uses', type: 'int', default: 0 })
  currentUses: number;

  // Minimum requirements
  @Column({ name: 'min_order_amount', type: 'decimal', precision: 15, scale: 2, nullable: true })
  minOrderAmount: number;

  @Column({ name: 'min_items', type: 'int', nullable: true })
  minItems: number;

  // Scope restrictions
  @Column({ name: 'applies_to_categories', type: 'jsonb', nullable: true })
  appliesToCategories: string[];

  @Column({ name: 'applies_to_products', type: 'jsonb', nullable: true })
  appliesToProducts: string[];

  @Column({ name: 'excluded_products', type: 'jsonb', nullable: true })
  excludedProducts: string[];

  @Column({ name: 'included_branches', type: 'jsonb', nullable: true })
  includedBranches: string[];

  // Customer restrictions
  @Column({ name: 'customer_specific', type: 'boolean', default: false })
  customerSpecific: boolean;

  @Column({ name: 'allowed_customers', type: 'jsonb', nullable: true })
  allowedCustomers: string[];

  @Column({ name: 'customer_levels', type: 'jsonb', nullable: true })
  customerLevels: string[];

  @Column({ name: 'new_customers_only', type: 'boolean', default: false })
  newCustomersOnly: boolean;

  @Column({ name: 'first_order_only', type: 'boolean', default: false })
  firstOrderOnly: boolean;

  // Campaign
  @Column({ name: 'campaign_id', type: 'uuid', nullable: true })
  campaignId: string;

  @Column({ name: 'campaign_name', length: 100, nullable: true })
  campaignName: string;

  // Stackability
  @Column({ name: 'stackable_with_promotions', type: 'boolean', default: false })
  stackableWithPromotions: boolean;

  @Column({ name: 'stackable_with_coupons', type: 'boolean', default: false })
  stackableWithCoupons: boolean;

  // Channels
  @Column({ name: 'pos_enabled', type: 'boolean', default: true })
  posEnabled: boolean;

  @Column({ name: 'ecommerce_enabled', type: 'boolean', default: true })
  ecommerceEnabled: boolean;

  // Distribution
  @Column({ name: 'is_single_use', type: 'boolean', default: false })
  isSingleUse: boolean;

  @Column({ name: 'auto_apply', type: 'boolean', default: false })
  autoApply: boolean;

  @Column({ name: 'public_visible', type: 'boolean', default: false })
  publicVisible: boolean;

  // Terms
  @Column({ name: 'terms_and_conditions', type: 'text', nullable: true })
  termsAndConditions: string;

  // Metadata
  @Column({ type: 'jsonb', nullable: true })
  metadata: Record<string, any>;

  @CreateDateColumn({ name: 'created_at' })
  createdAt: Date;

  @UpdateDateColumn({ name: 'updated_at' })
  updatedAt: Date;

  @Column({ name: 'created_by', type: 'uuid', nullable: true })
  createdBy: string;

  // Relations
  @OneToMany(() => CouponRedemption, (redemption) => redemption.coupon)
  redemptions: CouponRedemption[];
}
