// LOT FIFO 추천 설정 - 선입선출 재고 관리
// 상용 MES 대비 개선사항 Phase 1

/**
 * ═══════════════════════════════════════════════════════════════════
 * LOT FIFO (First In, First Out) 추천 기능
 * ═══════════════════════════════════════════════════════════════════
 *
 * 목적: 가장 오래된 LOT를 먼저 사용하도록 추천하여
 *       - 품질 유지 (원자재 열화 방지)
 *       - 재고 회전율 향상
 *       - 원가 계산 정확성 향상
 *       - 추적성 확보
 *
 * ═══════════════════════════════════════════════════════════════════
 */

// LOT 상태 정의
export const lotStatuses = {
  AVAILABLE: { code: 'AVAILABLE', name: '사용가능', color: 'bg-green-100 text-green-700', priority: 1 },
  RESERVED: { code: 'RESERVED', name: '예약됨', color: 'bg-blue-100 text-blue-700', priority: 2 },
  IN_USE: { code: 'IN_USE', name: '사용중', color: 'bg-yellow-100 text-yellow-700', priority: 3 },
  HOLD: { code: 'HOLD', name: '보류', color: 'bg-orange-100 text-orange-700', priority: 99 },
  EXPIRED: { code: 'EXPIRED', name: '만료', color: 'bg-red-100 text-red-700', priority: 100 },
  DEPLETED: { code: 'DEPLETED', name: '소진', color: 'bg-gray-100 text-gray-700', priority: 101 },
};

// 자재 유형별 유통기한/권장사용기한 설정 (일)
export const materialShelfLife = {
  '원자재': {
    '철판': { shelfLife: 365, warningDays: 30 },
    '스틸코일': { shelfLife: 365, warningDays: 30 },
    '알루미늄코일': { shelfLife: 730, warningDays: 60 },
  },
  '구매부품': {
    '전동개폐기': { shelfLife: 730, warningDays: 60 },
    '연동제어기': { shelfLife: 730, warningDays: 60 },
    '릴레이': { shelfLife: 365, warningDays: 30 },
    '리미트스위치': { shelfLife: 365, warningDays: 30 },
  },
  '부자재': {
    '볼트/너트': { shelfLife: 1095, warningDays: 90 },
    '리벳': { shelfLife: 1095, warningDays: 90 },
    '고무패킹': { shelfLife: 180, warningDays: 14 },
    '윤활유': { shelfLife: 365, warningDays: 30 },
  },
  '원단': {
    '방화원단': { shelfLife: 730, warningDays: 60 },
    '방화시트': { shelfLife: 730, warningDays: 60 },
  },
};

// LOT 번호 생성 규칙
export const lotNumberRules = {
  // 입고 LOT: [품목분류코드]-[YYMMDD]-[순번3자리]
  inbound: {
    prefix: 'IN',
    format: '{prefix}-{itemTypeCode}-{dateStr}-{seq}',
    example: 'IN-RM-241215-001',
  },
  // 생산 LOT: [공정코드]-[YYMMDD]-[순번3자리]
  production: {
    prefix: 'PR',
    format: '{prefix}-{processCode}-{dateStr}-{seq}',
    example: 'PR-SCR-241215-001',
  },
  // 완제품 LOT: [제품라인코드]-[YYMMDD]-[순번3자리]
  finished: {
    prefix: 'FG',
    format: '{prefix}-{productLine}-{dateStr}-{seq}',
    example: 'FG-SHT-241215-001',
  },
};

// 품목 유형 코드
export const itemTypeCodes = {
  '원자재': 'RM',      // Raw Material
  '구매부품': 'PP',    // Purchased Parts
  '부자재': 'SM',      // Sub Material
  '원단': 'FB',        // Fabric
  '반제품': 'WIP',     // Work In Progress
  '완제품': 'FG',      // Finished Goods
};

// 공정 코드
export const processCodes = {
  'SCREEN': 'SCR',
  'SLAT': 'SLT',
  'FOLD': 'FLD',
  'ASSEMBLY': 'ASM',
  'PAINTING': 'PNT',
  'PACKING': 'PCK',
};

