// 불합격품 처리 워크플로우 설정
// 상용 MES 대비 개선사항 Phase 1

/**
 * ═══════════════════════════════════════════════════════════════════
 * 불합격품 처리 워크플로우
 * ═══════════════════════════════════════════════════════════════════
 *
 * 품질검사에서 불합격 판정된 자재/제품의 처리 절차를 정의
 * - 명확한 처리 단계와 승인 절차
 * - 처리 옵션별 후속 조치 정의
 * - 이력 추적 및 분석 기능
 *
 * ═══════════════════════════════════════════════════════════════════
 */

// 불합격품 처리 상태
export const defectStatuses = {
  DETECTED: {
    code: 'DETECTED',
    name: '검출',
    description: '품질검사에서 불합격 판정됨',
    color: 'bg-red-100 text-red-700',
    nextActions: ['REVIEW'],
  },
  REVIEW: {
    code: 'REVIEW',
    name: '검토중',
    description: '처리 방안 검토 중',
    color: 'bg-yellow-100 text-yellow-700',
    nextActions: ['REWORK', 'ACCEPT_AS_IS', 'RETURN', 'SCRAP', 'DOWNGRADE'],
  },
  REWORK: {
    code: 'REWORK',
    name: '재작업',
    description: '재작업 진행 중',
    color: 'bg-blue-100 text-blue-700',
    nextActions: ['REINSPECTION'],
  },
  REINSPECTION: {
    code: 'REINSPECTION',
    name: '재검사',
    description: '재작업 후 재검사 대기/진행',
    color: 'bg-purple-100 text-purple-700',
    nextActions: ['COMPLETED', 'REWORK', 'SCRAP'],
  },
  ACCEPT_AS_IS: {
    code: 'ACCEPT_AS_IS',
    name: '특채승인대기',
    description: '조건부 합격 승인 대기',
    color: 'bg-orange-100 text-orange-700',
    nextActions: ['COMPLETED', 'REJECTED'],
    requireApproval: true,
  },
  RETURN: {
    code: 'RETURN',
    name: '반품처리',
    description: '공급업체 반품 진행',
    color: 'bg-indigo-100 text-indigo-700',
    nextActions: ['COMPLETED'],
  },
  SCRAP: {
    code: 'SCRAP',
    name: '폐기처리',
    description: '불량품 폐기 처리',
    color: 'bg-gray-100 text-gray-700',
    nextActions: ['COMPLETED'],
  },
  DOWNGRADE: {
    code: 'DOWNGRADE',
    name: '등급하향',
    description: '하위 등급으로 전용',
    color: 'bg-teal-100 text-teal-700',
    nextActions: ['COMPLETED'],
  },
  COMPLETED: {
    code: 'COMPLETED',
    name: '처리완료',
    description: '불합격품 처리 완료',
    color: 'bg-green-100 text-green-700',
    nextActions: [],
  },
  REJECTED: {
    code: 'REJECTED',
    name: '승인거부',
    description: '특채 승인 거부됨',
    color: 'bg-red-200 text-red-800',
    nextActions: ['REVIEW'],
  },
};

// 처리 옵션별 상세 정의
export const dispositionOptions = {
  REWORK: {
    code: 'REWORK',
    name: '재작업',
    description: '수정/보수 후 재검사',
    requiredFields: ['reworkPlan', 'estimatedTime', 'assignee'],
    workflow: ['작업지시 생성', '재작업 수행', '재검사 요청', '결과 확인'],
    costImpact: 'medium',
    timeImpact: 'medium',
  },
  ACCEPT_AS_IS: {
    code: 'ACCEPT_AS_IS',
    name: '특채',
    description: '조건부 합격 처리 (고객 동의 또는 내부 승인 필요)',
    requiredFields: ['reason', 'approver', 'conditions'],
    workflow: ['특채 사유 작성', '승인 요청', '승인/거부', '조건 이행'],
    approvalLevel: 'manager', // 관리자 이상 승인 필요
    costImpact: 'low',
    timeImpact: 'low',
  },
  RETURN: {
    code: 'RETURN',
    name: '반품',
    description: '공급업체로 반품 처리',
    requiredFields: ['returnReason', 'supplierContact', 'claimNo'],
    workflow: ['반품 사유 작성', '공급업체 통보', '반품 진행', '대체품 수령/환불'],
    documents: ['반품요청서', '불량보고서', '사진증빙'],
    costImpact: 'none', // 공급업체 부담
    timeImpact: 'high',
  },
  SCRAP: {
    code: 'SCRAP',
    name: '폐기',
    description: '불량품 폐기 처리',
    requiredFields: ['scrapReason', 'disposalMethod', 'quantity'],
    workflow: ['폐기 사유 작성', '폐기 승인', '폐기 수행', '재고 차감'],
    approvalLevel: 'supervisor', // 슈퍼바이저 이상 승인
    costImpact: 'high',
    timeImpact: 'low',
  },
  DOWNGRADE: {
    code: 'DOWNGRADE',
    name: '등급하향',
    description: '하위 등급 또는 다른 용도로 전용',
    requiredFields: ['newGrade', 'newUsage', 'priceAdjustment'],
    workflow: ['등급 재평가', '전용처 지정', '가격 조정', '재고 이동'],
    costImpact: 'medium',
    timeImpact: 'low',
  },
};

