const db = require('../models');

/**
 * Create approval transactions for a submitted transaction
 */
async function createApprovalTransactions({ companyId, moduleName, transactionId, transactionNumber, transactionAmount, userId }) {
  // Get approval masters for this module
  const approvalMasters = await db.ApprovalMaster.findAll({
    where: {
      company_id: companyId,
      module_name: moduleName,
      status: 'ACTIVE',
      is_required: true
    },
    order: [['sequence', 'ASC'], ['approval_level', 'ASC']]
  });

  if (approvalMasters.length === 0) {
    // No approval required - auto approve
    await updateTransactionStatus(moduleName, transactionId, 'APPROVED', userId);
    return [];
  }

  // Filter by amount thresholds if provided
  const applicableApprovals = approvalMasters.filter(am => {
    if (transactionAmount !== undefined && transactionAmount !== null) {
      const amount = parseFloat(transactionAmount);
      if (am.min_amount && amount < parseFloat(am.min_amount)) {
        return false;
      }
      if (am.max_amount && amount > parseFloat(am.max_amount)) {
        return false;
      }
    }
    return true;
  });

  if (applicableApprovals.length === 0) {
    // No approval required for this amount - auto approve
    await updateTransactionStatus(moduleName, transactionId, 'APPROVED', userId);
    return [];
  }

  // Create approval transactions
  const approvalTransactions = await Promise.all(
    applicableApprovals.map((am, index) => {
      return db.ApprovalTransaction.create({
        company_id: companyId,
        approval_master_id: am.id,
        module_name: moduleName,
        transaction_id: transactionId,
        transaction_number: transactionNumber,
        approval_level: am.approval_level,
        status: 'PENDING',
        approver_role_id: am.approver_role_id,
        approver_user_id: am.approver_user_id,
        transaction_amount: transactionAmount,
        created_by: userId,
        updated_by: userId
      });
    })
  );

  // Create notifications for approval requests
  if (approvalTransactions.length > 0) {
    try {
      const notificationService = require('./notificationService');
      await notificationService.createApprovalRequestNotifications({
        companyId,
        moduleName,
        transactionId,
        transactionNumber,
        approvalTransactions,
        createdBy: userId
      });
    } catch (error) {
      console.error('Error creating approval request notifications:', error);
      // Don't fail the approval creation if notification fails
    }
  }

  return approvalTransactions;
}

/**
 * Update transaction status based on approval result
 */
async function updateTransactionStatus(moduleName, transactionId, status, userId) {
  switch (moduleName) {
    case 'PURCHASE_ORDER':
      const po = await db.PurchaseOrder.findByPk(transactionId);
      if (po) {
        if (status === 'APPROVED') {
          await po.update({
            status: 'APPROVED',
            approved_at: new Date(),
            approved_by: userId,
            updated_by: userId
          });
        } else if (status === 'REJECTED') {
          await po.update({
            status: 'DRAFT',
            updated_by: userId
          });
        }
      }
      break;
    case 'SALES_ORDER':
      const so = await db.SalesOrder.findByPk(transactionId);
      if (so) {
        if (status === 'APPROVED') {
          await so.update({
            status: 'APPROVED',
            approved_at: new Date(),
            approved_by: userId,
            updated_by: userId
          });
        } else if (status === 'REJECTED') {
          await so.update({
            status: 'DRAFT',
            updated_by: userId
          });
        }
      }
      break;
    case 'CUSTOMER_PO':
      const cpo = await db.CustomerPO.findByPk(transactionId);
      if (cpo) {
        if (status === 'APPROVED') {
          await cpo.update({
            status: 'APPROVED',
            updated_by: userId
          });
        } else if (status === 'REJECTED') {
          await cpo.update({
            status: 'DRAFT',
            updated_by: userId
          });
        }
      }
      break;
  }
}

/**
 * Check if all approvals are completed
 */
async function checkAllApprovalsComplete(moduleName, transactionId) {
  const pendingApprovals = await db.ApprovalTransaction.count({
    where: {
      module_name: moduleName,
      transaction_id: transactionId,
      status: 'PENDING'
    }
  });

  return pendingApprovals === 0;
}

/**
 * Get next pending approval
 */
async function getNextPendingApproval(moduleName, transactionId) {
  return await db.ApprovalTransaction.findOne({
    where: {
      module_name: moduleName,
      transaction_id: transactionId,
      status: 'PENDING'
    },
    include: [
      { model: db.ApprovalMaster, as: 'approvalMaster' }
    ],
    order: [['approval_level', 'ASC']]
  });
}

module.exports = {
  createApprovalTransactions,
  updateTransactionStatus,
  checkAllApprovalsComplete,
  getNextPendingApproval
};

