// 안전재고 관리 및 알림 설정
// 상용 MES 대비 개선사항 Phase 2

/**
 * ═══════════════════════════════════════════════════════════════════
 * 안전재고 관리 (Safety Stock Management)
 * ═══════════════════════════════════════════════════════════════════
 *
 * 목적: 재고 부족으로 인한 생산 차질 방지
 *       - 품목별 안전재고 수준 설정
 *       - 실시간 재고 모니터링 및 알림
 *       - 발주점(Reorder Point) 관리
 *       - 재고 회전율 분석
 *
 * ═══════════════════════════════════════════════════════════════════
 */

// 알림 심각도 레벨
export const alertLevels = {
  CRITICAL: {
    code: 'CRITICAL',
    name: '긴급',
    description: '재고 소진 임박 (안전재고 50% 미만)',
    color: 'bg-red-500 text-white',
    icon: 'AlertTriangle',
    priority: 1,
  },
  WARNING: {
    code: 'WARNING',
    name: '경고',
    description: '안전재고 수준 미달',
    color: 'bg-orange-500 text-white',
    icon: 'AlertCircle',
    priority: 2,
  },
  INFO: {
    code: 'INFO',
    name: '정보',
    description: '안전재고 근접 (110% 이하)',
    color: 'bg-yellow-500 text-black',
    icon: 'Info',
    priority: 3,
  },
  OK: {
    code: 'OK',
    name: '정상',
    description: '적정 재고 수준',
    color: 'bg-green-500 text-white',
    icon: 'CheckCircle',
    priority: 4,
  },
  EXCESS: {
    code: 'EXCESS',
    name: '과잉',
    description: '과잉 재고 (최대재고 초과)',
    color: 'bg-blue-500 text-white',
    icon: 'Package',
    priority: 5,
  },
};

// 품목 유형별 기본 안전재고 설정
export const defaultSafetyStockSettings = {
  // 원자재
  '원자재': {
    safetyDays: 14,              // 안전재고 일수
    reorderDays: 21,             // 발주점 일수 (L/T + 안전재고일수)
    maxStockDays: 60,            // 최대재고 일수
    leadTime: 7,                 // 조달 리드타임 (일)
    minOrderQty: 100,            // 최소 발주량
    orderMultiple: 50,           // 발주 단위
  },
  // 구매부품
  '구매부품': {
    safetyDays: 7,
    reorderDays: 14,
    maxStockDays: 45,
    leadTime: 7,
    minOrderQty: 10,
    orderMultiple: 5,
  },
  // 부자재
  '부자재': {
    safetyDays: 30,
    reorderDays: 45,
    maxStockDays: 90,
    leadTime: 14,
    minOrderQty: 100,
    orderMultiple: 100,
  },
  // 원단
  '원단': {
    safetyDays: 14,
    reorderDays: 28,
    maxStockDays: 60,
    leadTime: 14,
    minOrderQty: 50,
    orderMultiple: 10,
  },
};

// 개별 품목 안전재고 설정 (예시)
export const itemSafetyStockSettings = {
  // 전동개폐기 - 주요 구매부품
  'MTR-001': {
    itemCode: 'MTR-001',
    itemName: '전동개폐기',
    safetyStock: 20,              // 안전재고 수량
    reorderPoint: 30,             // 발주점
    maxStock: 100,                // 최대재고
    minOrderQty: 10,              // 최소 발주량
    orderMultiple: 5,             // 발주 단위
    leadTime: 7,                  // 조달 L/T
    avgDailyUsage: 3,             // 일평균 사용량
    supplier: '(주)모터시스템',
  },
  // 연동제어기
  'CTL-001': {
    itemCode: 'CTL-001',
    itemName: '연동제어기',
    safetyStock: 15,
    reorderPoint: 25,
    maxStock: 80,
    minOrderQty: 5,
    orderMultiple: 5,
    leadTime: 7,
    avgDailyUsage: 2.5,
    supplier: '(주)제어시스템',
  },
  // 방화원단
  'FB-001': {
    itemCode: 'FB-001',
    itemName: '방화원단',
    safetyStock: 500,             // M2
    reorderPoint: 800,
    maxStock: 2000,
    minOrderQty: 100,
    orderMultiple: 50,
    leadTime: 14,
    avgDailyUsage: 50,
    supplier: '(주)방화소재',
  },
  // 스틸코일
  'STEEL-COIL': {
    itemCode: 'STEEL-COIL',
    itemName: '스틸코일',
    safetyStock: 2000,            // KG
    reorderPoint: 3500,
    maxStock: 10000,
    minOrderQty: 500,
    orderMultiple: 100,
    leadTime: 7,
    avgDailyUsage: 200,
    supplier: '(주)철강유통',
  },
};

/**
 * 안전재고 상태 확인
 * @param {number} currentStock - 현재고
 * @param {number} safetyStock - 안전재고
 * @param {number} maxStock - 최대재고 (선택)
 * @returns {object} 상태 정보
 */
