/**
 * Discount Model
 * Represents discounts and promotions
 */

module.exports = (sequelize, DataTypes) => {
  // Define Discount model
  const Discount = sequelize.define('Discount', {
    // Primary key
    id: {
      type: DataTypes.BIGINT, // Use BIGINT for large scale
      primaryKey: true, // Set as primary key
      autoIncrement: true, // Auto-increment ID
    },
    // Discount name
    name: {
      type: DataTypes.STRING(150), // Discount name with max length
      allowNull: false, // Name is required
      validate: {
        notEmpty: true, // Name cannot be empty string
        len: [1, 150], // Length validation
      },
    },
    // Discount code (unique identifier, e.g., "SUMMER2024")
    code: {
      type: DataTypes.STRING(50), // Discount code with max length
      allowNull: true, // Code is optional (some discounts may not have codes)
      unique: true, // Discount code must be unique if provided
      validate: {
        len: [0, 50], // Maximum length validation
      },
    },
    // Discount type (PERCENTAGE, FIXED_AMOUNT, BUY_X_GET_Y)
    discount_type: {
      type: DataTypes.ENUM('PERCENTAGE', 'FIXED_AMOUNT', 'BUY_X_GET_Y'), // Enum for discount type
      allowNull: false, // Discount type is required
      validate: {
        isIn: [['PERCENTAGE', 'FIXED_AMOUNT', 'BUY_X_GET_Y']], // Validate enum values
      },
    },
    // Discount value (percentage or fixed amount depending on type)
    discount_value: {
      type: DataTypes.DECIMAL(12, 2), // Decimal with 12 digits, 2 decimal places
      allowNull: false, // Discount value is required
      validate: {
        min: 0, // Discount value cannot be negative
      },
    },
    // Minimum purchase amount required for discount
    min_purchase_amount: {
      type: DataTypes.DECIMAL(12, 2), // Decimal with 12 digits, 2 decimal places
      defaultValue: 0, // Default minimum purchase is 0
      allowNull: false, // Minimum purchase amount is required
      validate: {
        min: 0, // Minimum purchase cannot be negative
      },
    },
    // Maximum discount amount (null for no limit)
    max_discount_amount: {
      type: DataTypes.DECIMAL(12, 2), // Decimal with 12 digits, 2 decimal places
      allowNull: true, // Maximum discount is optional (null for no limit)
      validate: {
        min: 0, // Maximum discount cannot be negative if provided
      },
    },
    // Effective start date
    effective_from: {
      type: DataTypes.DATE, // Start date
      allowNull: false, // Effective from date is required
      defaultValue: DataTypes.NOW, // Default to current date
    },
    // Effective end date (null for no expiration)
    effective_to: {
      type: DataTypes.DATE, // End date
      allowNull: true, // Effective to date is optional (null for no expiration)
    },
    // Maximum number of uses per customer (null for unlimited)
    max_uses_per_customer: {
      type: DataTypes.INTEGER, // Integer for maximum uses
      allowNull: true, // Maximum uses is optional (null for unlimited)
      validate: {
        min: 1, // Maximum uses must be at least 1 if provided
      },
    },
    // Total maximum uses (null for unlimited)
    max_total_uses: {
      type: DataTypes.INTEGER, // Integer for total maximum uses
      allowNull: true, // Total maximum uses is optional (null for unlimited)
      validate: {
        min: 1, // Total maximum uses must be at least 1 if provided
      },
    },
    // Current usage count
    usage_count: {
      type: DataTypes.INTEGER, // Integer for usage count
      defaultValue: 0, // Default usage count is 0
      allowNull: false, // Usage count is required
      validate: {
        min: 0, // Usage count cannot be negative
      },
    },
    // Whether this discount is active
    active: {
      type: DataTypes.BOOLEAN, // Boolean for active status
      defaultValue: true, // Default to active
      allowNull: false, // Active status is required
    },
    // Description of the discount
    description: {
      type: DataTypes.TEXT, // Text field for description
      allowNull: true, // Description is optional
    },
  }, {
    // Model options
    tableName: 'discounts', // Explicit table name
    underscored: true, // Use snake_case for database columns
    timestamps: true, // Enable createdAt and updatedAt timestamps
    createdAt: 'created_at', // Map createdAt to created_at column
    updatedAt: 'updated_at', // Map updatedAt to updated_at column
    indexes: [
      // Unique index on code (already enforced by unique constraint, where not null)
      {
        unique: true, // Unique index
        fields: ['code'], // Index on code field
        where: {
          code: {
            [sequelize.Sequelize.Op.ne]: null, // Only index non-null codes
          },
        },
      },
      // Index on discount_type for filtering
      {
        fields: ['discount_type'], // Index on discount_type field
      },
      // Index on effective_from for date-based queries
      {
        fields: ['effective_from'], // Index on effective_from field
      },
      // Index on effective_to for date-based queries
      {
        fields: ['effective_to'], // Index on effective_to field
      },
      // Index on active for filtering
      {
        fields: ['active'], // Index on active field
      },
    ],
  });

  // Define model associations
  Discount.associate = (models) => {
    // Discount has many DiscountRules (one-to-many relationship)
    Discount.hasMany(models.DiscountRule, {
      foreignKey: 'discount_id', // Foreign key in DiscountRules table
      as: 'rules', // Alias for association
      onDelete: 'CASCADE', // Cascade delete rules when discount is deleted
    });
  };

  // Return Discount model
  return Discount;
};