// 불량 유형별 추천 처리방법
export const defectDispositionMatrix = {
  DIMENSION: {
    // 치수불량
    minor: ['REWORK', 'ACCEPT_AS_IS'],
    major: ['REWORK', 'SCRAP'],
    critical: ['SCRAP', 'RETURN'],
  },
  APPEARANCE: {
    // 외관불량
    minor: ['ACCEPT_AS_IS', 'DOWNGRADE'],
    major: ['REWORK', 'DOWNGRADE'],
    critical: ['SCRAP'],
  },
  FUNCTION: {
    // 기능불량
    minor: ['REWORK'],
    major: ['REWORK', 'SCRAP'],
    critical: ['SCRAP', 'RETURN'],
  },
  MATERIAL: {
    // 재질불량
    minor: ['ACCEPT_AS_IS'],
    major: ['RETURN', 'SCRAP'],
    critical: ['RETURN'],
  },
  ASSEMBLY: {
    // 조립불량
    minor: ['REWORK'],
    major: ['REWORK'],
    critical: ['SCRAP'],
  },
  PACKAGING: {
    // 포장불량
    minor: ['REWORK'],
    major: ['REWORK'],
    critical: ['REWORK', 'SCRAP'],
  },
  QUANTITY: {
    // 수량부족
    minor: ['ACCEPT_AS_IS'],
    major: ['RETURN'],
    critical: ['RETURN'],
  },
};

// 불량 심각도 정의
export const defectSeverityLevels = {
  minor: {
    code: 'minor',
    name: '경미',
    description: '사용에 지장 없는 미미한 결함',
    color: 'bg-yellow-100 text-yellow-700',
    weight: 1,
  },
  major: {
    code: 'major',
    name: '중요',
    description: '기능 또는 외관에 영향을 주는 결함',
    color: 'bg-orange-100 text-orange-700',
    weight: 3,
  },
  critical: {
    code: 'critical',
    name: '치명',
    description: '안전 또는 기본 기능에 영향을 주는 결함',
    color: 'bg-red-100 text-red-700',
    weight: 5,
  },
};

// 승인 권한 레벨
export const approvalLevels = {
  operator: { level: 1, name: '작업자', canApprove: [] },
  supervisor: { level: 2, name: '슈퍼바이저', canApprove: ['SCRAP_minor'] },
  manager: { level: 3, name: '관리자', canApprove: ['ACCEPT_AS_IS', 'SCRAP_major', 'DOWNGRADE'] },
  director: { level: 4, name: '이사', canApprove: ['SCRAP_critical', 'ACCEPT_AS_IS_critical'] },
};

/**
 * 불합격품 처리 추천
 * @param {string} defectType - 불량 유형 코드
 * @param {string} severity - 심각도 (minor/major/critical)
 * @returns {Array} 추천 처리 방법 목록
 */
export const recommendDisposition = (defectType, severity) => {
  const matrix = defectDispositionMatrix[defectType];
  if (!matrix) return Object.keys(dispositionOptions);

  const recommended = matrix[severity] || matrix['minor'];
  return recommended.map(code => ({
    ...dispositionOptions[code],
    isRecommended: true,
  }));
};

/**
 * 처리 워크플로우 생성
 * @param {object} defect - 불량 정보
 * @param {string} disposition - 선택된 처리방법
 * @returns {object} 워크플로우 인스턴스
 */
export const createDefectWorkflow = (defect, disposition) => {
  const option = dispositionOptions[disposition];
  if (!option) {
    throw new Error(`Unknown disposition: ${disposition}`);
  }

  const workflow = {
    id: `DW-${Date.now()}`,
    defectId: defect.id,
    disposition,
    status: disposition === 'ACCEPT_AS_IS' ? 'ACCEPT_AS_IS' : disposition,
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
    steps: option.workflow.map((step, index) => ({
      seq: index + 1,
      name: step,
      status: index === 0 ? 'current' : 'pending',
      completedAt: null,
      completedBy: null,
    })),
    requiredFields: option.requiredFields,
    formData: {},
    approvals: option.approvalLevel ? [{
      level: option.approvalLevel,
      status: 'pending',
      approver: null,
      approvedAt: null,
      comments: null,
    }] : [],
    history: [{
      action: 'created',
      timestamp: new Date().toISOString(),
      user: null,
      details: `불합격품 처리 시작: ${option.name}`,
    }],
  };

  return workflow;
};

