'use strict';
const {
  Model
} = require('sequelize');

module.exports = (sequelize, DataTypes) => {
  class Refund extends Model {
    static associate(models) {
      // Association with Return
      Refund.belongsTo(models.Return, {
        foreignKey: 'returnId',
        as: 'return'
      });
      
      // Association with Transaction
      Refund.belongsTo(models.Transaction, {
        foreignKey: 'transactionId',
        as: 'originalTransaction'
      });
      
      // Association with Customer
      Refund.belongsTo(models.Customer, {
        foreignKey: 'customerId',
        as: 'customer'
      });
      
      // Association with User (processor)
      Refund.belongsTo(models.User, {
        foreignKey: 'processedBy',
        as: 'processor'
      });
    }
  }
  
  Refund.init({
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true
    },
    returnId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: {
        model: 'Returns',
        key: 'id'
      }
    },
    transactionId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: {
        model: 'Transactions',
        key: 'id'
      }
    },
    customerId: {
      type: DataTypes.INTEGER,
      allowNull: true,
      references: {
        model: 'Customers',
        key: 'id'
      }
    },
    refundNumber: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true
    },
    amount: {
      type: DataTypes.DECIMAL(10, 2),
      allowNull: false
    },
    method: {
      type: DataTypes.ENUM('original_payment', 'cash', 'store_credit', 'exchange'),
      allowNull: false
    },
    status: {
      type: DataTypes.ENUM('pending', 'processing', 'completed', 'failed', 'cancelled'),
      defaultValue: 'pending'
    },
    paymentReference: {
      type: DataTypes.STRING,
      allowNull: true
    },
    storeCreditId: {
      type: DataTypes.INTEGER,
      allowNull: true,
      comment: 'Reference to store credit record if refund method is store_credit'
    },
    exchangeTransactionId: {
      type: DataTypes.INTEGER,
      allowNull: true,
      comment: 'Reference to new transaction if refund method is exchange'
    },
    processedBy: {
      type: DataTypes.INTEGER,
      allowNull: true,
      references: {
        model: 'Users',
        key: 'id'
      }
    },
    processedAt: {
      type: DataTypes.DATE,
      allowNull: true
    },
    failureReason: {
      type: DataTypes.TEXT,
      allowNull: true
    },
    notes: {
      type: DataTypes.TEXT,
      allowNull: true
    },
    metadata: {
      type: DataTypes.JSON,
      allowNull: true,
      comment: 'Additional payment gateway metadata'
    }
  }, {
    sequelize,
    modelName: 'Refund',
    tableName: 'Refunds',
    timestamps: true,
    indexes: [
      { fields: ['refundNumber'], unique: true },
      { fields: ['returnId'] },
      { fields: ['transactionId'] },
      { fields: ['customerId'] },
      { fields: ['status'] },
      { fields: ['processedAt'] }
    ],
    hooks: {
      beforeCreate: async (refund, options) => {
        // Generate unique refund number
        if (!refund.refundNumber) {
          const date = new Date();
          const year = date.getFullYear().toString().slice(-2);
          const month = (date.getMonth() + 1).toString().padStart(2, '0');
          const day = date.getDate().toString().padStart(2, '0');
          const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
          
          refund.refundNumber = `REF${year}${month}${day}${random}`;
        }
      }
    }
  });
  
  return Refund;
};