export const checkStockLevel = (currentStock, safetyStock, maxStock = null) => {
  const ratio = safetyStock > 0 ? (currentStock / safetyStock) * 100 : 100;

  if (currentStock === 0) {
    return {
      level: alertLevels.CRITICAL,
      ratio: 0,
      message: '재고 소진',
      action: '긴급 발주 필요',
    };
  } else if (ratio < 50) {
    return {
      level: alertLevels.CRITICAL,
      ratio: Math.round(ratio),
      message: `안전재고 ${Math.round(ratio)}%`,
      action: '긴급 발주 필요',
    };
  } else if (ratio < 100) {
    return {
      level: alertLevels.WARNING,
      ratio: Math.round(ratio),
      message: `안전재고 ${Math.round(ratio)}%`,
      action: '발주 검토 필요',
    };
  } else if (ratio <= 110) {
    return {
      level: alertLevels.INFO,
      ratio: Math.round(ratio),
      message: '안전재고 근접',
      action: '모니터링 필요',
    };
  } else if (maxStock && currentStock > maxStock) {
    return {
      level: alertLevels.EXCESS,
      ratio: Math.round(ratio),
      message: '최대재고 초과',
      action: '재고 조정 검토',
    };
  }

  return {
    level: alertLevels.OK,
    ratio: Math.round(ratio),
    message: '정상 수준',
    action: null,
  };
};

/**
 * 발주점 도달 확인
 * @param {number} currentStock - 현재고
 * @param {number} reorderPoint - 발주점
 * @returns {boolean} 발주 필요 여부
 */
export const isReorderNeeded = (currentStock, reorderPoint) => {
  return currentStock <= reorderPoint;
};

/**
 * 권장 발주량 계산
 * @param {object} item - 품목 정보
 * @param {number} currentStock - 현재고
 * @returns {object} 발주 권장 정보
 */
export const calculateReorderQuantity = (item, currentStock) => {
  const {
    maxStock = 0,
    safetyStock = 0,
    minOrderQty = 1,
    orderMultiple = 1,
    avgDailyUsage = 0,
    leadTime = 0,
  } = item;

  // 목표 재고 = 최대재고 또는 (안전재고 + 리드타임 사용량)
  const targetStock = maxStock || (safetyStock + (avgDailyUsage * leadTime * 2));

  // 필요량 = 목표 재고 - 현재고
  let neededQty = Math.max(0, targetStock - currentStock);

  // 발주 단위로 올림
  if (orderMultiple > 1) {
    neededQty = Math.ceil(neededQty / orderMultiple) * orderMultiple;
  }

  // 최소 발주량 확인
  if (neededQty > 0 && neededQty < minOrderQty) {
    neededQty = minOrderQty;
  }

  return {
    recommendedQty: neededQty,
    targetStock,
    expectedStock: currentStock + neededQty,
    coverageDays: avgDailyUsage > 0 ? Math.round((currentStock + neededQty) / avgDailyUsage) : null,
  };
};

/**
 * 전체 재고 알림 생성
 * @param {Array} inventory - 재고 목록 [{ itemCode, itemName, currentStock, itemType, ... }]
 * @param {object} settings - 품목별 설정
 * @returns {Array} 알림 목록
 */
export const generateStockAlerts = (inventory, settings = itemSafetyStockSettings) => {
  const alerts = [];

  inventory.forEach(item => {
    // 개별 설정 또는 기본 설정 사용
    const itemSettings = settings[item.itemCode] ||
      defaultSafetyStockSettings[item.itemType] ||
      { safetyStock: 0, reorderPoint: 0, maxStock: 0 };

    // 안전재고 설정이 없으면 건너뜀
    if (!itemSettings.safetyStock && !itemSettings.safetyDays) {
      return;
    }

    // 일수 기반 설정을 수량으로 변환
    const safetyStock = itemSettings.safetyStock ||
      (itemSettings.safetyDays * (item.avgDailyUsage || 1));
    const maxStock = itemSettings.maxStock ||
      (itemSettings.maxStockDays * (item.avgDailyUsage || 1));

    const status = checkStockLevel(item.currentStock || 0, safetyStock, maxStock);

    // 정상이 아닌 경우만 알림 생성
    if (status.level.code !== 'OK') {
      alerts.push({
        itemCode: item.itemCode,
        itemName: item.itemName,
        itemType: item.itemType,
        currentStock: item.currentStock || 0,
        safetyStock,
        unit: item.unit,
        ...status,
        reorderInfo: isReorderNeeded(item.currentStock || 0, itemSettings.reorderPoint || safetyStock)
          ? calculateReorderQuantity({ ...itemSettings, safetyStock, maxStock }, item.currentStock || 0)
          : null,
        supplier: itemSettings.supplier || item.supplier,
        timestamp: new Date().toISOString(),
      });
    }
  });

  // 우선순위 순 정렬 (긴급 > 경고 > 정보 > 과잉)
  return alerts.sort((a, b) => a.level.priority - b.level.priority);
};

