/**
 * Database Models Index
 * Central file for initializing and exporting all database models
 * Sets up Sequelize instance and all model associations
 */

// Import Sequelize
const { Sequelize, DataTypes } = require('sequelize');
// Import database configuration
const dbConfig = require('../config/database');
// Import logger utility
const logger = require('../utils/logger');

// Get current environment
const env = process.env.NODE_ENV || 'development';
// Get configuration for current environment
const config = dbConfig[env];

// Initialize Sequelize instance
const sequelize = new Sequelize(
  config.database, // Database name
  config.username, // Database username
  config.password, // Database password
  {
    host: config.host, // Database host
    port: config.port, // Database port
    dialect: config.dialect, // Database dialect (mysql, postgres, etc.)
    logging: config.logging, // Logging configuration
    pool: config.pool, // Connection pool settings
  }
);

// Import and initialize all models (load all models first)
// Note: Load models in dependency order to satisfy foreign key constraints
const User = require('./User')(sequelize, DataTypes);
const Customer = require('./Customer')(sequelize, DataTypes);
const Product = require('./Product')(sequelize, DataTypes);
const Inventory = require('./Inventory')(sequelize, DataTypes);
const InventoryItem = require('./InventoryItem')(sequelize, DataTypes);
const InventoryMovement = require('./InventoryMovement')(sequelize, DataTypes);
const Vendor = require('./Vendor')(sequelize, DataTypes);
const PurchaseOrder = require('./PurchaseOrder')(sequelize, DataTypes);
const PurchaseOrderItem = require('./PurchaseOrderItem')(sequelize, DataTypes);
const GRN = require('./GRN')(sequelize, DataTypes);
const GRNItem = require('./GRNItem')(sequelize, DataTypes);
const BOM = require('./BOM')(sequelize, DataTypes);
const BOMItem = require('./BOMItem')(sequelize, DataTypes);
const ProductionOrder = require('./ProductionOrder')(sequelize, DataTypes);
const Sale = require('./Sale')(sequelize, DataTypes);
const SaleItem = require('./SaleItem')(sequelize, DataTypes);
const Payment = require('./Payment')(sequelize, DataTypes);
const FiscalReceipt = require('./FiscalReceipt')(sequelize, DataTypes);
const Return = require('./Return')(sequelize, DataTypes);
const ReturnItem = require('./ReturnItem')(sequelize, DataTypes);
const SystemLog = require('./SystemLog')(sequelize, DataTypes);
// Category models
const Category = require('./Category')(sequelize, DataTypes);
const ProductCategory = require('./ProductCategory')(sequelize, DataTypes);
// Pricing models
const PriceList = require('./PriceList')(sequelize, DataTypes);
const ProductPrice = require('./ProductPrice')(sequelize, DataTypes);
// Discount models
const Discount = require('./Discount')(sequelize, DataTypes);
const DiscountRule = require('./DiscountRule')(sequelize, DataTypes);
// Dimension-based inventory models
const RMInventoryPiece = require('./RMInventoryPiece')(sequelize, DataTypes);
const RMCuttingOperation = require('./RMCuttingOperation')(sequelize, DataTypes);

// Create models object to pass to associate methods
const models = {
  User,
  Customer,
  Product,
  Inventory,
  InventoryItem,
  InventoryMovement,
  Vendor,
  PurchaseOrder,
  PurchaseOrderItem,
  GRN,
  GRNItem,
  BOM,
  BOMItem,
  ProductionOrder,
  Sale,
  SaleItem,
  Payment,
  FiscalReceipt,
  Return,
  ReturnItem,
  SystemLog,
  // Category models
  Category,
  ProductCategory,
  // Pricing models
  PriceList,
  ProductPrice,
  // Discount models
  Discount,
  DiscountRule,
  // Dimension-based inventory models
  RMInventoryPiece,
  RMCuttingOperation,
};

// Define all model associations (call associate methods after all models are loaded)
// Note: Call associations in dependency order
User.associate(models);
// Category associations
Category.associate(models);
ProductCategory.associate(models);
// Pricing associations
PriceList.associate(models);
ProductPrice.associate(models);
// Discount associations
Discount.associate(models);
DiscountRule.associate(models);
// Dimension-based inventory associations
RMInventoryPiece.associate(models);
RMCuttingOperation.associate(models);
// Core model associations
Product.associate(models);
Customer.associate(models);
Inventory.associate(models);
InventoryItem.associate(models);
InventoryMovement.associate(models);
Vendor.associate(models);
PurchaseOrder.associate(models);
PurchaseOrderItem.associate(models);
GRN.associate(models);
GRNItem.associate(models);
BOM.associate(models);
BOMItem.associate(models);
ProductionOrder.associate(models);
Sale.associate(models);
SaleItem.associate(models);
Payment.associate(models);
FiscalReceipt.associate(models);
Return.associate(models);
ReturnItem.associate(models);
SystemLog.associate(models);

// Database object to export
const db = {
  sequelize, // Sequelize instance
  Sequelize, // Sequelize class
  // All models
  User,
  Customer,
  Product,
  Inventory,
  InventoryItem,
  InventoryMovement,
  Vendor,
  PurchaseOrder,
  PurchaseOrderItem,
  GRN,
  GRNItem,
  BOM,
  BOMItem,
  ProductionOrder,
  Sale,
  SaleItem,
  Payment,
  FiscalReceipt,
  Return,
  ReturnItem,
  SystemLog,
  // Category models
  Category,
  ProductCategory,
  // Pricing models
  PriceList,
  ProductPrice,
  // Discount models
  Discount,
  DiscountRule,
  // Dimension-based inventory models
  RMInventoryPiece,
  RMCuttingOperation,
};

// Export database object
module.exports = db;
