/**
 * Fiscal Receipt Model
 * Represents KRA eTIMS fiscal receipts (decoupled from sales)
 */

module.exports = (sequelize, DataTypes) => {
  // Define FiscalReceipt model
  const FiscalReceipt = sequelize.define('FiscalReceipt', {
    // Primary key
    id: {
      type: DataTypes.BIGINT, // Use BIGINT for large scale
      primaryKey: true, // Set as primary key
      autoIncrement: true, // Auto-increment ID
    },
    // Foreign key to Sale (decoupled - sale can exist without fiscal receipt)
    sale_id: {
      type: DataTypes.BIGINT, // Match Sale ID type
      allowNull: true, // Sale ID is optional (for credit notes not linked to sale)
      references: {
        model: 'sales', // Reference to sales table
        key: 'id', // Reference to id column
      },
      onUpdate: 'CASCADE', // Cascade update on sale update
    },
    // Foreign key to Return (for credit notes) - ENHANCEMENT
    return_id: {
      type: DataTypes.BIGINT, // Match Return ID type
      allowNull: true, // Return ID is optional (only for credit notes)
      references: {
        model: 'returns', // Reference to returns table
        key: 'id', // Reference to id column
      },
      onUpdate: 'CASCADE', // Cascade update on return update
    },
    // Receipt category (Sale or Credit Note)
    receipt_category: {
      type: DataTypes.ENUM('SALE', 'CREDIT_NOTE'), // Enum for receipt category
      allowNull: false, // Receipt category is required
      validate: {
        isIn: [['SALE', 'CREDIT_NOTE']], // Validate enum values
      },
    },
    // Receipt type (B2C or B2B)
    receipt_type: {
      type: DataTypes.ENUM('B2C', 'B2B'), // Enum for receipt type
      allowNull: false, // Receipt type is required
      validate: {
        isIn: [['B2C', 'B2B']], // Validate enum values
      },
    },
    // Customer PIN (optional - stored only in fiscal record, not in customer table)
    customer_pin: {
      type: DataTypes.STRING(20), // Customer PIN with max length
      allowNull: true, // Customer PIN is optional
      validate: {
        len: [0, 20], // Maximum length validation
      },
    },
    // KRA receipt number (from KRA eTIMS system)
    kra_receipt_no: {
      type: DataTypes.STRING(100), // KRA receipt number with max length
      allowNull: true, // KRA receipt number is optional (only set after fiscalisation)
      validate: {
        len: [0, 100], // Maximum length validation
      },
    },
    // QR code content (from KRA eTIMS system)
    qr_code: {
      type: DataTypes.TEXT, // Text field for QR code content
      allowNull: true, // QR code is optional (only set after fiscalisation)
    },
    // Fiscal status
    fiscal_status: {
      type: DataTypes.ENUM('PENDING', 'FISCALISED', 'FAILED'), // Enum for fiscal status
      defaultValue: 'PENDING', // Default status is PENDING
      allowNull: false, // Fiscal status is required
      validate: {
        isIn: [['PENDING', 'FISCALISED', 'FAILED']], // Validate enum values
      },
    },
    // Date and time when fiscal receipt was fiscalised
    fiscalised_at: {
      type: DataTypes.DATE, // Date and time
      allowNull: true, // Fiscalised date is optional (only set when fiscalised)
    },
  }, {
    // Model options
    tableName: 'fiscal_receipts', // 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: false, // No updatedAt for fiscal receipts (immutable after creation)
    indexes: [
      // Index on sale_id for faster lookups
      {
        fields: ['sale_id'], // Index on sale_id field
      },
      // Index on return_id for faster lookups (ENHANCEMENT)
      {
        fields: ['return_id'], // Index on return_id field
      },
      // Index on receipt_category for filtering
      {
        fields: ['receipt_category'], // Index on receipt_category field
      },
      // Index on receipt_type for filtering
      {
        fields: ['receipt_type'], // Index on receipt_type field
      },
      // Index on fiscal_status for filtering
      {
        fields: ['fiscal_status'], // Index on fiscal_status field
      },
      // Index on kra_receipt_no for lookup (unique where not null)
      {
        unique: true, // Unique index
        fields: ['kra_receipt_no'], // Index on kra_receipt_no field
        where: {
          kra_receipt_no: {
            [sequelize.Sequelize.Op.ne]: null, // Only index non-null receipt numbers
          },
        },
      },
      // Index on fiscalised_at for date-based queries
      {
        fields: ['fiscalised_at'], // Index on fiscalised_at field
      },
    ],
  });

  // Define model associations
  FiscalReceipt.associate = (models) => {
    // FiscalReceipt belongs to Sale (many-to-one relationship, optional)
    FiscalReceipt.belongsTo(models.Sale, {
      foreignKey: 'sale_id', // Foreign key in FiscalReceipt table
      as: 'sale', // Alias for association
    });
    
    // FiscalReceipt belongs to Return (many-to-one relationship, optional) - ENHANCEMENT
    FiscalReceipt.belongsTo(models.Return, {
      foreignKey: 'return_id', // Foreign key in FiscalReceipt table
      as: 'return', // Alias for association
    });
  };

  // Return FiscalReceipt model
  return FiscalReceipt;
};