/**
 * 재고 회전율 계산
 * @param {number} usedQty - 기간 내 사용량
 * @param {number} avgStock - 평균 재고
 * @returns {number} 재고 회전율
 */
export const calculateTurnoverRate = (usedQty, avgStock) => {
  if (avgStock <= 0) return 0;
  return Math.round((usedQty / avgStock) * 100) / 100;
};

/**
 * 재고 일수 계산
 * @param {number} currentStock - 현재고
 * @param {number} avgDailyUsage - 일평균 사용량
 * @returns {number} 재고 일수
 */
export const calculateDaysOfSupply = (currentStock, avgDailyUsage) => {
  if (avgDailyUsage <= 0) return Infinity;
  return Math.round(currentStock / avgDailyUsage);
};

/**
 * ABC 분석 (재고 중요도 분류)
 * @param {Array} inventory - 재고 목록 [{ itemCode, value, ... }]
 * @returns {object} ABC 분류 결과
 */
export const abcAnalysis = (inventory) => {
  // 금액 기준 내림차순 정렬
  const sorted = [...inventory].sort((a, b) => (b.value || 0) - (a.value || 0));

  const totalValue = sorted.reduce((sum, item) => sum + (item.value || 0), 0);

  let cumValue = 0;
  const classified = sorted.map(item => {
    cumValue += item.value || 0;
    const cumPercent = totalValue > 0 ? (cumValue / totalValue) * 100 : 0;

    let category;
    if (cumPercent <= 70) {
      category = 'A';  // 상위 70% 금액 (약 20% 품목)
    } else if (cumPercent <= 90) {
      category = 'B';  // 다음 20% 금액 (약 30% 품목)
    } else {
      category = 'C';  // 나머지 10% 금액 (약 50% 품목)
    }

    return {
      ...item,
      abcCategory: category,
      cumPercent: Math.round(cumPercent * 10) / 10,
    };
  });

  // 분류별 집계
  const summary = {
    A: { count: 0, value: 0, items: [] },
    B: { count: 0, value: 0, items: [] },
    C: { count: 0, value: 0, items: [] },
  };

  classified.forEach(item => {
    summary[item.abcCategory].count++;
    summary[item.abcCategory].value += item.value || 0;
    summary[item.abcCategory].items.push(item);
  });

  return {
    items: classified,
    summary,
    totalItems: inventory.length,
    totalValue,
  };
};

/**
 * 재고 대시보드 데이터 생성
 * @param {Array} inventory - 재고 목록
 * @param {object} settings - 안전재고 설정
 * @returns {object} 대시보드 데이터
 */
export const generateStockDashboard = (inventory, settings = itemSafetyStockSettings) => {
  const alerts = generateStockAlerts(inventory, settings);

  const dashboard = {
    // 전체 현황
    overview: {
      totalItems: inventory.length,
      totalValue: inventory.reduce((sum, i) => sum + ((i.currentStock || 0) * (i.unitPrice || 0)), 0),
    },
    // 알림 현황
    alerts: {
      critical: alerts.filter(a => a.level.code === 'CRITICAL').length,
      warning: alerts.filter(a => a.level.code === 'WARNING').length,
      info: alerts.filter(a => a.level.code === 'INFO').length,
      excess: alerts.filter(a => a.level.code === 'EXCESS').length,
      list: alerts.slice(0, 10), // 상위 10개만
    },
    // 품목 유형별 현황
    byItemType: {},
    // 발주 필요 품목
    reorderNeeded: alerts.filter(a => a.reorderInfo).map(a => ({
      itemCode: a.itemCode,
      itemName: a.itemName,
      currentStock: a.currentStock,
      recommendedQty: a.reorderInfo.recommendedQty,
      supplier: a.supplier,
    })),
  };

  // 품목 유형별 집계
  inventory.forEach(item => {
    const type = item.itemType || '기타';
    if (!dashboard.byItemType[type]) {
      dashboard.byItemType[type] = {
        count: 0,
        totalStock: 0,
        totalValue: 0,
        alertCount: 0,
      };
    }
    dashboard.byItemType[type].count++;
    dashboard.byItemType[type].totalStock += item.currentStock || 0;
    dashboard.byItemType[type].totalValue += (item.currentStock || 0) * (item.unitPrice || 0);
  });

  // 유형별 알림 수 집계
  alerts.forEach(alert => {
    const type = alert.itemType || '기타';
    if (dashboard.byItemType[type]) {
      dashboard.byItemType[type].alertCount++;
    }
  });

  return dashboard;
};

export default {
  alertLevels,
  defaultSafetyStockSettings,
  itemSafetyStockSettings,
  checkStockLevel,
  isReorderNeeded,
  calculateReorderQuantity,
  generateStockAlerts,
  calculateTurnoverRate,
  calculateDaysOfSupply,
  abcAnalysis,
  generateStockDashboard,
};