/**
 * LOT 번호 생성
 * @param {string} type - 'inbound' | 'production' | 'finished'
 * @param {object} params - { itemType, processCode, productLine }
 * @param {Date} date - 생성일
 * @param {number} seq - 순번
 * @returns {string} LOT 번호
 */
export const generateLotNumber = (type, params, date, seq) => {
  const rule = lotNumberRules[type];
  const dateStr = date.toISOString().slice(2, 10).replace(/-/g, '');
  const seqStr = String(seq).padStart(3, '0');

  let code = '';
  switch (type) {
    case 'inbound':
      code = itemTypeCodes[params.itemType] || 'XX';
      break;
    case 'production':
      code = processCodes[params.processCode] || 'XX';
      break;
    case 'finished':
      code = params.productLine || 'XX';
      break;
    default:
      code = 'XX';
  }

  return `${rule.prefix}-${code}-${dateStr}-${seqStr}`;
};

/**
 * FIFO 기반 LOT 추천 (핵심 기능)
 * @param {Array} lots - LOT 목록
 * @param {number} requiredQty - 필요 수량
 * @param {object} options - 옵션 { excludeHold: true, checkExpiry: true }
 * @returns {Array} 추천 LOT 목록 (FIFO 순서, 각 LOT에서 사용할 수량 포함)
 */
export const recommendFifoLots = (lots, requiredQty, options = {}) => {
  const { excludeHold = true, checkExpiry = true } = options;

  // 필터링: 사용 가능한 LOT만
  let availableLots = lots.filter(lot => {
    // 보류 상태 제외
    if (excludeHold && lot.status === 'HOLD') return false;
    // 만료 LOT 제외
    if (checkExpiry && lot.status === 'EXPIRED') return false;
    // 소진된 LOT 제외
    if (lot.status === 'DEPLETED') return false;
    // 잔량이 있는 LOT만
    if (lot.remainingQty <= 0) return false;
    return true;
  });

  // FIFO 정렬: 입고일 기준 오름차순 (가장 오래된 것 먼저)
  availableLots.sort((a, b) => {
    const dateA = new Date(a.inboundDate || a.createdDate);
    const dateB = new Date(b.inboundDate || b.createdDate);
    return dateA - dateB;
  });

  // 필요 수량 충족될 때까지 LOT 선택
  const recommendations = [];
  let remainingRequired = requiredQty;

  for (const lot of availableLots) {
    if (remainingRequired <= 0) break;

    const useQty = Math.min(lot.remainingQty, remainingRequired);
    recommendations.push({
      ...lot,
      recommendedQty: useQty,
      isPartial: useQty < lot.remainingQty,
      fifoRank: recommendations.length + 1,
      daysInStock: calculateDaysInStock(lot.inboundDate || lot.createdDate),
      expiryWarning: checkExpiryWarning(lot),
    });

    remainingRequired -= useQty;
  }

  // 추천 결과 요약
  const summary = {
    totalRequired: requiredQty,
    totalAllocated: requiredQty - remainingRequired,
    shortfall: Math.max(0, remainingRequired),
    lotCount: recommendations.length,
    isFullyAllocated: remainingRequired <= 0,
  };

  return { recommendations, summary };
};

/**
 * 재고 일수 계산
 */
export const calculateDaysInStock = (inboundDate) => {
  const today = new Date();
  const inbound = new Date(inboundDate);
  const diffTime = Math.abs(today - inbound);
  return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
};

/**
 * 만료 경고 확인
 */
export const checkExpiryWarning = (lot) => {
  if (!lot.expiryDate) return null;

  const today = new Date();
  const expiry = new Date(lot.expiryDate);
  const daysToExpiry = Math.ceil((expiry - today) / (1000 * 60 * 60 * 24));

  if (daysToExpiry <= 0) {
    return { level: 'expired', message: '만료됨', daysToExpiry };
  } else if (daysToExpiry <= 7) {
    return { level: 'critical', message: `${daysToExpiry}일 후 만료`, daysToExpiry };
  } else if (daysToExpiry <= 30) {
    return { level: 'warning', message: `${daysToExpiry}일 후 만료`, daysToExpiry };
  }
  return { level: 'ok', message: '정상', daysToExpiry };
};

/**
 * LOT 재고 현황 집계
 */
