import { ItemMaster, PricingData, CalculationFormula, CategoryGroup } from "../contexts/DataContext";
import type { ItemDebugInfo } from "../BomCalculationResults";

/**
 * BOM 라인 인터페이스
 */
export interface BOMLine {
  childItemCode: string;
  childItemName?: string;
  quantity: number;
  unit?: string;
  quantityFormula?: string;
  formula?: string;
  note?: string;
}

/**
 * 계산 변수
 */
export interface CalculationVariables {
  W0: number; // 오픈사이즈 폭
  H0: number; // 오픈사이즈 높이
  W1: number; // 제작폭
  H1: number; // 제작높이
  M: number;  // 면적
  K: number;  // 중량
}

/**
 * BOM 아이템 결과 (디버깅 정보 포함)
 */
export interface BomItemWithDebug {
  itemCode: string;
  itemName: string;
  itemCategory: string;
  quantityFormula: string;
  calculatedQuantity: number;
  unit: string;
  unitPrice: number;
  totalPrice: number;
  debugInfo?: ItemDebugInfo;
}

/**
 * 수식을 평가하여 수량을 계산
 */
function evaluateFormula(formula: string, variables: CalculationVariables): number {
  try {
    let evaluatedFormula = formula
      .replace(/W0/g, variables.W0.toString())
      .replace(/H0/g, variables.H0.toString())
      .replace(/W1/g, variables.W1.toString())
      .replace(/H1/g, variables.H1.toString())
      .replace(/M/g, variables.M.toString())
      .replace(/K/g, variables.K.toString());
    
    return eval(evaluatedFormula);
  } catch (error) {
    console.error("수식 평가 오류:", error);
    return 0;
  }
}

/**
 * 품목의 단가를 찾기
 */
function findItemPrice(
  item: ItemMaster,
  pricingData: PricingData[]
): { price: number; source: string } {
  // 1. 단가관리에서 찾기
  const pricing = pricingData.find(
    (p) => p.itemCode === item.itemCode && p.status === 'active'
  );
  
  if (pricing && pricing.salesPrice) {
    return {
      price: pricing.salesPrice,
      source: `단가관리 (${pricing.effectiveDate})`
    };
  }
  
  // 2. 품목마스터에서 찾기
  if (item.salesPrice) {
    return {
      price: item.salesPrice,
      source: "품목마스터"
    };
  }
  
  return {
    price: 0,
    source: "단가 없음"
  };
}

/**
 * 품목 분류에 따른 변수 곱셈 적용
 */
function applyCategoryMultiplier(
  itemCategory: string,
  basePrice: number,
  variables: CalculationVariables,
  categoryGroups: CategoryGroup[]
): { finalPrice: number; multiplierFormula?: string } {
  // 카테고리 그룹에서 해당 품목의 분류 찾기
  const categoryGroup = categoryGroups.find(group => 
    group.categories.includes(itemCategory)
  );
  
  if (!categoryGroup) {
    return { finalPrice: basePrice };
  }
  
  // 분류별 변수 곱셈 로직
  // 예: "오픈사이즈" 그룹이면 면적(M)을 곱함
  if (categoryGroup.name.includes("면적")) {
    return {
      finalPrice: basePrice * variables.M,
      multiplierFormula: `기본단가 ${basePrice.toLocaleString()}원 × 면적 ${variables.M.toFixed(2)}m²`
    };
  }
  
  if (categoryGroup.name.includes("중량")) {
    return {
      finalPrice: basePrice * variables.K,
      multiplierFormula: `기본단가 ${basePrice.toLocaleString()}원 × 중량 ${variables.K.toFixed(2)}kg`
    };
  }
  
  return { finalPrice: basePrice };
}

/**
 * BOM 라인을 계산하고 디버깅 정보 생성
 */
export function calculateBomWithDebug(
  bomLines: BOMLine[],
  itemMasters: ItemMaster[],
  pricingData: PricingData[],
  formulas: CalculationFormula[],
  categoryGroups: CategoryGroup[],
  variables: CalculationVariables
): BomItemWithDebug[] {
  return bomLines.map((line) => {
    // Step 1: 품목 찾기
    const item = itemMasters.find((i) => i.itemCode === line.childItemCode);
    
    if (!item) {
      console.warn(`품목을 찾을 수 없음: ${line.childItemCode}`);
      return {
        itemCode: line.childItemCode,
        itemName: line.childItemName || "알 수 없음",
        itemCategory: "",
        quantityFormula: "",
        calculatedQuantity: 0,
        unit: line.unit || "EA",
        unitPrice: 0,
        totalPrice: 0
      };
    }
    
    // Step 2-4: 수량 계산
    const formula = line.quantityFormula || line.formula || "";
    let calculatedQuantity = line.quantity;
    let quantityCalcProcess = `기본 수량: ${line.quantity}`;
    
    if (formula) {
      const beforeReplace = formula;
      calculatedQuantity = evaluateFormula(formula, variables);
      
      // 수식 계산 과정 문자열 생성
      const replacedFormula = formula
        .replace(/W0/g, `${variables.W0}`)
        .replace(/H0/g, `${variables.H0}`)
        .replace(/W1/g, `${variables.W1}`)
        .replace(/H1/g, `${variables.H1}`)
        .replace(/M/g, `${variables.M.toFixed(2)}`)
        .replace(/K/g, `${variables.K.toFixed(2)}`);
      
      quantityCalcProcess = `${beforeReplace} = ${replacedFormula} = ${calculatedQuantity.toFixed(2)}`;
    }
    
    // Step 5-6: 단가 찾기
    const { price: basePrice, source: priceSource } = findItemPrice(item, pricingData);
    
    // Step 7-8: 분류별 변수 곱셈 적용
    const { finalPrice, multiplierFormula } = applyCategoryMultiplier(
      item.itemCategory || "",
      basePrice,
      variables,
      categoryGroups
    );
    
    // Step 9-10: 최종 금액 계산
    const totalPrice = calculatedQuantity * finalPrice;
    const totalCalcProcess = `${calculatedQuantity.toFixed(2)} ${item.unit} × ${finalPrice.toLocaleString()}원 = ${totalPrice.toLocaleString()}원`;
    
    // 디버깅 정보 생성
    const debugInfo: ItemDebugInfo = {
      step1_formula: formula || "수식 없음 (고정 수량)",
      step2_variables: {
        W0: variables.W0,
        H0: variables.H0,
        W1: variables.W1,
        H1: variables.H1,
        M: parseFloat(variables.M.toFixed(2)),
        K: parseFloat(variables.K.toFixed(2))
      },
      step3_quantityCalc: quantityCalcProcess,
      step4_quantity: calculatedQuantity,
      step5_priceSource: priceSource,
      step6_basePrice: basePrice,
      step7_categoryMultiplier: multiplierFormula,
      step8_finalPrice: finalPrice,
      step9_totalCalc: totalCalcProcess,
      step10_total: totalPrice
    };
    
    return {
      itemCode: item.itemCode,
      itemName: item.itemName,
      itemCategory: item.itemCategory || "",
      quantityFormula: formula,
      calculatedQuantity,
      unit: item.unit || "EA",
      unitPrice: finalPrice,
      totalPrice,
      debugInfo
    };
  }).filter(Boolean) as BomItemWithDebug[];
}