/**
 * 워크플로우 단계 진행
 * @param {object} workflow - 워크플로우 인스턴스
 * @param {number} stepSeq - 완료할 단계 번호
 * @param {string} userId - 완료 처리자
 * @returns {object} 업데이트된 워크플로우
 */
export const advanceWorkflowStep = (workflow, stepSeq, userId) => {
  const updated = { ...workflow };
  const step = updated.steps.find(s => s.seq === stepSeq);

  if (!step) {
    throw new Error(`Step ${stepSeq} not found`);
  }

  step.status = 'completed';
  step.completedAt = new Date().toISOString();
  step.completedBy = userId;

  // 다음 단계 활성화
  const nextStep = updated.steps.find(s => s.seq === stepSeq + 1);
  if (nextStep) {
    nextStep.status = 'current';
  } else {
    // 모든 단계 완료
    updated.status = 'COMPLETED';
  }

  updated.updatedAt = new Date().toISOString();
  updated.history.push({
    action: 'step_completed',
    timestamp: new Date().toISOString(),
    user: userId,
    details: `단계 완료: ${step.name}`,
  });

  return updated;
};

/**
 * 불량 통계 계산
 * @param {Array} defects - 불량 목록
 * @returns {object} 통계 정보
 */
export const calculateDefectStatistics = (defects) => {
  const stats = {
    total: defects.length,
    byType: {},
    bySeverity: {},
    byStatus: {},
    byDisposition: {},
    avgResolutionTime: 0,
    topDefectTypes: [],
  };

  let totalResolutionTime = 0;
  let resolvedCount = 0;

  defects.forEach(defect => {
    // 유형별
    const type = defect.defectType || 'OTHER';
    stats.byType[type] = (stats.byType[type] || 0) + 1;

    // 심각도별
    const severity = defect.severity || 'minor';
    stats.bySeverity[severity] = (stats.bySeverity[severity] || 0) + 1;

    // 상태별
    const status = defect.status || 'DETECTED';
    stats.byStatus[status] = (stats.byStatus[status] || 0) + 1;

    // 처리방법별
    if (defect.disposition) {
      stats.byDisposition[defect.disposition] = (stats.byDisposition[defect.disposition] || 0) + 1;
    }

    // 처리시간 계산
    if (defect.resolvedAt && defect.createdAt) {
      const created = new Date(defect.createdAt);
      const resolved = new Date(defect.resolvedAt);
      totalResolutionTime += (resolved - created) / (1000 * 60 * 60); // 시간 단위
      resolvedCount++;
    }
  });

  // 평균 처리시간
  stats.avgResolutionTime = resolvedCount > 0
    ? Math.round(totalResolutionTime / resolvedCount * 10) / 10
    : 0;

  // Top 불량 유형
  stats.topDefectTypes = Object.entries(stats.byType)
    .sort((a, b) => b[1] - a[1])
    .slice(0, 5)
    .map(([type, count]) => ({ type, count, percentage: Math.round(count / stats.total * 100) }));

  return stats;
};

/**
 * 공급업체별 불량률 계산
 * @param {Array} defects - 불량 목록
 * @param {Array} receipts - 입고 목록
 * @returns {Array} 공급업체별 불량률
 */
export const calculateSupplierDefectRate = (defects, receipts) => {
  const supplierStats = {};

  // 입고 집계
  receipts.forEach(receipt => {
    const supplier = receipt.supplier || receipt.supplierName;
    if (!supplierStats[supplier]) {
      supplierStats[supplier] = { totalQty: 0, defectQty: 0, defectCount: 0 };
    }
    supplierStats[supplier].totalQty += receipt.quantity || receipt.receivedQty || 0;
  });

  // 불량 집계
  defects.forEach(defect => {
    const supplier = defect.supplier || defect.supplierName;
    if (supplierStats[supplier]) {
      supplierStats[supplier].defectQty += defect.quantity || defect.defectQty || 0;
      supplierStats[supplier].defectCount++;
    }
  });

  // 불량률 계산
  return Object.entries(supplierStats)
    .map(([supplier, stats]) => ({
      supplier,
      totalQty: stats.totalQty,
      defectQty: stats.defectQty,
      defectCount: stats.defectCount,
      defectRate: stats.totalQty > 0
        ? Math.round(stats.defectQty / stats.totalQty * 1000) / 10
        : 0,
    }))
    .sort((a, b) => b.defectRate - a.defectRate);
};

export default {
  defectStatuses,
  dispositionOptions,
  defectDispositionMatrix,
  defectSeverityLevels,
  approvalLevels,
  recommendDisposition,
  createDefectWorkflow,
  advanceWorkflowStep,
  calculateDefectStatistics,
  calculateSupplierDefectRate,
};
