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

/**
 * Create a notification for a user
 */
async function createNotification({ companyId, userId, type, moduleName, transactionId, transactionNumber, title, message, link, priority = 'MEDIUM', createdBy = null }) {
  try {
    const notification = await db.Notification.create({
      company_id: companyId,
      user_id: userId,
      type,
      module_name: moduleName || null,
      transaction_id: transactionId || null,
      transaction_number: transactionNumber || null,
      title,
      message,
      link: link || null,
      priority,
      created_by: createdBy,
      updated_by: createdBy
    });
    return notification;
  } catch (error) {
    console.error('Error creating notification:', error);
    throw error;
  }
}

/**
 * Create notifications for approval request
 */
async function createApprovalRequestNotifications({ companyId, moduleName, transactionId, transactionNumber, approvalTransactions, createdBy }) {
  const notifications = [];
  
  for (const approvalTransaction of approvalTransactions) {
    // Get approvers (users with the role or specific user)
    let approverUserIds = [];
    
    if (approvalTransaction.approver_user_id) {
      // Specific user
      approverUserIds = [approvalTransaction.approver_user_id];
    } else if (approvalTransaction.approver_role_id) {
      // All users with this role
      const userRoles = await db.UserRole.findAll({
        where: { 
          role_id: approvalTransaction.approver_role_id,
          status: 'ACTIVE'
        },
        include: [{ 
          model: db.User, 
          as: 'user',
          where: { status: 'ACTIVE' },
          required: true
        }]
      });
      approverUserIds = userRoles.map(ur => ur.user_id || ur.user?.id).filter(id => id);
    }
    
    // Create notification for each approver
    for (const approverUserId of approverUserIds) {
      const moduleDisplayName = moduleName.replace(/([A-Z])/g, ' $1').trim();
      const notification = await createNotification({
        companyId,
        userId: approverUserId,
        type: 'APPROVAL_REQUEST',
        moduleName,
        transactionId,
        transactionNumber,
        title: `Approval Request: ${moduleDisplayName}`,
        message: `${moduleDisplayName} ${transactionNumber || `#${transactionId}`} requires your approval at level ${approvalTransaction.approval_level}.`,
        link: getApprovalLink(moduleName, transactionId),
        priority: 'HIGH',
        createdBy
      });
      notifications.push(notification);
    }
  }
  
  return notifications;
}

/**
 * Create notification for approval approved
 */
async function createApprovalApprovedNotification({ companyId, moduleName, transactionId, transactionNumber, approvedBy, approverUserId, transactionCreatorId }) {
  const moduleDisplayName = moduleName.replace(/([A-Z])/g, ' $1').trim();
  
  // Notify the creator of the transaction
  if (transactionCreatorId && transactionCreatorId !== approverUserId) {
    await createNotification({
      companyId,
      userId: transactionCreatorId,
      type: 'APPROVAL_APPROVED',
      moduleName,
      transactionId,
      transactionNumber,
      title: `Approval Approved: ${moduleDisplayName}`,
      message: `${moduleDisplayName} ${transactionNumber || `#${transactionId}`} has been approved.`,
      link: getTransactionLink(moduleName, transactionId),
      priority: 'MEDIUM',
      createdBy: approvedBy
    });
  }
}

/**
 * Create notification for approval rejected
 */
async function createApprovalRejectedNotification({ companyId, moduleName, transactionId, transactionNumber, rejectedBy, approverUserId, transactionCreatorId, rejectionReason }) {
  const moduleDisplayName = moduleName.replace(/([A-Z])/g, ' $1').trim();
  
  // Notify the creator of the transaction
  if (transactionCreatorId && transactionCreatorId !== approverUserId) {
    await createNotification({
      companyId,
      userId: transactionCreatorId,
      type: 'APPROVAL_REJECTED',
      moduleName,
      transactionId,
      transactionNumber,
      title: `Approval Rejected: ${moduleDisplayName}`,
      message: `${moduleDisplayName} ${transactionNumber || `#${transactionId}`} has been rejected.${rejectionReason ? ` Reason: ${rejectionReason}` : ''}`,
      link: getTransactionLink(moduleName, transactionId),
      priority: 'HIGH',
      createdBy: rejectedBy
    });
  }
}

/**
 * Get approval link based on module name
 */
function getApprovalLink(moduleName, transactionId) {
  const modulePathMap = {
    'PurchaseOrder': `/purchase/purchaseorder/${transactionId}/view`,
    'SalesOrder': `/sales/order/${transactionId}/view`,
    'CustomerPO': `/customer/po/${transactionId}/view`,
    'PurchaseRequisition': `/purchase/purchaserequisition/${transactionId}/view`,
    'RequestForQuotation': `/purchase/requestforquotation/${transactionId}/view`,
    'GoodsReceiptNote': `/purchase/goodsreceiptnote/${transactionId}/view`,
    'VendorInvoice': `/purchase/vendorinvoice/${transactionId}/view`,
    'ProductionOrder': `/production/productionorder/${transactionId}/view`,
  };
  
  return modulePathMap[moduleName] || `/dashboard`;
}

/**
 * Get transaction link based on module name
 */
function getTransactionLink(moduleName, transactionId) {
  return getApprovalLink(moduleName, transactionId);
}

module.exports = {
  createNotification,
  createApprovalRequestNotifications,
  createApprovalApprovedNotification,
  createApprovalRejectedNotification,
};

