/**
 * 단가 수식 계산 유틸리티
 * 단가 수식 관리에서 설정한 맵핑을 기반으로 품목별 단가를 계산합니다.
 */

interface CalculationVariables {
  W0: number;  // 오픈사이즈 폭
  H0: number;  // 오픈사이즈 높이
  W1: number;  // 제작사이즈 폭
  H1: number;  // 제작사이즈 높이
  M: number;   // 면적 (㎡)
  K: number;   // 중량 (kg)
  UP?: number; // 품목 판매단가
  [key: string]: number | undefined;
}

interface FormulaData {
  id: string;
  name: string;
  formula: string;
  category?: string;
}

interface ItemMaster {
  id: string;
  itemCode: string;
  itemName: string;
  itemCategory?: string;
  sellingPrice?: number;
  [key: string]: any;
}

interface CategoryGroup {
  id: string;
  name: string;
  categories: string[];
}

interface PriceMappingItem {
  id: string;
  mappingType: 'individual' | 'categoryGroup';
  itemCode?: string;
  categoryGroupId?: string;
  priceFormulaId: string;
  quantityFormula?: string; // 단가 계산 수식
  enabled: boolean;
  priority?: number;
}

interface PricingData {
  id: string;
  itemCode?: string;
  itemId?: string;
  itemName?: string;
  salesPrice?: number;
  purchasePrice?: number;
  [key: string]: any;
}

interface PriceCalculationResult {
  unitPrice: number;
  source: string;
  formulaUsed?: string;
  debugInfo?: {
    mappingFound: boolean;
    mappingType?: 'individual' | 'categoryGroup';
    categoryGroupName?: string;
    formulaExpression?: string;
    variablesUsed?: Record<string, number>;
    calculationSteps?: string[];
  };
}

/**
 * 품목의 단가를 계산합니다.
 * 단가 수식 관리(ItemPriceMappingManager)에서 설정한 맵핑을 우선 적용합니다.
 */
export function calculateItemPrice(
  item: ItemMaster,
  variables: CalculationVariables,
  formulas: FormulaData[],
  categoryGroups: CategoryGroup[],
  pricings: PricingData[],
  priceMappings?: PriceMappingItem[]
): PriceCalculationResult {
  
  console.log(`\n🔍 [단가 계산 시작] ${item.itemCode} - ${item.itemName}`);
  console.log(`  📁 품목 카테고리: ${item.itemCategory || '없음'}`);
  
  // UP 변수에 품목 판매단가 추가
  const enrichedVariables = {
    ...variables,
    UP: item.sellingPrice || 0
  };
  
  console.log(`  💰 판매단가(UP): ${enrichedVariables.UP}`);
  
  // 1. 단가 맵핑 확인 (우선순위: 개별 품목 > 분류 그룹)
  if (priceMappings && priceMappings.length > 0) {
    console.log(`  🔎 단가 맵핑 검색 중... (총 ${priceMappings.length}개)`);
    
    // 1-1. 개별 품목 맵핑 찾기
    const individualMapping = priceMappings.find(m => 
      m.mappingType === 'individual' && 
      m.itemCode === item.itemCode &&
      m.enabled
    );
    
    if (individualMapping) {
      console.log(`  ✅ 개별 품목 맵핑 발견!`);
      const result = applyPriceMapping(individualMapping, item, enrichedVariables, formulas, 'individual');
      if (result) {
        console.log(`  ✨ 계산 완료 - 단가: ${result.unitPrice}원`);
        return result;
      }
    }
    
    // 1-2. 분류 그룹 맵핑 찾기
    if (item.itemCategory) {
      const categoryGroupMapping = priceMappings.find(m => {
        if (m.mappingType !== 'categoryGroup' || !m.enabled || !m.categoryGroupId) {
          return false;
        }
        
        const group = categoryGroups.find(g => g.id === m.categoryGroupId);
        const isInGroup = group?.categories.includes(item.itemCategory!);
        
        if (isInGroup) {
          console.log(`  ✅ 분류 그룹 맵핑 발견! 그룹: ${group?.name}`);
        }
        
        return isInGroup;
      });
      
      if (categoryGroupMapping) {
        const group = categoryGroups.find(g => g.id === categoryGroupMapping.categoryGroupId);
        const result = applyPriceMapping(categoryGroupMapping, item, enrichedVariables, formulas, 'categoryGroup', group?.name);
        if (result) {
          console.log(`  ✨ 계산 완료 - 단가: ${result.unitPrice}원`);
          return result;
        }
      }
    }
    
    console.log(`  ⚠️  맵핑 없음 - 기본 단가 사용`);
  }
  
  // 2. 맵핑이 없으면 pricing 데이터에서 직접 조회
  const pricing = findPricingData(item, pricings);
  const fallbackPrice = pricing?.salesPrice || pricing?.purchasePrice || item.sellingPrice || 0;
  
  console.log(`  📊 기본 단가: ${fallbackPrice}원 (출처: ${pricing ? 'Pricing' : 'ItemMaster'})`);
  
  return {
    unitPrice: fallbackPrice,
    source: pricing ? '단가 직접 조회' : '품목 판매단가',
    debugInfo: {
      mappingFound: false
    }
  };
}

