/**
 * Pricing Rule Model
 * Defines pricing rules (discounts, surcharges, minimums, bundles) that are evaluated
 * based on selected items and billing cycle. Rules are applied in priority order.
 */

import mongoose, { Schema, Document } from 'mongoose';

export type PricingRuleType = 'discount' | 'surcharge' | 'minimum' | 'bundle';
export type PricingRuleEffectType = 'percentage' | 'fixed_amount';
export type PricingRuleApplyTo = 'total' | 'category' | 'item';
export type PricingRuleStacking = 'exclusive' | 'stackable';

export interface IPricingRuleCondition {
  categorySlugs?: string[];
  itemSlugs?: string[];
  minItemsSelected?: number;
  billingCycle?: string[];
}

export interface IPricingRuleEffect {
  type: PricingRuleEffectType;
  value: number;
  applyTo: PricingRuleApplyTo;
  targetCategorySlug?: string;
  targetItemSlug?: string;
}

export interface IPricingRule extends Document {
  slug: string;
  name: string;
  description?: string;
  ruleType: PricingRuleType;
  conditions: IPricingRuleCondition;
  effect: IPricingRuleEffect;
  priority: number;
  stackingBehavior: PricingRuleStacking;
  isActive: boolean;
  validFrom?: Date;
  validUntil?: Date;
  createdAt: Date;
  updatedAt: Date;
}

const PricingRuleConditionSchema = new Schema<IPricingRuleCondition>({
  categorySlugs: [{ type: String, trim: true, lowercase: true }],
  itemSlugs: [{ type: String, trim: true, lowercase: true }],
  minItemsSelected: { type: Number, min: 0 },
  billingCycle: [{ type: String }],
}, { _id: false });

const PricingRuleEffectSchema = new Schema<IPricingRuleEffect>({
  type: {
    type: String,
    enum: ['percentage', 'fixed_amount'],
    required: true,
  },
  value: {
    type: Number,
    required: true,
    min: 0,
  },
  applyTo: {
    type: String,
    enum: ['total', 'category', 'item'],
    required: true,
  },
  targetCategorySlug: { type: String, trim: true, lowercase: true },
  targetItemSlug: { type: String, trim: true, lowercase: true },
}, { _id: false });

const PricingRuleSchema = new Schema<IPricingRule>({
  slug: {
    type: String,
    required: [true, 'Rule slug is required'],
    unique: true,
    trim: true,
    lowercase: true,
    match: [/^[a-z0-9_]+$/, 'Slug must contain only lowercase letters, numbers, and underscores'],
  },
  name: {
    type: String,
    required: [true, 'Rule name is required'],
    trim: true,
    maxlength: [150, 'Rule name cannot exceed 150 characters'],
  },
  description: {
    type: String,
    trim: true,
    maxlength: [1000, 'Description cannot exceed 1000 characters'],
  },
  ruleType: {
    type: String,
    enum: ['discount', 'surcharge', 'minimum', 'bundle'],
    required: true,
  },
  conditions: {
    type: PricingRuleConditionSchema,
    default: () => ({}),
  },
  effect: {
    type: PricingRuleEffectSchema,
    required: true,
  },
  priority: {
    type: Number,
    default: 100,
    min: 0,
  },
  stackingBehavior: {
    type: String,
    enum: ['exclusive', 'stackable'],
    default: 'stackable',
  },
  isActive: {
    type: Boolean,
    default: true,
  },
  validFrom: {
    type: Date,
    default: null,
  },
  validUntil: {
    type: Date,
    default: null,
  },
}, {
  timestamps: true,
  toJSON: { virtuals: true },
  toObject: { virtuals: true },
});

PricingRuleSchema.index({ slug: 1 }, { unique: true });
PricingRuleSchema.index({ isActive: 1, priority: 1 });
PricingRuleSchema.index({ ruleType: 1 });

export const PricingRule = mongoose.models.PricingRule || mongoose.model<IPricingRule>('PricingRule', PricingRuleSchema);