/**
 * Модуль для управления workflow согласования счетов на оплату
 */

const WORKFLOW_STAGES = {
  draft: { 
    next: 'pending_manager_approval', 
    role: null,
    description: 'Черновик'
  },
  pending_manager_approval: { 
    next: 'pending_finance_manager_approval', 
    role: 'manager',
    description: 'На согласовании у руководителя'
  },
  pending_finance_manager_approval: { 
    next: 'approved', 
    role: 'finance_manager',
    description: 'На согласовании у финансового руководителя'
  },
  approved: { 
    next: 'scheduled', 
    role: 'financier',
    description: 'Согласован, ожидает постановки в график'
  },
  scheduled: { 
    next: 'paid', 
    role: null,
    description: 'В графике платежей'
  },
  paid: { 
    next: null, 
    role: null,
    description: 'Оплачен'
  },
  postponed: {
    next: 'scheduled',
    role: null,
    description: 'Отложен'
  },
  cancelled: {
    next: null,
    role: null,
    description: 'Отменен'
  },
  rejected: { 
    next: 'draft', 
    role: null,
    description: 'Отклонен'
  },
  completed: {
    next: null,
    role: null,
    description: 'Выполнено'
  }
};

// Роли высшего звена, которые пропускают этап manager
const TOP_MANAGEMENT_ROLES = ['finance_director', 'director', 'top_management'];

/**
 * Определяет следующий статус для счета
 * @param {string} currentStatus - текущий статус
 * @param {string[]} userRoles - роли пользователя
 * @returns {string|null} следующий статус
 */
function getNextStatus(currentStatus, userRoles = []) {
  const stage = WORKFLOW_STAGES[currentStatus];
  if (!stage) return null;

  // Если текущий статус pending_manager_approval и пользователь из высшего звена
  // пропускаем этап manager и идем сразу на finance_manager
  if (currentStatus === 'pending_manager_approval' && 
      userRoles.some(role => TOP_MANAGEMENT_ROLES.includes(role))) {
    return 'pending_finance_manager_approval';
  }

  return stage.next;
}

/**
 * Определяет, может ли пользователь согласовать счет на текущем этапе
 * @param {string} currentStatus - текущий статус счета
 * @param {string[]} userRoles - роли пользователя
 * @returns {boolean}
 */
function canApprove(currentStatus, userRoles = []) {
  const stage = WORKFLOW_STAGES[currentStatus];
  if (!stage || !stage.role) return false;

  // Если требуется роль manager, но пользователь из высшего звена - может согласовать
  if (stage.role === 'manager' && 
      userRoles.some(role => TOP_MANAGEMENT_ROLES.includes(role))) {
    return true;
  }

  return userRoles.includes(stage.role);
}

/**
 * Определяет роль следующего согласующего
 * @param {string} currentStatus - текущий статус
 * @param {string[]} userRoles - роли пользователя (для определения пропуска этапа)
 * @returns {string|null}
 */
function getNextApproverRole(currentStatus, userRoles = []) {
  const nextStatus = getNextStatus(currentStatus, userRoles);
  if (!nextStatus) return null;

  const nextStage = WORKFLOW_STAGES[nextStatus];
  return nextStage ? nextStage.role : null;
}

/**
 * Создает запись в истории согласования
 * @param {string} userId - ID пользователя
 * @param {string} userRole - роль пользователя
 * @param {string} action - действие (approve, reject, etc.)
 * @param {string} comment - комментарий
 * @returns {object}
 */
function createApprovalHistoryEntry(userId, userRole, action, comment = '') {
  return {
    userId,
    userRole,
    action,
    comment,
    date: new Date().toISOString()
  };
}

/**
 * Генерирует номер счета
 * @param {Date} date - дата создания
 * @returns {string}
 */
function generateInvoiceNumber(date = new Date()) {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const timestamp = Date.now().toString().slice(-6);
  return `INV-${year}${month}${day}-${timestamp}`;
}

module.exports = {
  WORKFLOW_STAGES,
  TOP_MANAGEMENT_ROLES,
  getNextStatus,
  canApprove,
  getNextApproverRole,
  createApprovalHistoryEntry,
  generateInvoiceNumber
};