export const aggregateLotInventory = (lots) => {
  const summary = {
    totalLots: lots.length,
    totalQty: 0,
    byStatus: {},
    byItemType: {},
    expiryWarnings: [],
    fifoViolations: [], // FIFO 위반 (오래된 LOT가 남아있는 경우)
  };

  lots.forEach(lot => {
    summary.totalQty += lot.remainingQty || 0;

    // 상태별 집계
    const status = lot.status || 'AVAILABLE';
    if (!summary.byStatus[status]) {
      summary.byStatus[status] = { count: 0, qty: 0 };
    }
    summary.byStatus[status].count++;
    summary.byStatus[status].qty += lot.remainingQty || 0;

    // 품목 유형별 집계
    const itemType = lot.itemType || '기타';
    if (!summary.byItemType[itemType]) {
      summary.byItemType[itemType] = { count: 0, qty: 0, lots: [] };
    }
    summary.byItemType[itemType].count++;
    summary.byItemType[itemType].qty += lot.remainingQty || 0;
    summary.byItemType[itemType].lots.push(lot);

    // 만료 경고
    const warning = checkExpiryWarning(lot);
    if (warning && warning.level !== 'ok') {
      summary.expiryWarnings.push({ lot, warning });
    }
  });

  // FIFO 위반 검사 (각 품목별로 오래된 LOT가 사용되지 않은 경우)
  Object.entries(summary.byItemType).forEach(([itemType, data]) => {
    const sortedLots = data.lots
      .filter(l => l.remainingQty > 0)
      .sort((a, b) => new Date(a.inboundDate) - new Date(b.inboundDate));

    if (sortedLots.length > 1) {
      const oldestLot = sortedLots[0];
      const newerLots = sortedLots.slice(1);
      const hasNewerUsed = newerLots.some(l =>
        l.usedQty > 0 || l.status === 'IN_USE'
      );
      if (hasNewerUsed && oldestLot.remainingQty > 0) {
        summary.fifoViolations.push({
          itemType,
          oldestLot,
          message: `${oldestLot.lotNo}가 사용되지 않았습니다 (입고일: ${oldestLot.inboundDate})`,
        });
      }
    }
  });

  return summary;
};

/**
 * 안전재고 확인
 * @param {Array} lots - LOT 목록
 * @param {object} safetyStockLevels - 품목별 안전재고 수준 { '원자재': 100, ... }
 * @returns {Array} 안전재고 미달 품목 목록
 */
export const checkSafetyStock = (lots, safetyStockLevels) => {
  const aggregated = aggregateLotInventory(lots);
  const alerts = [];

  Object.entries(safetyStockLevels).forEach(([itemType, safetyLevel]) => {
    const current = aggregated.byItemType[itemType]?.qty || 0;
    if (current < safetyLevel) {
      alerts.push({
        itemType,
        currentQty: current,
        safetyLevel,
        shortfall: safetyLevel - current,
        percentage: Math.round((current / safetyLevel) * 100),
        severity: current === 0 ? 'critical' : current < safetyLevel * 0.5 ? 'warning' : 'info',
      });
    }
  });

  return alerts.sort((a, b) => {
    const severityOrder = { critical: 0, warning: 1, info: 2 };
    return severityOrder[a.severity] - severityOrder[b.severity];
  });
};

/**
 * LOT 추적 이력 조회용 구조
 */
export const lotTraceabilityFields = {
  // 입고 정보
  inbound: ['lotNo', 'inboundDate', 'supplier', 'poNo', 'invoiceNo', 'receivedQty'],
  // IQC 검사 정보
  iqc: ['inspectionNo', 'inspectionDate', 'inspector', 'result', 'checkItems'],
  // 사용 이력
  usage: ['workOrderNo', 'usedDate', 'usedQty', 'processName', 'operator'],
  // 출하 정보
  shipment: ['shipmentNo', 'shipmentDate', 'customer', 'deliveryAddress', 'shippedQty'],
};

export default {
  lotStatuses,
  materialShelfLife,
  lotNumberRules,
  itemTypeCodes,
  processCodes,
  generateLotNumber,
  recommendFifoLots,
  calculateDaysInStock,
  checkExpiryWarning,
  aggregateLotInventory,
  checkSafetyStock,
  lotTraceabilityFields,
};
