/**
 * Status Validation Service
 * Provides centralized status state machine validation for all ERP modules
 * Following SAP Advanced, Oracle ERP, and D365 patterns
 */

/**
 * Status Flow Definitions
 * Defines valid status transitions for each module
 */
const statusFlows = {
  // Customer PO Status Flow
  customerPO: {
    DRAFT: ['SUBMITTED', 'CANCELLED'],
    SUBMITTED: ['APPROVED', 'REJECTED', 'DRAFT'],
    APPROVED: ['RELEASED', 'REJECTED'],
    RELEASED: ['IN_PROGRESS', 'CANCELLED'],
    IN_PROGRESS: ['PARTIALLY_DELIVERED', 'DELIVERED'],
    PARTIALLY_DELIVERED: ['DELIVERED'],
    DELIVERED: ['INVOICED'],
    INVOICED: ['CLOSED'],
    REJECTED: ['DRAFT'],
    CANCELLED: [],
    CLOSED: []
  },

  // Production Order Status Flow
  productionOrder: {
    DRAFT: ['RELEASED', 'CANCELLED'],
    RELEASED: ['IN_PROGRESS', 'CANCELLED'],
    IN_PROGRESS: ['PARTIALLY_CONFIRMED', 'CONFIRMED', 'CANCELLED'],
    PARTIALLY_CONFIRMED: ['CONFIRMED', 'IN_PROGRESS'],
    CONFIRMED: ['CLOSED'],
    CANCELLED: [],
    CLOSED: []
  },

  // Material Request Status Flow
  materialRequest: {
    DRAFT: ['SENT_TO_STORES', 'CANCELLED'],
    SENT_TO_STORES: ['REVIEWED', 'DRAFT'],
    REVIEWED: ['SENT_TO_PURCHASE', 'PARTIALLY_ISSUED', 'COMPLETED', 'CANCELLED'],
    SENT_TO_PURCHASE: ['COMPLETED', 'CANCELLED'],
    PARTIALLY_ISSUED: ['COMPLETED', 'CANCELLED'],
    COMPLETED: [],
    CANCELLED: []
  },

  // Purchase Order Status Flow
  purchaseOrder: {
    DRAFT: ['APPROVED', 'CANCELLED'],
    APPROVED: ['RELEASED', 'CANCELLED'],
    RELEASED: ['PARTIALLY_RECEIVED', 'RECEIVED', 'CANCELLED'],
    PARTIALLY_RECEIVED: ['RECEIVED', 'CANCELLED'],
    RECEIVED: ['CLOSED'],
    CANCELLED: [],
    CLOSED: []
  },

  // Material Issue Status Flow
  materialIssue: {
    DRAFT: ['IN_TRANSIT', 'CANCELLED'],
    IN_TRANSIT: ['RECEIVED', 'CANCELLED'],
    RECEIVED: ['POSTED'],
    POSTED: [],
    CANCELLED: []
  },

  // Purchase Requisition Status Flow
  purchaseRequisition: {
    DRAFT: ['SUBMITTED', 'CANCELLED'],
    SUBMITTED: ['APPROVED', 'REJECTED', 'CANCELLED'],
    APPROVED: ['CLOSED'],
    REJECTED: ['DRAFT'],
    CANCELLED: [],
    CLOSED: []
  }
};

/**
 * Validate status transition
 * @param {string} module - Module name (e.g., 'customerPO', 'productionOrder')
 * @param {string} currentStatus - Current status
 * @param {string} newStatus - New status to transition to
 * @returns {Object} { valid: boolean, message: string }
 */
const validateStatusTransition = (module, currentStatus, newStatus) => {
  if (!statusFlows[module]) {
    return {
      valid: false,
      message: `Invalid module: ${module}`
    };
  }

  const flow = statusFlows[module];

  if (!flow[currentStatus]) {
    return {
      valid: false,
      message: `Invalid current status: ${currentStatus} for module: ${module}`
    };
  }

  const allowedTransitions = flow[currentStatus];

  if (!allowedTransitions.includes(newStatus)) {
    return {
      valid: false,
      message: `Invalid status transition from ${currentStatus} to ${newStatus}. Allowed transitions: ${allowedTransitions.join(', ')}`
    };
  }

  return {
    valid: true,
    message: 'Status transition is valid'
  };
};

/**
 * Get allowed status transitions for a given status
 * @param {string} module - Module name
 * @param {string} currentStatus - Current status
 * @returns {Array} Array of allowed status values
 */
const getAllowedTransitions = (module, currentStatus) => {
  if (!statusFlows[module]) {
    return [];
  }

  const flow = statusFlows[module];
  return flow[currentStatus] || [];
};

/**
 * Check if status transition is allowed
 * @param {string} module - Module name
 * @param {string} currentStatus - Current status
 * @param {string} newStatus - New status
 * @returns {boolean}
 */
const isTransitionAllowed = (module, currentStatus, newStatus) => {
  const validation = validateStatusTransition(module, currentStatus, newStatus);
  return validation.valid;
};

/**
 * Get status flow definition for a module
 * @param {string} module - Module name
 * @returns {Object|null} Status flow object or null if module not found
 */
const getStatusFlow = (module) => {
  return statusFlows[module] || null;
};

/**
 * Get all valid statuses for a module
 * @param {string} module - Module name
 * @returns {Array} Array of all valid status values
 */
const getAllValidStatuses = (module) => {
  if (!statusFlows[module]) {
    return [];
  }

  const flow = statusFlows[module];
  return Object.keys(flow);
};

module.exports = {
  validateStatusTransition,
  getAllowedTransitions,
  isTransitionAllowed,
  getStatusFlow,
  getAllValidStatuses,
  statusFlows
};