/**
 * 단가 맵핑을 적용하여 단가를 계산합니다.
 */
function applyPriceMapping(
  mapping: PriceMappingItem,
  item: ItemMaster,
  variables: CalculationVariables,
  formulas: FormulaData[],
  mappingType: 'individual' | 'categoryGroup',
  categoryGroupName?: string
): PriceCalculationResult | null {
  
  console.log(`  🧮 맵핑 적용 중... (타입: ${mappingType})`);
  
  // 수식 찾기
  const formula = mapping.quantityFormula;
  
  if (!formula || formula.trim() === '') {
    console.error(`  ❌ 수식 없음`);
    return null;
  }
  
  console.log(`  📝 수식: ${formula}`);
  
  try {
    // 변수 치환
    let expression = formula;
    const variablesUsed: Record<string, number> = {};
    const calculationSteps: string[] = [];
    
    calculationSteps.push(`원본 수식: ${formula}`);
    
    // 변수 치환 (긴 변수명부터 먼저 처리)
    const sortedKeys = Object.keys(variables).sort((a, b) => b.length - a.length);
    
    for (const key of sortedKeys) {
      const value = variables[key];
      if (value !== undefined) {
        const regex = new RegExp(`\\b${key}\\b`, 'g');
        if (regex.test(expression)) {
          variablesUsed[key] = value;
          expression = expression.replace(regex, value.toString());
          console.log(`    ${key} = ${value}`);
        }
      }
    }
    
    calculationSteps.push(`변수 대입: ${expression}`);
    
    // 수식 계산
    const calculatedPrice = eval(expression);
    
    calculationSteps.push(`계산 결과: ${calculatedPrice}`);
    console.log(`  💵 계산된 단가: ${calculatedPrice}원`);
    
    return {
      unitPrice: calculatedPrice,
      source: mappingType === 'individual' 
        ? `개별 맵핑: ${item.itemCode}`
        : `분류 맵핑: ${categoryGroupName}`,
      formulaUsed: formula,
      debugInfo: {
        mappingFound: true,
        mappingType,
        categoryGroupName,
        formulaExpression: formula,
        variablesUsed,
        calculationSteps
      }
    };
  } catch (error) {
    console.error(`  ❌ 수식 계산 오류:`, error);
    return null;
  }
}

/**
 * pricing 데이터에서 품목 단가 찾기
 */
function findPricingData(item: ItemMaster, pricings: PricingData[]): PricingData | undefined {
  return pricings.find(p => 
    p.itemCode === item.itemCode || 
    p.itemId === item.id || 
    p.itemName === item.itemName
  );
}

/**
 * 여러 품목의 단가를 일괄 계산합니다.
 */
export function calculateBulkPrices(
  items: ItemMaster[],
  variables: CalculationVariables,
  formulas: FormulaData[],
  categoryGroups: CategoryGroup[],
  pricings: PricingData[],
  priceMappings?: PriceMappingItem[]
): Map<string, PriceCalculationResult> {
  
  console.log(`\n🚀 [일괄 단가 계산 시작] 총 ${items.length}개 품목`);
  
  const priceMap = new Map<string, PriceCalculationResult>();
  
  items.forEach(item => {
    const result = calculateItemPrice(item, variables, formulas, categoryGroups, pricings, priceMappings);
    priceMap.set(item.itemCode, result);
  });
  
  console.log(`✅ [일괄 단가 계산 완료]\n`);
  
  return priceMap;
}
