import React, { useState } from 'react';
import {
  Box,
  Paper,
  Typography,
  IconButton,
  Chip,
  useTheme,
  Tooltip,
  TextField,
  Select,
  MenuItem,
  FormControl,
  InputLabel,
  Grid,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Button,
  FormControlLabel,
  Radio,
  RadioGroup,
} from '@mui/material';
import {
  Delete as DeleteIcon,
  Add as AddIcon,
  AccountTree as TreeIcon,
  ShowChart as ChartIcon,
  Save as SaveIcon,
} from '@mui/icons-material';
import { useDraggable, useDroppable } from '@dnd-kit/core';
import { LogicNode, LogicNodeType } from '../../services/strategyDSLApi';
import { useIndicatorSettings } from '../../contexts/IndicatorSettingsContext';
import { useIndicatorVisibility } from '../../contexts/IndicatorVisibilityContext';
import { 
  saveCustomTemplate, 
  findTemplateByName,
  StrategyTemplate 
} from './strategyTemplates';

// ============================================================
// MUI Select 공통 MenuProps (드롭다운 메뉴 표시 문제 해결)
// ============================================================
const SELECT_MENU_PROPS = {
  disablePortal: false,
  PaperProps: {
    style: {
      maxHeight: 300,
    },
  },
};

// ============================================================
// 조건 타입 옵션
// ============================================================
const CONDITION_OPTIONS: { value: string; label: string }[] = [
  { value: 'GOLDEN_CROSS', label: '골든크로스 (상향 교차)' },
  { value: 'CROSS_UP', label: '상향 돌파' },
  { value: 'DEAD_CROSS', label: '데드크로스 (하향 교차)' },
  { value: 'CROSS_DOWN', label: '하향 돌파' },
  { value: 'ABOVE', label: '이상' },
  { value: 'BELOW', label: '이하' },
  { value: 'ZERO_CROSS_UP', label: '0선 상향 교차' },
  { value: 'ZERO_CROSS_DOWN', label: '0선 하향 교차' },
  { value: 'INCREASING', label: '상승 중' },
  { value: 'DECREASING', label: '하락 중' },
  { value: 'OVERBOUGHT', label: '과매수' },
  { value: 'OVERSOLD', label: '과매도' },
];

// ============================================================
// 지표별 허용 조건 매핑
// ============================================================
const INDICATOR_CONDITIONS: { [key: string]: string[] } = {
  'VOLUME': ['CROSS_UP', 'CROSS_DOWN', 'ABOVE', 'BELOW', 'INCREASING', 'DECREASING'],
  'MACD': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'STOCHASTIC': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'RSI': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'ADX': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'CCI': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'TRIX': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'DISPARITY': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'NEW_PSYCHOLOGICAL': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'INVEST_PSYCHOLOGICAL': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'WILLIAMS_R': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'BWI': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'VR': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'VOLUME_OSC': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'OBV': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'DMI': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'MA': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'EMA': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'BOLLINGER': [
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    'CROSS_UP', 'CROSS_DOWN',
    'SLOPE_UP', 'SLOPE_DOWN',
    'DIFF_GT', 'DIFF_LT',
    'HOLD_N_DAYS'
  ],
  'ICHIMOKU': [
    // 기본 비교
    'GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ',
    // 교차
    'CROSS_UP', 'CROSS_DOWN',
    // 구름 위치
    'ABOVE_CLOUD', 'BELOW_CLOUD', 'IN_CLOUD', 'CLOUD_BREAK_UP', 'CLOUD_BREAK_DOWN',
    // 구름 전환
    'SPAN1_GT_SPAN2', 'SPAN1_LT_SPAN2', 'SPAN1_CROSS_UP_SPAN2', 'SPAN1_CROSS_DOWN_SPAN2',
    // 후행스팬
    'LAGGING_GT_PRICE', 'LAGGING_LT_PRICE',
    // 기울기
    'SLOPE_UP', 'SLOPE_DOWN',
    // 차이
    'DIFF_GT', 'DIFF_LT',
    // 유지
    'HOLD_N_DAYS'
  ],
};

// ============================================================
// TreeNode Props
// ============================================================

export interface TreeNodeProps {
  node: LogicNode;
  onChange?: (updatedNode: LogicNode) => void;
  onEdit?: (nodeId: string) => void;
  onDelete?: (nodeId: string) => void;
  onAddChild?: (nodeId: string) => void;
  depth?: number;
  disabled?: boolean;
  signalType?: 'buy' | 'sell'; // 매수/매도 탭 구분
}

// ============================================================
// TreeNode 컴포넌트
// ============================================================

const TreeNode: React.FC<TreeNodeProps> = ({
  node,
  onChange,
  onEdit,
  onDelete,
  onAddChild,
  depth = 0,
  disabled = false,
  signalType = 'buy', // 기본값: 매수
}) => {
  const theme = useTheme();
  const { indicatorSettings } = useIndicatorSettings();
  const { settings: visibilitySettings } = useIndicatorVisibility();

  // 템플릿 저장 다이얼로그 상태
  const [saveDialogOpen, setSaveDialogOpen] = useState(false);
  const [templateName, setTemplateName] = useState('');
  const [templateSignal, setTemplateSignal] = useState<'buy' | 'sell'>('buy');
  const [templateDescription, setTemplateDescription] = useState('');

  // 드래그 설정 (노드 자체를 드래그 가능하게)
  const { attributes: dragAttributes, listeners: dragListeners, setNodeRef: setDragRef, isDragging } = useDraggable({
    id: `drag-${node.id}`,
    data: { node },
    disabled: disabled,
  });

  // 드롭 설정 (자식을 받을 수 있게)
  const { setNodeRef: setDropRef, isOver } = useDroppable({
    id: `drop-${node.id}`,
    data: { node },
    disabled: disabled || node.type === 'CONDITION',
  });

  // 노드 타입별 색상
  const getNodeColor = () => {
    switch (node.type) {
      case 'AND':
        return theme.palette.success.main;
      case 'OR':
        return theme.palette.info.main;
      case 'NOT':
        return theme.palette.warning.main;
      case 'CONDITION':
        return theme.palette.secondary.main;
      default:
        return theme.palette.grey[500];
    }
  };

  // 노드 타입별 라벨
  const getNodeLabel = () => {
    switch (node.type) {
      case 'AND':
        return 'AND (그리고)';
      case 'OR':
        return 'OR (또는)';
      case 'NOT':
        return 'NOT (반대)';
      case 'CONDITION':
        if (!node.condition) return '조건';
        
        const { indicatorType, conditionType, leftField, rightField } = node.condition;
        
        // MA는 CommonOperator 방식으로 처리
        if (indicatorType === 'MA') {
          // ✅ MA5, MA10... 형식을 실제 MA 설정에서 읽어서 라벨 생성
          const getMaLabel = (field: string | undefined) => {
            if (!field || field === 'NONE') return '';
            if (field === 'CLOSE_PRICE') return '종가';
            
            // MA5, MA10, MA20... 형식 파싱
            const periodMatch = field.match(/^MA(\d+)$/);
            if (periodMatch) {
              const period = parseInt(periodMatch[1]);
              // ✅ enabled된 MA만 필터링
              const enabledMAs = (visibilitySettings.maLines || []).filter(ma => ma.enabled);
              // ✅ 전체 MA 목록 (enabled/disabled 포함)
              const allMAs = visibilitySettings.maLines || [];
              
              console.log(`[TreeNode Label] field=${field}, period=${period}`);
              console.log(`[TreeNode Label] enabledMAs=`, enabledMAs.map(m => m.period));
              console.log(`[TreeNode Label] allMAs=`, allMAs.map(m => `${m.period}(${m.enabled ? 'ON' : 'OFF'})`));
              
              // 1단계: enabled된 MA 중에서 정확히 일치하는 것 찾기
              let maIndex = enabledMAs.findIndex(ma => ma.period === period);
              console.log(`[TreeNode Label] Step 1 - maIndex in enabledMAs: ${maIndex}`);
              
              if (maIndex >= 0) {
                const label = `MA${maIndex + 1}(${period}일)`;
                console.log(`[TreeNode Label] ✅ Found in enabled - label: ${label}`);
                return label;
              }
              
              // 2단계: 전체 MA 목록에서 찾기 (disabled 포함)
              const allIndex = allMAs.findIndex(ma => ma.period === period);
              console.log(`[TreeNode Label] Step 2 - allIndex in allMAs: ${allIndex}`);
              
              if (allIndex >= 0) {
                // 전체 목록에서의 인덱스 사용
                const label = `MA${allIndex + 1}(${period}일)`;
                console.log(`[TreeNode Label] ✅ Found in all (including disabled) - label: ${label}`);
                return label;
              }
              
              // 3단계: 가장 가까운 enabled MA 찾기
              if (enabledMAs.length > 0) {
                const closest = enabledMAs.reduce((prev, curr) => {
                  return Math.abs(curr.period - period) < Math.abs(prev.period - period) ? curr : prev;
                });
                const closestIndex = enabledMAs.findIndex(ma => ma.period === closest.period);
                const label = `MA${closestIndex + 1}(${closest.period}일)`;
                console.log(`[TreeNode Label] ⚠️  가장 가까운 MA 매핑: ${period}일 → ${label}`);
                return label;
              }
              
              // 4단계: 못 찾으면 기간만 표시
              console.log(`[TreeNode Label] ❌ Not found - returning: ${period}일`);
              return `${period}일`;
            }
            
            return field;
          };
          
          const leftLabel = getMaLabel(leftField);
          const rightLabel = getMaLabel(rightField);
          
          const conditionLabel = conditionType === 'CROSS_UP' ? '상향돌파' :
                                 conditionType === 'CROSS_DOWN' ? '하향돌파' :
                                 conditionType === 'GT' ? '>' :
                                 conditionType === 'LT' ? '<' : conditionType;
          
          const finalLabel = rightLabel ? `MA - ${leftLabel} ${conditionLabel} ${rightLabel}` : `MA - ${leftLabel} ${conditionLabel}`;
          console.log(`[TreeNode Label] Final MA label: ${finalLabel}`);
          return finalLabel;
        }
        
        return `${indicatorType} - ${conditionType}`;
      default:
        return '알 수 없음';
    }
  };

  // 노드 아이콘
  const getNodeIcon = () => {
    if (node.type === 'CONDITION') {
      return <ChartIcon fontSize="small" />;
    }
    return <TreeIcon fontSize="small" />;
  };

  // 템플릿 저장 버튼 클릭 핸들러
  const handleSaveAsTemplate = () => {
    if (node.type !== 'CONDITION' || !node.condition) {
      alert('조건 노드만 템플릿으로 저장할 수 있습니다.');
      return;
    }

    // metadata에서 템플릿 정보 추출 (있으면)
    let defaultName = `${node.condition.indicatorType} - ${node.condition.conditionType}`;
    let defaultSignal: 'buy' | 'sell' = 'buy';
    
    if (node.metadata) {
      try {
        const metadata = JSON.parse(node.metadata);
        if (metadata.templateName) {
          defaultName = metadata.templateName;
        }
        if (metadata.templateSignal) {
          defaultSignal = metadata.templateSignal;
        }
      } catch (error) {
        console.warn('메타데이터 파싱 실패:', error);
      }
    }
    
    setTemplateName(defaultName);
    setTemplateDescription('');
    setTemplateSignal(defaultSignal);
    setSaveDialogOpen(true);
  };

  // 템플릿 저장 실행
  const handleSaveTemplate = () => {
    if (!templateName.trim()) {
      alert('템플릿 이름을 입력하세요.');
      return;
    }

    if (node.type !== 'CONDITION' || !node.condition) {
      alert('조건 노드만 템플릿으로 저장할 수 있습니다.');
      return;
    }

    // 기존 템플릿 검색
    const existingTemplate = findTemplateByName(templateName);
    
    // 템플릿 ID 생성 (기존 템플릿이 있으면 같은 ID 사용, 없으면 새로 생성)
    const templateId = existingTemplate 
      ? existingTemplate.id 
      : `custom-${node.condition.indicatorType.toLowerCase()}-${Date.now()}`;

    const template: StrategyTemplate = {
      id: templateId,
      category: node.condition.indicatorType,
      categoryLabel: node.condition.indicatorType,
      signal: templateSignal,
      name: templateName,
      description: templateDescription || `사용자 정의 ${node.condition.indicatorType} 전략`,
      condition: { ...node },
    };

    const success = saveCustomTemplate(template);
    
    if (success) {
      if (existingTemplate) {
        alert(`템플릿 "${templateName}"이(가) 업데이트되었습니다.`);
      } else {
        alert(`템플릿 "${templateName}"이(가) 저장되었습니다.`);
      }
      
      // 템플릿 목록 새로고침을 위한 이벤트 발생
      window.dispatchEvent(new CustomEvent('templateSaved'));
      
      setSaveDialogOpen(false);
    } else {
      alert('템플릿 저장에 실패했습니다.');
    }
  };

  // 임계값 필드를 실제 설정값으로 변환
  const parseThresholdFieldValue = (fieldName: string, indicatorType: string): number | null => {
    // RSI 임계값
    if (indicatorType === 'RSI') {
      if (fieldName === 'OVERBOUGHT_70') return indicatorSettings.rsiOverbought;
      if (fieldName === 'NEUTRAL_50') return indicatorSettings.rsiMiddle;
      if (fieldName === 'OVERSOLD_30') return indicatorSettings.rsiOversold;
    }
    
    // CCI 임계값
    if (indicatorType === 'CCI') {
      if (fieldName === 'OVERBOUGHT_100') return indicatorSettings.cciOverbought;
      if (fieldName === 'NEUTRAL_0') return indicatorSettings.cciMiddle;
      if (fieldName === 'OVERSOLD_NEG100') return indicatorSettings.cciOversold;
    }
    
    // Stochastic 임계값
    if (indicatorType === 'STOCHASTIC') {
      if (fieldName === 'OVERBOUGHT_80') return indicatorSettings.stochasticOverbought;
      if (fieldName === 'NEUTRAL_50') return indicatorSettings.stochasticNeutral;
      if (fieldName === 'OVERSOLD_20') return indicatorSettings.stochasticOversold;
    }
    
    // Williams %R 임계값
    if (indicatorType === 'WILLIAMS_R') {
      if (fieldName === 'OVERBOUGHT_NEG20') return indicatorSettings.williamsROverbought;
      if (fieldName === 'NEUTRAL_NEG50') return indicatorSettings.williamsRMiddle;
      if (fieldName === 'OVERSOLD_NEG80') return indicatorSettings.williamsROversold;
    }
    
    // BWI 임계값
    if (indicatorType === 'BWI') {
      if (fieldName === 'OVERBOUGHT_80') return indicatorSettings.bwiOverbought;
      if (fieldName === 'NEUTRAL_50') return indicatorSettings.bwiMiddle;
      if (fieldName === 'OVERSOLD_20') return indicatorSettings.bwiOversold;
    }
    
    // ADX 임계값
    if (indicatorType === 'ADX') {
      if (fieldName === 'ADX_25' || fieldName === 'THRESHOLD_25') return indicatorSettings.adxStrongThreshold;
      if (fieldName === 'ADX_20' || fieldName === 'THRESHOLD_20') return indicatorSettings.adxWeakThreshold;
      if (fieldName === 'ADX_50') return 50.0; // 강한추세 상한
    }
    
    // 신심리도 임계값
    if (indicatorType === 'NEW_PSYCHOLOGICAL') {
      if (fieldName === 'OVERBOUGHT_75') return indicatorSettings.newPsychologicalOverbought;
      if (fieldName === 'NEUTRAL_50') return indicatorSettings.newPsychologicalMiddle;
      if (fieldName === 'OVERSOLD_25') return indicatorSettings.newPsychologicalOversold;
    }
    
    // 투자심리도 임계값
    if (indicatorType === 'INVEST_PSYCHOLOGICAL') {
      if (fieldName === 'OVERBOUGHT_75') return indicatorSettings.investPsychologicalOverbought;
      if (fieldName === 'NEUTRAL_50') return indicatorSettings.investPsychologicalMiddle;
      if (fieldName === 'OVERSOLD_25') return indicatorSettings.investPsychologicalOversold;
    }
    
    // TRIX 임계값
    if (indicatorType === 'TRIX') {
      if (fieldName === 'OVERBOUGHT_100') return indicatorSettings.trixOverbought;
      if (fieldName === 'NEUTRAL_0') return indicatorSettings.trixMiddle;
      if (fieldName === 'OVERSOLD_NEG100') return indicatorSettings.trixOversold;
    }
    
    // VR 임계값
    if (indicatorType === 'VR') {
      if (fieldName === 'OVERBOUGHT_200' || fieldName === 'OVERBOUGHT_150') return indicatorSettings.vrOverbought;
      if (fieldName === 'NEUTRAL_100') return indicatorSettings.vrBaseLine;
      if (fieldName === 'OVERSOLD_70' || fieldName === 'OVERSOLD_50') return indicatorSettings.vrOversold;
    }
    
    // DMI 임계값
    if (indicatorType === 'DMI') {
      if (fieldName === 'OVERBOUGHT_30') return indicatorSettings.dmiOverbought;
      if (fieldName === 'MIDDLE_20') return indicatorSettings.dmiMiddle;
      if (fieldName === 'OVERSOLD_10') return indicatorSettings.dmiOversold;
    }
    
    // DISPARITY 임계값
    if (indicatorType === 'DISPARITY') {
      if (fieldName === 'OVERBOUGHT_105') return 105.0;
      if (fieldName === 'NEUTRAL_100') return 100.0;
      if (fieldName === 'OVERSOLD_95') return 95.0;
    }
    
    // 공통 0선
    if (fieldName === 'ZERO_LINE') return 0.0;
    
    return null;
  };

  // 인덴트 계산 - depth > 0인 경우 공백 제거 (자식 노드는 부모 안에서 렌더링)
  const indentSize = 0;

  // 지표별 기간 옵션 가져오기 (IndicatorSettings 값 기반)
  const getPeriodOptionsForIndicator = (indicatorType: string): { value: number; label: string }[] => {
    const maShortOptions = [5, 10, 20];
    const maLongOptions = [10, 20, 60, 120];
    
    switch (indicatorType) {
      case 'RSI':
        return [
          { value: indicatorSettings.rsiPeriod, label: `${indicatorSettings.rsiPeriod}일 (현재 설정)` },
          { value: 6, label: '6일 (초단기)' },
          { value: 9, label: '9일 (단기)' },
          { value: 14, label: '14일 (기본)' },
          { value: 21, label: '21일 (장기)' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'MACD':
        return [
          { value: indicatorSettings.macdSignalPeriod, label: `${indicatorSettings.macdSignalPeriod}일 (시그널, 현재 설정)` },
          { value: indicatorSettings.macdFastPeriod, label: `${indicatorSettings.macdFastPeriod}일 (Fast)` },
          { value: indicatorSettings.macdSlowPeriod, label: `${indicatorSettings.macdSlowPeriod}일 (Slow)` },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'CCI':
        return [
          { value: indicatorSettings.cciPeriod, label: `${indicatorSettings.cciPeriod}일 (현재 설정)` },
          { value: indicatorSettings.cciSignalPeriod, label: `${indicatorSettings.cciSignalPeriod}일 (시그널)` },
          { value: 9, label: '9일 (단기)' },
          { value: 13, label: '13일' },
          { value: 20, label: '20일' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'STOCHASTIC':
        return [
          { value: indicatorSettings.stochasticKPeriod, label: `${indicatorSettings.stochasticKPeriod}일 (현재 설정)` },
          { value: 5, label: '5일 (단기)' },
          { value: 9, label: '9일' },
          { value: 14, label: '14일 (기본)' },
          { value: 21, label: '21일 (장기)' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'ADX':
        return [
          { value: indicatorSettings.adxPeriod, label: `${indicatorSettings.adxPeriod}일 (현재 설정)` },
          { value: 13, label: '13일' },
          { value: 14, label: '14일 (기본)' },
          { value: 21, label: '21일' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'OBV':
        return [
          { value: indicatorSettings.obvPeriod, label: `${indicatorSettings.obvPeriod}일 (현재 설정)` },
          { value: 5, label: '5일 (단기)' },
          { value: 10, label: '10일' },
          { value: 20, label: '20일' },
          { value: 60, label: '60일 (장기)' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'BWI':
        return [
          { value: indicatorSettings.bwiPeriod, label: `${indicatorSettings.bwiPeriod}일 (현재 설정)` },
          { value: 10, label: '10일 (단기)' },
          { value: 20, label: '20일 (기본)' },
          { value: 50, label: '50일 (장기)' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'DMI':
        return [
          { value: indicatorSettings.dmiPeriod, label: `${indicatorSettings.dmiPeriod}일 (현재 설정)` },
          { value: 14, label: '14일 (기본)' },
          { value: 21, label: '21일' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'WILLIAMS_R':
        return [
          { value: indicatorSettings.williamsRPeriod, label: `${indicatorSettings.williamsRPeriod}일 (현재 설정)` },
          { value: 11, label: '11일 (기본)' },
          { value: 14, label: '14일' },
          { value: 20, label: '20일' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'TRIX':
        return [
          { value: indicatorSettings.trixPeriod, label: `${indicatorSettings.trixPeriod}일 (현재 설정)` },
          { value: indicatorSettings.trixSignalPeriod, label: `${indicatorSettings.trixSignalPeriod}일 (시그널)` },
          { value: 9, label: '9일 (단기)' },
          { value: 12, label: '12일 (기본)' },
          { value: 18, label: '18일 (장기)' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'NEW_PSYCHOLOGICAL':
        return [
          { value: indicatorSettings.newPsychologicalPeriod, label: `${indicatorSettings.newPsychologicalPeriod}일 (현재 설정)` },
          { value: 10, label: '10일' },
          { value: 12, label: '12일 (기본)' },
          { value: 20, label: '20일' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'INVEST_PSYCHOLOGICAL':
        return [
          { value: indicatorSettings.investPsychologicalPeriod, label: `${indicatorSettings.investPsychologicalPeriod}일 (현재 설정)` },
          { value: 10, label: '10일' },
          { value: 12, label: '12일 (기본)' },
          { value: 20, label: '20일' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'VR':
        return [
          { value: indicatorSettings.vrPeriod, label: `${indicatorSettings.vrPeriod}일 (현재 설정)` },
          { value: 10, label: '10일' },
          { value: 14, label: '14일' },
          { value: 20, label: '20일 (기본)' },
          { value: 26, label: '26일' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'VOLUME_OSC':
        return [
          { value: indicatorSettings.volumeOscShortPeriod, label: `${indicatorSettings.volumeOscShortPeriod}일 (단기, 현재 설정)` },
          { value: indicatorSettings.volumeOscLongPeriod, label: `${indicatorSettings.volumeOscLongPeriod}일 (장기, 현재 설정)` },
          { value: 5, label: '5일 (단기)' },
          { value: 10, label: '10일' },
          { value: 20, label: '20일 (장기)' },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'DISPARITY':
        return [
          { value: indicatorSettings.disparityUltraShortPeriod, label: `${indicatorSettings.disparityUltraShortPeriod}일 (초단기)` },
          { value: indicatorSettings.disparityShortPeriod, label: `${indicatorSettings.disparityShortPeriod}일 (단기)` },
          { value: indicatorSettings.disparityMidPeriod, label: `${indicatorSettings.disparityMidPeriod}일 (중기)` },
          { value: indicatorSettings.disparityLongPeriod, label: `${indicatorSettings.disparityLongPeriod}일 (장기)` },
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'MA':
      case 'EMA':
        return [
          ...maShortOptions.map(v => ({ value: v, label: `${v}일 (단기)` })),
          ...maLongOptions.map(v => ({ value: v, label: `${v}일 (장기)` })),
        ].filter((opt, idx, arr) => arr.findIndex(o => o.value === opt.value) === idx);
      
      case 'BOLLINGER':
        return [
          { value: 10, label: '10일 (단기)' },
          { value: 20, label: '20일 (기본)' },
          { value: 50, label: '50일 (장기)' },
        ];
      
      case 'ICHIMOKU':
        return [
          { value: 9, label: '9일 (전환선)' },
          { value: 26, label: '26일 (기준선)' },
          { value: 52, label: '52일 (후행스팬)' },
        ];
      
      default:
        return [];
    }
  };

  // 지표별 조건 옵션 가져오기
  const getConditionOptionsForIndicator = (indicatorType: string): { value: string; label: string }[] => {
    const allowedConditions = INDICATOR_CONDITIONS[indicatorType] || [];
    return CONDITION_OPTIONS.filter(opt => allowedConditions.includes(opt.value));
  };

  // 지표별 기준값(targetValue) 옵션 가져오기 (IndicatorSettings 값 기반)
  const getTargetValueOptionsForIndicator = (indicatorType: string, conditionType: string): { value: number; label: string }[] => {
    switch (indicatorType) {
      case 'RSI':
        return [
          { value: indicatorSettings.rsiOverbought, label: getOverboughtLabel(`${indicatorSettings.rsiOverbought} (과매수)`) },
          { value: indicatorSettings.rsiMiddle, label: `${indicatorSettings.rsiMiddle} (중립)` },
          { value: indicatorSettings.rsiOversold, label: getOversoldLabel(`${indicatorSettings.rsiOversold} (과매도)`) },
        ];
      
      case 'CCI':
        return [
          { value: indicatorSettings.cciOverbought, label: getOverboughtLabel(`${indicatorSettings.cciOverbought} (과매수)`) },
          { value: indicatorSettings.cciMiddle, label: `${indicatorSettings.cciMiddle} (중립)` },
          { value: indicatorSettings.cciOversold, label: getOversoldLabel(`${indicatorSettings.cciOversold} (과매도)`) },
        ];
      
      case 'STOCHASTIC':
        return [
          { value: indicatorSettings.stochasticOverbought, label: getOverboughtLabel(`${indicatorSettings.stochasticOverbought} (과매수)`) },
          { value: indicatorSettings.stochasticNeutral, label: `${indicatorSettings.stochasticNeutral} (중립)` },
          { value: indicatorSettings.stochasticOversold, label: getOversoldLabel(`${indicatorSettings.stochasticOversold} (과매도)`) },
        ];
      
      case 'WILLIAMS_R':
        return [
          { value: indicatorSettings.williamsROverbought, label: getOverboughtLabel(`${indicatorSettings.williamsROverbought} (과매수)`) },
          { value: indicatorSettings.williamsRMiddle, label: `${indicatorSettings.williamsRMiddle} (중립)` },
          { value: indicatorSettings.williamsROversold, label: getOversoldLabel(`${indicatorSettings.williamsROversold} (과매도)`) },
        ];
      
      case 'BWI':
        return [
          { value: indicatorSettings.bwiOverbought, label: getOverboughtLabel(`${indicatorSettings.bwiOverbought} (과매수)`) },
          { value: indicatorSettings.bwiMiddle, label: `${indicatorSettings.bwiMiddle} (중립)` },
          { value: indicatorSettings.bwiOversold, label: getOversoldLabel(`${indicatorSettings.bwiOversold} (과매도)`) },
        ];
      
      case 'ADX':
        return [
          { value: indicatorSettings.adxStrongThreshold, label: `${indicatorSettings.adxStrongThreshold} (강한 추세)` },
          { value: indicatorSettings.adxWeakThreshold, label: `${indicatorSettings.adxWeakThreshold} (약한 추세)` },
        ];
      
      case 'NEW_PSYCHOLOGICAL':
        return [
          { value: indicatorSettings.newPsychologicalOverbought, label: `${indicatorSettings.newPsychologicalOverbought} (과열)` },
          { value: indicatorSettings.newPsychologicalMiddle, label: `${indicatorSettings.newPsychologicalMiddle} (중립)` },
          { value: indicatorSettings.newPsychologicalOversold, label: `${indicatorSettings.newPsychologicalOversold} (침체)` },
        ];
      
      case 'INVEST_PSYCHOLOGICAL':
        return [
          { value: indicatorSettings.investPsychologicalOverbought, label: `${indicatorSettings.investPsychologicalOverbought} (과열)` },
          { value: indicatorSettings.investPsychologicalMiddle, label: `${indicatorSettings.investPsychologicalMiddle} (중립)` },
          { value: indicatorSettings.investPsychologicalOversold, label: `${indicatorSettings.investPsychologicalOversold} (침체)` },
        ];
      
      case 'TRIX':
        return [
          { value: indicatorSettings.trixOverbought, label: `${indicatorSettings.trixOverbought} (과매수)` },
          { value: indicatorSettings.trixMiddle, label: `${indicatorSettings.trixMiddle} (중립)` },
          { value: indicatorSettings.trixOversold, label: `${indicatorSettings.trixOversold} (과매도)` },
        ];
      
      case 'VR':
        return [
          { value: indicatorSettings.vrOverbought, label: `${indicatorSettings.vrOverbought} (과열)` },
          { value: indicatorSettings.vrBaseLine, label: `${indicatorSettings.vrBaseLine} (기준선)` },
          { value: indicatorSettings.vrOversold, label: `${indicatorSettings.vrOversold} (침체)` },
        ];
      
      case 'DMI':
        return [
          { value: indicatorSettings.dmiOverbought, label: `${indicatorSettings.dmiOverbought} (과열)` },
          { value: indicatorSettings.dmiMiddle, label: `${indicatorSettings.dmiMiddle} (중간값)` },
          { value: indicatorSettings.dmiOversold, label: `${indicatorSettings.dmiOversold} (침체)` },
        ];
      
      case 'DISPARITY':
        return [
          { value: 102, label: '102% (과매수 기준)' },
          { value: 100, label: '100% (중립)' },
          { value: 98, label: '98% (과매도 기준)' },
        ];
      
      case 'MACD':
        return [
          { value: 0, label: '0 (중립선)' },
        ];
      
      case 'VOLUME_OSC':
        return [
          { value: 0, label: '0 (중립선)' },
        ];
      
      default:
        return [];
    }
  };

  // 공통 필드 기본값 적용 헬퍼 함수
  const applyCommonFieldDefaults = (condType: string, condition: any, defaultLeft: string, defaultRight: string, defaultSlope: string) => {
    const updated = { ...condition };
    
    if (['GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ', 'CROSS_UP', 'CROSS_DOWN'].includes(condType)) {
      updated.leftField = updated.leftField || defaultLeft;
      updated.rightField = updated.rightField || defaultRight;
    }
    else if (['SLOPE_UP', 'SLOPE_DOWN'].includes(condType)) {
      updated.leftField = updated.leftField || defaultSlope;
      updated.rightField = 'NONE';
      updated.slopePeriod = updated.slopePeriod || 3;
    }
    else if (['DIFF_GT', 'DIFF_LT'].includes(condType)) {
      updated.leftField = updated.leftField || defaultLeft;
      updated.rightField = updated.rightField || defaultRight;
      updated.compareValue = updated.compareValue || 0;
    }
    else if (condType === 'HOLD_N_DAYS') {
      updated.leftField = 'NONE';
      updated.rightField = 'NONE';
      updated.holdDays = updated.holdDays || 3;
    }
    
    return updated;
  };

  // 조건 값 변경 핸들러
  const handleConditionChange = (field: string, value: any) => {
    if (!node.condition || !onChange) return;

    let updatedCondition = {
      ...node.condition,
      [field]: value,
    };

    // rightField 변경 시 임계값 필드면 실제 설정값을 targetValue로 설정
    if (field === 'rightField' && value && typeof value === 'string') {
      const thresholdValue = parseThresholdFieldValue(value, node.condition.indicatorType);
      if (thresholdValue !== null) {
        updatedCondition.targetValue = thresholdValue;
        console.log(`🔢 임계값 필드 감지: ${value} → ${thresholdValue}`);
      }
    }

    // 일목균형표 조건 타입 변경 시 자동으로 필드 설정
    if (field === 'conditionType' && node.condition.indicatorType === 'ICHIMOKU') {
      const condType = value as string;
      
      // 기본 비교형, 교차형 - 전환선 vs 기준선 기본값
      if (['GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ', 'CROSS_UP', 'CROSS_DOWN'].includes(condType)) {
        updatedCondition.leftField = updatedCondition.leftField || 'CONVERSION_LINE';
        updatedCondition.rightField = updatedCondition.rightField || 'BASE_LINE';
      }
      // 구름 위치형 - 종가 vs 사용안함
      else if (['ABOVE_CLOUD', 'BELOW_CLOUD', 'IN_CLOUD', 'CLOUD_BREAK_UP', 'CLOUD_BREAK_DOWN'].includes(condType)) {
        updatedCondition.leftField = 'CLOSE_PRICE';
        updatedCondition.rightField = 'NONE';
      }
      // 구름 전환 - 선행스팬1 vs 선행스팬2
      else if (['SPAN1_GT_SPAN2', 'SPAN1_LT_SPAN2', 'SPAN1_CROSS_UP_SPAN2', 'SPAN1_CROSS_DOWN_SPAN2'].includes(condType)) {
        updatedCondition.leftField = 'LEADING_SPAN1';
        updatedCondition.rightField = 'LEADING_SPAN2';
      }
      // 후행스팬 - 후행스팬 vs 종가
      else if (['LAGGING_GT_PRICE', 'LAGGING_LT_PRICE'].includes(condType)) {
        updatedCondition.leftField = 'LAGGING_SPAN';
        updatedCondition.rightField = 'CLOSE_PRICE';
      }
      // 기울기형 - 전환선 vs 사용안함
      else if (['SLOPE_UP', 'SLOPE_DOWN'].includes(condType)) {
        updatedCondition.leftField = updatedCondition.leftField || 'CONVERSION_LINE';
        updatedCondition.rightField = 'NONE';
        updatedCondition.slopePeriod = updatedCondition.slopePeriod || 3;
      }
      // 차이형 - 전환선 vs 기준선
      else if (['DIFF_GT', 'DIFF_LT'].includes(condType)) {
        updatedCondition.leftField = updatedCondition.leftField || 'CONVERSION_LINE';
        updatedCondition.rightField = updatedCondition.rightField || 'BASE_LINE';
        updatedCondition.compareValue = updatedCondition.compareValue || 0;
      }
      // 유지형 - 사용안함 vs 사용안함
      else if (condType === 'HOLD_N_DAYS') {
        updatedCondition.leftField = 'NONE';
        updatedCondition.rightField = 'NONE';
        updatedCondition.holdDays = updatedCondition.holdDays || 3;
      }
    }

    // 볼린저밴드 조건 타입 변경 시 자동으로 필드 설정
    if (field === 'conditionType' && node.condition.indicatorType === 'BOLLINGER') {
      const condType = value as string;
      
      // 기본 비교형, 교차형 - 종가 vs 상단밴드 기본값
      if (['GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ', 'CROSS_UP', 'CROSS_DOWN'].includes(condType)) {
        updatedCondition.leftField = updatedCondition.leftField || 'CLOSE_PRICE';
        updatedCondition.rightField = updatedCondition.rightField || 'UPPER_BAND';
      }
      // 기울기형 - 상단밴드 vs 사용안함
      else if (['SLOPE_UP', 'SLOPE_DOWN'].includes(condType)) {
        updatedCondition.leftField = updatedCondition.leftField || 'UPPER_BAND';
        updatedCondition.rightField = 'NONE';
        updatedCondition.slopePeriod = updatedCondition.slopePeriod || 3;
      }
      // 차이형 - 상단밴드 vs 하단밴드
      else if (['DIFF_GT', 'DIFF_LT'].includes(condType)) {
        updatedCondition.leftField = updatedCondition.leftField || 'UPPER_BAND';
        updatedCondition.rightField = updatedCondition.rightField || 'LOWER_BAND';
        updatedCondition.compareValue = updatedCondition.compareValue || 0;
      }
      // 유지형 - 사용안함 vs 사용안함
      else if (condType === 'HOLD_N_DAYS') {
        updatedCondition.leftField = 'NONE';
        updatedCondition.rightField = 'NONE';
        updatedCondition.holdDays = updatedCondition.holdDays || 3;
      }
    }

    // MACD 조건 타입 변경 시 자동으로 필드 설정
    if (field === 'conditionType' && node.condition.indicatorType === 'MACD') {
      const condType = value as string;
      
      if (['GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ', 'CROSS_UP', 'CROSS_DOWN'].includes(condType)) {
        updatedCondition.leftField = updatedCondition.leftField || 'MACD_LINE';
        updatedCondition.rightField = updatedCondition.rightField || 'SIGNAL_LINE';
      }
      else if (['SLOPE_UP', 'SLOPE_DOWN'].includes(condType)) {
        updatedCondition.leftField = updatedCondition.leftField || 'MACD_LINE';
        updatedCondition.rightField = 'NONE';
        updatedCondition.slopePeriod = updatedCondition.slopePeriod || 3;
      }
      else if (['DIFF_GT', 'DIFF_LT'].includes(condType)) {
        updatedCondition.leftField = updatedCondition.leftField || 'MACD_LINE';
        updatedCondition.rightField = updatedCondition.rightField || 'ZERO_LINE';
        updatedCondition.compareValue = updatedCondition.compareValue || 0;
      }
      else if (condType === 'HOLD_N_DAYS') {
        updatedCondition.leftField = 'NONE';
        updatedCondition.rightField = 'NONE';
        updatedCondition.holdDays = updatedCondition.holdDays || 3;
      }
    }

    // RSI 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'RSI') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'RSI_VALUE', 'OVERBOUGHT_70', 'RSI_VALUE');
    }

    // Stochastic 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'STOCHASTIC') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'STOCH_K', 'STOCH_D', 'STOCH_K');
    }

    // CCI 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'CCI') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'CCI_VALUE', 'OVERBOUGHT_100', 'CCI_VALUE');
    }

    // ADX 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'ADX') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'ADX_VALUE', 'ADX_25', 'ADX_VALUE');
    }

    // TRIX 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'TRIX') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'TRIX_VALUE', 'TRIX_SIGNAL', 'TRIX_VALUE');
    }

    // DMI 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'DMI') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'PDI', 'MDI', 'PDI');
    }

    // OBV 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'OBV') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'OBV_LINE', 'OBV_SIGNAL', 'OBV_LINE');
    }

    // VOLUME 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'VOLUME') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'VOLUME_VALUE', 'VOLUME_MA', 'VOLUME_VALUE');
    }

    // MA 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'MA') {
      // ✅ 동적으로 활성화된 MA 기본값 설정
      const enabledMAs = (visibilitySettings.maLines || []).filter(ma => ma.enabled);
      const defaultLeft = enabledMAs.length > 0 ? `MA${enabledMAs[0].period}` : 'CLOSE_PRICE';
      const defaultRight = enabledMAs.length > 1 ? `MA${enabledMAs[1].period}` : 'CLOSE_PRICE';
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, defaultLeft, defaultRight, defaultLeft);
    }

    // DISPARITY 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'DISPARITY') {
      const ultraShortPeriod = indicatorSettings.disparityUltraShortPeriod || 5;
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, `DISPARITY${ultraShortPeriod}`, 'NEUTRAL_100', `DISPARITY${ultraShortPeriod}`);
    }

    // NEW_PSYCHOLOGICAL 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'NEW_PSYCHOLOGICAL') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'NEW_PSY_VALUE', 'OVERBOUGHT_75', 'NEW_PSY_VALUE');
    }

    // INVEST_PSYCHOLOGICAL 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'INVEST_PSYCHOLOGICAL') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'INVEST_PSY_VALUE', 'OVERBOUGHT_75', 'INVEST_PSY_VALUE');
    }

    // WILLIAMS_R 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'WILLIAMS_R') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'WILLIAMS_R_VALUE', 'OVERBOUGHT_NEG20', 'WILLIAMS_R_VALUE');
    }

    // BWI 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'BWI') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'BWI_VALUE', 'OVERBOUGHT_80', 'BWI_VALUE');
    }

    // VR 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'VR') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'VR_VALUE', 'OVERBOUGHT_200', 'VR_VALUE');
    }

    // VOLUME_OSC 조건 타입 변경 시
    if (field === 'conditionType' && node.condition.indicatorType === 'VOLUME_OSC') {
      updatedCondition = applyCommonFieldDefaults(value as string, updatedCondition, 'VOLUME_OSC_VALUE', 'ZERO_LINE', 'VOLUME_OSC_VALUE');
    }

    const updatedNode = {
      ...node,
      condition: updatedCondition,
    };
    onChange(updatedNode);
  };

  // MA/EMA 조건의 상세 정보 (특별한 UI)
  const getMAConditionDetails = () => {
    if (node.type !== 'CONDITION' || !node.condition) return null;

    const { indicatorType, conditionType, period, targetValue } = node.condition;
    
    // MA 라인 옵션 (MA1(5), MA2(10), MA3(20), MA4(60) - 사용자 요청)
    const maLineOptions = visibilitySettings.maLines
      .filter(line => ['MA1', 'MA2', 'MA3', 'MA4'].includes(line.id))
      .map(line => ({
        id: line.id,
        period: line.period,
        label: `${line.id}(${line.period}일)`,
      }));
    
    // 조건 옵션 (골든크로스, 데드크로스, 상향, 하향)
    const maConditionOptions = [
      { value: 'GOLDEN_CROSS', label: '골든크로스 (상향 교차)' },
      { value: 'DEAD_CROSS', label: '데드크로스 (하향 교차)' },
      { value: 'ABOVE', label: '상향 (위에 위치)' },
      { value: 'BELOW', label: '하향 (아래 위치)' },
    ];
    
    return (
      <Box sx={{ mt: 1.5 }}>
        <Grid container spacing={1.5}>
          {/* 단기선 선택 */}
          <Grid item xs={4}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>단기선</InputLabel>
              <Select
                value={period || maLineOptions[0]?.period || 5}
                label="단기선"
                onChange={(e) => handleConditionChange('period', Number(e.target.value))}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  '& .MuiSelect-select': { 
                    fontSize: '0.875rem',
                    py: 0.75,
                  }
                }}
              >
                {maLineOptions.map((option) => (
                  <MenuItem key={option.id} value={option.period}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          {/* 장기선 선택 */}
          <Grid item xs={4}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>장기선</InputLabel>
              <Select
                value={targetValue || maLineOptions[1]?.period || 10}
                label="장기선"
                onChange={(e) => handleConditionChange('targetValue', Number(e.target.value))}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  '& .MuiSelect-select': { 
                    fontSize: '0.875rem',
                    py: 0.75,
                  }
                }}
              >
                {maLineOptions.map((option) => (
                  <MenuItem key={option.id} value={option.period}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          {/* 조건 선택 */}
          <Grid item xs={4}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건</InputLabel>
              <Select
                value={conditionType || 'GOLDEN_CROSS'}
                label="조건"
                onChange={(e) => handleConditionChange('conditionType', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  '& .MuiSelect-select': { 
                    fontSize: '0.875rem',
                    py: 0.75,
                  }
                }}
              >
                {maConditionOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>
        </Grid>
      </Box>
    );
  };

  // MACD 조건 상세 정보
  const getMacdConditionDetails = () => {
    if (node.type !== 'CONDITION' || !node.condition) return null;

    const { conditionType, leftField, rightField, compareValue, slopePeriod, holdDays, candleRange } = node.condition;
    
    // ✅ 실제 설정된 MACD 기간값 읽기
    const fastPeriod = indicatorSettings.macdFastPeriod || 12;
    const slowPeriod = indicatorSettings.macdSlowPeriod || 26;
    const signalPeriod = indicatorSettings.macdSignalPeriod || 9;
    
    // 필드 옵션 (기간값 표시)
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'MACD_LINE', label: `MACD 라인(${fastPeriod}일/${slowPeriod}일)` },
      { value: 'SIGNAL_LINE', label: `시그널 라인(${signalPeriod}일)` },
      { value: 'HISTOGRAM', label: '히스토그램' },
      { value: 'ZERO_LINE', label: '0선' },
    ];
    
    // 조건 옵션
    const macdConditionOptions = [
      { value: 'GT', label: '초과 (>)' },
      { value: 'LT', label: '미만 (<)' },
      { value: 'GTE', label: '이상 (>=)' },
      { value: 'LTE', label: '이하 (<=)' },
      { value: 'EQ', label: '같음 (==)' },
      { value: 'NEQ', label: '다름 (!=)' },
      { value: 'CROSS_UP', label: '상향 돌파' },
      { value: 'CROSS_DOWN', label: '하향 돌파' },
      { value: 'SLOPE_UP', label: '상승 기울기' },
      { value: 'SLOPE_DOWN', label: '하락 기울기' },
      { value: 'DIFF_GT', label: '차이 > 값' },
      { value: 'DIFF_LT', label: '차이 < 값' },
      { value: 'HOLD_N_DAYS', label: 'N일 연속 유지' },
    ];
    
    const getFieldSettings = (condType: string) => {
      if (['GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ', 'CROSS_UP', 'CROSS_DOWN', 'DIFF_GT', 'DIFF_LT'].includes(condType)) {
        return {
          leftValue: leftField || 'MACD_LINE',
          leftDisabled: false,
          rightValue: rightField || 'SIGNAL_LINE',
          rightDisabled: false
        };
      }
      
      if (['SLOPE_UP', 'SLOPE_DOWN'].includes(condType)) {
        return {
          leftValue: leftField || 'MACD_LINE',
          leftDisabled: false,
          rightValue: 'NONE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      if (condType === 'HOLD_N_DAYS') {
        return {
          leftValue: 'NONE',
          leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
          rightValue: 'NONE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      return {
        leftValue: leftField || 'NONE',
        leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        rightValue: rightField || 'NONE',
        rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
      };
    };
    
    const fieldSettings = getFieldSettings(conditionType || '');
    const needsCompareValue = ['DIFF_GT', 'DIFF_LT'].includes(conditionType || '');
    const needsSlopePeriod = ['SLOPE_UP', 'SLOPE_DOWN'].includes(conditionType || '');
    const needsHoldDays = conditionType === 'HOLD_N_DAYS';
    
    return (
      <Box sx={{ mt: 1.5 }}>
        <Grid container spacing={1.5}>
          {/* 캔들 범위 선택 */}
          <Grid item xs={12} sm={3}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>캔들 범위</InputLabel>
              <Select
                value={candleRange || 1}
                label="캔들 범위"
                onChange={(e) => handleConditionChange('candleRange', Number(e.target.value))}
                sx={{ fontSize: '0.875rem' }}
                MenuProps={SELECT_MENU_PROPS}
              >
                <MenuItem value={1} sx={{ fontSize: '0.875rem' }}>현재 캔들</MenuItem>
                <MenuItem value={2} sx={{ fontSize: '0.875rem' }}>2개 캔들</MenuItem>
                <MenuItem value={3} sx={{ fontSize: '0.875rem' }}>3개 캔들</MenuItem>
                <MenuItem value={4} sx={{ fontSize: '0.875rem' }}>4개 캔들</MenuItem>
                <MenuItem value={5} sx={{ fontSize: '0.875rem' }}>5개 캔들</MenuItem>
              </Select>
            </FormControl>
          </Grid>
          
          <Grid item xs={12} sm={3}>
            <FormControl size="small" fullWidth disabled={disabled || fieldSettings.leftDisabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건대상1</InputLabel>
              <Select
                value={fieldSettings.leftValue}
                label="조건대상1"
                onChange={(e) => handleConditionChange('leftField', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  fontSize: '0.875rem',
                  backgroundColor: fieldSettings.leftDisabled ? '#f5f5f5' : 'transparent'
                }}
              >
                {fieldOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value} sx={{ fontSize: '0.875rem' }}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          <Grid item xs={12} sm={3}>
            <FormControl size="small" fullWidth disabled={disabled || fieldSettings.rightDisabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건대상2</InputLabel>
              <Select
                value={fieldSettings.rightValue}
                label="조건대상2"
                onChange={(e) => handleConditionChange('rightField', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  fontSize: '0.875rem',
                  backgroundColor: fieldSettings.rightDisabled ? '#f5f5f5' : 'transparent'
                }}
              >
                {fieldOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value} sx={{ fontSize: '0.875rem' }}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          <Grid item xs={12} sm={3}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건</InputLabel>
              <Select
                value={conditionType || 'GT'}
                label="조건"
                onChange={(e) => handleConditionChange('conditionType', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ fontSize: '0.875rem' }}
              >
                {macdConditionOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value} sx={{ fontSize: '0.875rem' }}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          {needsCompareValue && (
            <Grid item xs={12}>
              <TextField
                label="비교값"
                type="number"
                value={compareValue || ''}
                onChange={(e) => handleConditionChange('compareValue', parseFloat(e.target.value))}
                size="small"
                fullWidth
                disabled={disabled}
                InputProps={{ sx: { fontSize: '0.875rem' } }}
                InputLabelProps={{ sx: { fontSize: '0.875rem' } }}
                placeholder="예: 0.5"
              />
            </Grid>
          )}

          {needsSlopePeriod && (
            <Grid item xs={12}>
              <TextField
                label="기울기 기간 (일)"
                type="number"
                value={slopePeriod || ''}
                onChange={(e) => handleConditionChange('slopePeriod', parseInt(e.target.value))}
                size="small"
                fullWidth
                disabled={disabled}
                InputProps={{ sx: { fontSize: '0.875rem' } }}
                InputLabelProps={{ sx: { fontSize: '0.875rem' } }}
                placeholder="예: 5"
                inputProps={{ min: 1, max: 100 }}
              />
            </Grid>
          )}

          {needsHoldDays && (
            <Grid item xs={12}>
              <TextField
                label="유지 일수 (일)"
                type="number"
                value={holdDays || ''}
                onChange={(e) => handleConditionChange('holdDays', parseInt(e.target.value))}
                size="small"
                fullWidth
                disabled={disabled}
                InputProps={{ sx: { fontSize: '0.875rem' } }}
                InputLabelProps={{ sx: { fontSize: '0.875rem' } }}
                placeholder="예: 3"
                inputProps={{ min: 1, max: 30 }}
              />
            </Grid>
          )}
        </Grid>
      </Box>
    );
  };

  // 볼린저밴드 조건 상세 정보
  const getBollingerConditionDetails = () => {
    if (node.type !== 'CONDITION' || !node.condition) return null;

    const { conditionType, leftField, rightField, compareValue, slopePeriod, holdDays, candleRange } = node.condition;
    
    // ✅ 실제 설정된 볼린저밴드 기간값 읽기
    const bbPeriod = visibilitySettings.bollingerPeriod || 20;
    const bbStdDev = visibilitySettings.bollingerStdDev || 2;
    
    // 필드 옵션 (기간값 표시)
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'UPPER_BAND', label: `상단밴드(${bbPeriod}일, σ${bbStdDev})` },
      { value: 'MIDDLE_BAND', label: `중심선(${bbPeriod}일)` },
      { value: 'LOWER_BAND', label: `하단밴드(${bbPeriod}일, σ${bbStdDev})` },
      { value: 'CLOSE_PRICE', label: '종가' },
      { value: 'OPEN_PRICE', label: '시가' },
      { value: 'HIGH_PRICE', label: '고가' },
      { value: 'LOW_PRICE', label: '저가' },
    ];
    
    // 조건 옵션 (13개)
    const bollingerConditionOptions = [
      { value: 'GT', label: '초과 (>)' },
      { value: 'LT', label: '미만 (<)' },
      { value: 'GTE', label: '이상 (>=)' },
      { value: 'LTE', label: '이하 (<=)' },
      { value: 'EQ', label: '같음 (==)' },
      { value: 'NEQ', label: '다름 (!=)' },
      { value: 'CROSS_UP', label: '상향 돌파' },
      { value: 'CROSS_DOWN', label: '하향 돌파' },
      { value: 'SLOPE_UP', label: '상승 기울기' },
      { value: 'SLOPE_DOWN', label: '하락 기울기' },
      { value: 'DIFF_GT', label: '차이 > 값' },
      { value: 'DIFF_LT', label: '차이 < 값' },
      { value: 'HOLD_N_DAYS', label: 'N일 연속 유지' },
    ];
    
    // 조건 타입에 따른 필드 설정
    const getFieldSettings = (condType: string) => {
      // 기본 비교형, 교차형, 차이형 - 둘 다 선택 가능
      if (['GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ', 'CROSS_UP', 'CROSS_DOWN', 'DIFF_GT', 'DIFF_LT'].includes(condType)) {
        return {
          leftValue: leftField || 'CLOSE_PRICE',
          leftDisabled: false,
          rightValue: rightField || 'UPPER_BAND',
          rightDisabled: false
        };
      }
      
      // 기울기형 - 조건대상1: 선택 가능, 조건대상2: 사용안함(고정)
      if (['SLOPE_UP', 'SLOPE_DOWN'].includes(condType)) {
        return {
          leftValue: leftField || 'UPPER_BAND',
          leftDisabled: false,
          rightValue: 'NONE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      // 유지형 - 조건대상1: 사용안함, 조건대상2: 사용안함
      if (condType === 'HOLD_N_DAYS') {
        return {
          leftValue: 'NONE',
          leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
          rightValue: 'NONE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      // 기본값
      return {
        leftValue: leftField || 'NONE',
        leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        rightValue: rightField || 'NONE',
        rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
      };
    };
    
    const fieldSettings = getFieldSettings(conditionType || '');
    const needsCompareValue = ['DIFF_GT', 'DIFF_LT'].includes(conditionType || '');
    const needsSlopePeriod = ['SLOPE_UP', 'SLOPE_DOWN'].includes(conditionType || '');
    const needsHoldDays = conditionType === 'HOLD_N_DAYS';
    
    return (
      <Box sx={{ mt: 1.5 }}>
        <Grid container spacing={1.5}>
          {/* 캔들 범위 선택 */}
          <Grid item xs={12} sm={3}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>캔들 범위</InputLabel>
              <Select
                value={candleRange || 1}
                label="캔들 범위"
                onChange={(e) => handleConditionChange('candleRange', Number(e.target.value))}
                sx={{ fontSize: '0.875rem' }}
                MenuProps={SELECT_MENU_PROPS}
              >
                <MenuItem value={1} sx={{ fontSize: '0.875rem' }}>현재 캔들</MenuItem>
                <MenuItem value={2} sx={{ fontSize: '0.875rem' }}>2개 캔들</MenuItem>
                <MenuItem value={3} sx={{ fontSize: '0.875rem' }}>3개 캔들</MenuItem>
                <MenuItem value={4} sx={{ fontSize: '0.875rem' }}>4개 캔들</MenuItem>
                <MenuItem value={5} sx={{ fontSize: '0.875rem' }}>5개 캔들</MenuItem>
              </Select>
            </FormControl>
          </Grid>
          
          {/* 조건대상1 - 항상 표시 */}
          <Grid item xs={12} sm={3}>
            <FormControl size="small" fullWidth disabled={disabled || fieldSettings.leftDisabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건대상1</InputLabel>
              <Select
                value={fieldSettings.leftValue}
                label="조건대상1"
                onChange={(e) => handleConditionChange('leftField', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  fontSize: '0.875rem',
                  backgroundColor: fieldSettings.leftDisabled ? '#f5f5f5' : 'transparent'
                }}
              >
                {fieldOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value} sx={{ fontSize: '0.875rem' }}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          {/* 조건대상2 - 항상 표시 */}
          <Grid item xs={12} sm={3}>
            <FormControl size="small" fullWidth disabled={disabled || fieldSettings.rightDisabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건대상2</InputLabel>
              <Select
                value={fieldSettings.rightValue}
                label="조건대상2"
                onChange={(e) => handleConditionChange('rightField', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  fontSize: '0.875rem',
                  backgroundColor: fieldSettings.rightDisabled ? '#f5f5f5' : 'transparent'
                }}
              >
                {fieldOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value} sx={{ fontSize: '0.875rem' }}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          {/* 조건 드롭다운 */}
          <Grid item xs={12} sm={3}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건</InputLabel>
              <Select
                value={conditionType || 'GT'}
                label="조건"
                onChange={(e) => handleConditionChange('conditionType', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ fontSize: '0.875rem' }}
              >
                {bollingerConditionOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value} sx={{ fontSize: '0.875rem' }}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          {/* compareValue 입력 (DIFF_GT, DIFF_LT) */}
          {needsCompareValue && (
            <Grid item xs={12}>
              <TextField
                label="비교값"
                type="number"
                value={compareValue || ''}
                onChange={(e) => handleConditionChange('compareValue', parseFloat(e.target.value))}
                size="small"
                fullWidth
                disabled={disabled}
                InputProps={{ sx: { fontSize: '0.875rem' } }}
                InputLabelProps={{ sx: { fontSize: '0.875rem' } }}
                placeholder="예: 1.0"
              />
            </Grid>
          )}

          {/* slopePeriod 입력 (SLOPE_UP, SLOPE_DOWN) */}
          {needsSlopePeriod && (
            <Grid item xs={12}>
              <TextField
                label="기울기 기간 (일)"
                type="number"
                value={slopePeriod || ''}
                onChange={(e) => handleConditionChange('slopePeriod', parseInt(e.target.value))}
                size="small"
                fullWidth
                disabled={disabled}
                InputProps={{ sx: { fontSize: '0.875rem' } }}
                InputLabelProps={{ sx: { fontSize: '0.875rem' } }}
                placeholder="예: 5"
                inputProps={{ min: 1, max: 100 }}
              />
            </Grid>
          )}

          {/* holdDays 입력 (HOLD_N_DAYS) */}
          {needsHoldDays && (
            <Grid item xs={12}>
              <TextField
                label="유지 일수 (일)"
                type="number"
                value={holdDays || ''}
                onChange={(e) => handleConditionChange('holdDays', parseInt(e.target.value))}
                size="small"
                fullWidth
                disabled={disabled}
                InputProps={{ sx: { fontSize: '0.875rem' } }}
                InputLabelProps={{ sx: { fontSize: '0.875rem' } }}
                placeholder="예: 3"
                inputProps={{ min: 1, max: 30 }}
              />
            </Grid>
          )}
        </Grid>
      </Box>
    );
  };

  // 일목균형표 조건 상세 정보
  const getIchimokuConditionDetails = () => {
    if (node.type !== 'CONDITION' || !node.condition) return null;

    const { conditionType, leftField, rightField, compareValue, slopePeriod, holdDays, candleRange } = node.condition;
    
    // ✅ 실제 설정된 일목균형표 기간값 읽기
    const tenkanPeriod = visibilitySettings.ichimokuTenkanPeriod || 9;
    const kijunPeriod = visibilitySettings.ichimokuKijunPeriod || 26;
    const senkouBPeriod = visibilitySettings.ichimokuSenkouBPeriod || 52;
    
    // 필드 옵션 (기간값 표시)
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'CONVERSION_LINE', label: `전환선(${tenkanPeriod}일)` },
      { value: 'BASE_LINE', label: `기준선(${kijunPeriod}일)` },
      { value: 'LEADING_SPAN1', label: `선행스팬1` },
      { value: 'LEADING_SPAN2', label: `선행스팬2(${senkouBPeriod}일)` },
      { value: 'LAGGING_SPAN', label: '후행스팬' },
      { value: 'CLOSE_PRICE', label: '종가' },
      { value: 'OPEN_PRICE', label: '시가' },
      { value: 'HIGH_PRICE', label: '고가' },
      { value: 'LOW_PRICE', label: '저가' },
    ];
    
    // 조건 옵션 (27개)
    const ichimokuConditionOptions = [
      { value: 'GT', label: '초과 (>)' },
      { value: 'LT', label: '미만 (<)' },
      { value: 'GTE', label: '이상 (>=)' },
      { value: 'LTE', label: '이하 (<=)' },
      { value: 'EQ', label: '같음 (==)' },
      { value: 'NEQ', label: '다름 (!=)' },
      { value: 'CROSS_UP', label: '상향 돌파' },
      { value: 'CROSS_DOWN', label: '하향 돌파' },
      { value: 'ABOVE_CLOUD', label: '구름 위' },
      { value: 'BELOW_CLOUD', label: '구름 아래' },
      { value: 'IN_CLOUD', label: '구름 안' },
      { value: 'CLOUD_BREAK_UP', label: '구름 상향 돌파' },
      { value: 'CLOUD_BREAK_DOWN', label: '구름 하향 돌파' },
      { value: 'SPAN1_GT_SPAN2', label: '선행스팬1 > 선행스팬2' },
      { value: 'SPAN1_LT_SPAN2', label: '선행스팬1 < 선행스팬2' },
      { value: 'SPAN1_CROSS_UP_SPAN2', label: '선행스팬1 상향돌파 선행스팬2' },
      { value: 'SPAN1_CROSS_DOWN_SPAN2', label: '선행스팬1 하향돌파 선행스팬2' },
      { value: 'LAGGING_GT_PRICE', label: '후행스팬 > 가격' },
      { value: 'LAGGING_LT_PRICE', label: '후행스팬 < 가격' },
      { value: 'SLOPE_UP', label: '상승 기울기' },
      { value: 'SLOPE_DOWN', label: '하락 기울기' },
      { value: 'DIFF_GT', label: '차이 > 값' },
      { value: 'DIFF_LT', label: '차이 < 값' },
      { value: 'HOLD_N_DAYS', label: 'N일 연속 유지' },
    ];
    
    // 조건 타입에 따른 필드 설정
    const getFieldSettings = (condType: string) => {
      // 기본 비교형, 교차형, 차이형 - 둘 다 선택 가능
      if (['GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ', 'CROSS_UP', 'CROSS_DOWN', 'DIFF_GT', 'DIFF_LT'].includes(condType)) {
        return {
          leftValue: leftField || 'CONVERSION_LINE',
          leftDisabled: false,
          rightValue: rightField || 'BASE_LINE',
          rightDisabled: false
        };
      }
      
      // 구름 위치형 - 조건대상1: 선택안함(고정), 조건대상2: 선택안함(고정)
      if (['ABOVE_CLOUD', 'BELOW_CLOUD', 'IN_CLOUD', 'CLOUD_BREAK_UP', 'CLOUD_BREAK_DOWN'].includes(condType)) {
        return {
          leftValue: 'NONE',
          leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
          rightValue: 'NONE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      // 구름 전환 - 조건대상1: 선행스팬1(고정), 조건대상2: 선행스팬2(고정)
      if (['SPAN1_GT_SPAN2', 'SPAN1_LT_SPAN2', 'SPAN1_CROSS_UP_SPAN2', 'SPAN1_CROSS_DOWN_SPAN2'].includes(condType)) {
        return {
          leftValue: 'LEADING_SPAN1',
          leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
          rightValue: 'LEADING_SPAN2',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      // 후행스팬 - 조건대상1: 후행스팬(고정), 조건대상2: 종가(고정)
      if (['LAGGING_GT_PRICE', 'LAGGING_LT_PRICE'].includes(condType)) {
        return {
          leftValue: 'LAGGING_SPAN',
          leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
          rightValue: 'CLOSE_PRICE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      // 기울기형 - 조건대상1: 선택 가능, 조건대상2: 사용안함(고정)
      if (['SLOPE_UP', 'SLOPE_DOWN'].includes(condType)) {
        return {
          leftValue: leftField || 'CONVERSION_LINE',
          leftDisabled: false,
          rightValue: 'NONE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      // 유지형 - 조건대상1: 사용안함, 조건대상2: 사용안함
      if (condType === 'HOLD_N_DAYS') {
        return {
          leftValue: 'NONE',
          leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
          rightValue: 'NONE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      // 기본값
      return {
        leftValue: leftField || 'NONE',
        leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        rightValue: rightField || 'NONE',
        rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
      };
    };
    
    const fieldSettings = getFieldSettings(conditionType || '');
    const needsCompareValue = ['DIFF_GT', 'DIFF_LT'].includes(conditionType || '');
    const needsSlopePeriod = ['SLOPE_UP', 'SLOPE_DOWN'].includes(conditionType || '');
    const needsHoldDays = conditionType === 'HOLD_N_DAYS';
    
    return (
      <Box sx={{ mt: 1.5 }}>
        <Grid container spacing={1.5}>
          {/* 캔들 범위 선택 */}
          <Grid item xs={12} sm={4}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>캔들 범위</InputLabel>
              <Select
                value={candleRange || 1}
                label="캔들 범위"
                onChange={(e) => handleConditionChange('candleRange', Number(e.target.value))}
                sx={{ fontSize: '0.875rem' }}
                MenuProps={SELECT_MENU_PROPS}
              >
                <MenuItem value={1} sx={{ fontSize: '0.875rem' }}>현재 캔들</MenuItem>
                <MenuItem value={2} sx={{ fontSize: '0.875rem' }}>2개 캔들</MenuItem>
                <MenuItem value={3} sx={{ fontSize: '0.875rem' }}>3개 캔들</MenuItem>
                <MenuItem value={4} sx={{ fontSize: '0.875rem' }}>4개 캔들</MenuItem>
                <MenuItem value={5} sx={{ fontSize: '0.875rem' }}>5개 캔들</MenuItem>
              </Select>
            </FormControl>
          </Grid>
          
          {/* 조건대상1 - 항상 표시 */}
          <Grid item xs={12} sm={4}>
            <FormControl size="small" fullWidth disabled={disabled || fieldSettings.leftDisabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건대상1</InputLabel>
              <Select
                value={fieldSettings.leftValue}
                label="조건대상1"
                onChange={(e) => handleConditionChange('leftField', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  fontSize: '0.875rem',
                  backgroundColor: fieldSettings.leftDisabled ? '#f5f5f5' : 'transparent'
                }}
              >
                {fieldOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>
          
          {/* 조건대상2 - 항상 표시 */}
          <Grid item xs={12} sm={4}>
            <FormControl size="small" fullWidth disabled={disabled || fieldSettings.rightDisabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건대상2</InputLabel>
              <Select
                value={fieldSettings.rightValue}
                label="조건대상2"
                onChange={(e) => handleConditionChange('rightField', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  fontSize: '0.875rem',
                  backgroundColor: fieldSettings.rightDisabled ? '#f5f5f5' : 'transparent'
                }}
              >
                {fieldOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>
          
          {/* 조건 타입 선택 */}
          <Grid item xs={12}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건</InputLabel>
              <Select
                value={conditionType || 'CROSS_UP'}
                label="조건"
                onChange={(e) => handleConditionChange('conditionType', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ fontSize: '0.875rem' }}
              >
                {ichimokuConditionOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>
          
          {/* 비교값 (DIFF_GT, DIFF_LT) */}
          {needsCompareValue && (
            <Grid item xs={12}>
              <TextField
                size="small"
                type="number"
                label="비교값"
                value={compareValue || 0}
                onChange={(e) => handleConditionChange('compareValue', Number(e.target.value))}
                disabled={disabled}
                fullWidth
                sx={{ fontSize: '0.875rem' }}
              />
            </Grid>
          )}
          
          {/* 기울기 기간 (SLOPE_UP, SLOPE_DOWN) */}
          {needsSlopePeriod && (
            <Grid item xs={12}>
              <TextField
                size="small"
                type="number"
                label="기울기 기간 (N일)"
                value={slopePeriod || 3}
                onChange={(e) => handleConditionChange('slopePeriod', Number(e.target.value))}
                disabled={disabled}
                fullWidth
                inputProps={{ min: 1, max: 100 }}
                helperText="N일 전 값과 비교 (1-100)"
                sx={{ fontSize: '0.875rem' }}
              />
            </Grid>
          )}
          
          {/* 유지 일수 (HOLD_N_DAYS) */}
          {needsHoldDays && (
            <Grid item xs={12}>
              <TextField
                size="small"
                type="number"
                label="유지 일수 (N일)"
                value={holdDays || 3}
                onChange={(e) => handleConditionChange('holdDays', Number(e.target.value))}
                disabled={disabled}
                fullWidth
                inputProps={{ min: 1, max: 30 }}
                helperText="조건이 N일 연속 유지 (1-30)"
                sx={{ fontSize: '0.875rem' }}
              />
            </Grid>
          )}
        </Grid>
      </Box>
    );
  };

  // 공통 조건 옵션 (13개)
  const COMMON_CONDITION_OPTIONS = [
    { value: 'GT', label: '초과 (>)' },
    { value: 'LT', label: '미만 (<)' },
    { value: 'GTE', label: '이상 (>=)' },
    { value: 'LTE', label: '이하 (<=)' },
    { value: 'EQ', label: '같음 (==)' },
    { value: 'NEQ', label: '다름 (!=)' },
    { value: 'CROSS_UP', label: '상향 돌파' },
    { value: 'CROSS_DOWN', label: '하향 돌파' },
    { value: 'SLOPE_UP', label: '상승 기울기' },
    { value: 'SLOPE_DOWN', label: '하락 기울기' },
    { value: 'DIFF_GT', label: '차이 > 값' },
    { value: 'DIFF_LT', label: '차이 < 값' },
    { value: 'HOLD_N_DAYS', label: 'N일 연속 유지' },
  ];

  // 공통 UI 생성 함수 (모든 CommonOperator 기반 지표에서 재사용)
  const createCommonConditionUI = (
    fieldOptions: Array<{ value: string; label: string }>,
    defaultLeftField: string,
    defaultRightField: string,
    defaultSlopeField: string
  ) => {
    if (node.type !== 'CONDITION' || !node.condition) return null;

    const { conditionType, leftField, rightField, compareValue, slopePeriod, holdDays, candleRange } = node.condition;
    
    // ✅ fieldOptions에 값이 존재하는지 확인하는 함수
    const isValidFieldValue = (value: string | undefined) => {
      if (!value) return false;
      return fieldOptions.some(opt => opt.value === value);
    };
    
    const getFieldSettings = (condType: string) => {
      if (['GT', 'LT', 'GTE', 'LTE', 'EQ', 'NEQ', 'CROSS_UP', 'CROSS_DOWN', 'DIFF_GT', 'DIFF_LT'].includes(condType)) {
        // ✅ leftField가 fieldOptions에 존재하는지 확인
        const validLeftValue = isValidFieldValue(leftField) ? leftField : defaultLeftField;
        const validRightValue = isValidFieldValue(rightField) ? rightField : defaultRightField;
        
        return {
          leftValue: validLeftValue || defaultLeftField,
          leftDisabled: false,
          rightValue: validRightValue || defaultRightField,
          rightDisabled: false
        };
      }
      
      if (['SLOPE_UP', 'SLOPE_DOWN'].includes(condType)) {
        const validLeftValue = isValidFieldValue(leftField) ? leftField : defaultSlopeField;
        
        return {
          leftValue: validLeftValue || defaultSlopeField,
          leftDisabled: false,
          rightValue: 'NONE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      if (condType === 'HOLD_N_DAYS') {
        return {
          leftValue: 'NONE',
          leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
          rightValue: 'NONE',
          rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        };
      }
      
      return {
        leftValue: leftField || 'NONE',
        leftDisabled: false, // 구름 위치형은 변경 불가하되 드롭다운은 활성화
        rightValue: rightField || 'NONE',
        rightDisabled: false // 구름 위치형은 변경 불가하되 드롭다운은 활성화
      };
    };
    
    const fieldSettings = getFieldSettings(conditionType || '');
    const needsCompareValue = ['DIFF_GT', 'DIFF_LT'].includes(conditionType || '');
    const needsSlopePeriod = ['SLOPE_UP', 'SLOPE_DOWN'].includes(conditionType || '');
    const needsHoldDays = conditionType === 'HOLD_N_DAYS';
    
    return (
      <Box sx={{ mt: 1.5 }}>
        <Grid container spacing={1.5}>
          {/* 캔들 범위 선택 */}
          <Grid item xs={3}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>캔들 범위</InputLabel>
              <Select
                value={candleRange || 1}
                label="캔들 범위"
                onChange={(e) => handleConditionChange('candleRange', Number(e.target.value))}
                sx={{ fontSize: '0.875rem' }}
                MenuProps={SELECT_MENU_PROPS}
              >
                <MenuItem value={1} sx={{ fontSize: '0.875rem' }}>현재 캔들</MenuItem>
                <MenuItem value={2} sx={{ fontSize: '0.875rem' }}>2개 캔들</MenuItem>
                <MenuItem value={3} sx={{ fontSize: '0.875rem' }}>3개 캔들</MenuItem>
                <MenuItem value={4} sx={{ fontSize: '0.875rem' }}>4개 캔들</MenuItem>
                <MenuItem value={5} sx={{ fontSize: '0.875rem' }}>5개 캔들</MenuItem>
              </Select>
            </FormControl>
          </Grid>
          
          <Grid item xs={3}>
            <FormControl size="small" fullWidth disabled={disabled || fieldSettings.leftDisabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건대상1</InputLabel>
              <Select
                value={fieldSettings.leftValue}
                label="조건대상1"
                onChange={(e) => handleConditionChange('leftField', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  fontSize: '0.875rem',
                  backgroundColor: fieldSettings.leftDisabled ? '#f5f5f5' : 'transparent'
                }}
              >
                {fieldOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value} sx={{ fontSize: '0.875rem' }}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          <Grid item xs={3}>
            <FormControl size="small" fullWidth disabled={disabled || fieldSettings.rightDisabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건대상2</InputLabel>
              <Select
                value={fieldSettings.rightValue}
                label="조건대상2"
                onChange={(e) => handleConditionChange('rightField', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ 
                  fontSize: '0.875rem',
                  backgroundColor: fieldSettings.rightDisabled ? '#f5f5f5' : 'transparent'
                }}
              >
                {fieldOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value} sx={{ fontSize: '0.875rem' }}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          <Grid item xs={3}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건</InputLabel>
              <Select
                value={conditionType || 'GT'}
                label="조건"
                onChange={(e) => handleConditionChange('conditionType', e.target.value)}
                MenuProps={SELECT_MENU_PROPS}
                sx={{ fontSize: '0.875rem' }}
              >
                {COMMON_CONDITION_OPTIONS.map((option) => (
                  <MenuItem key={option.value} value={option.value} sx={{ fontSize: '0.875rem' }}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          {needsCompareValue && (
            <Grid item xs={12}>
              <TextField
                label="비교값"
                type="number"
                value={compareValue || ''}
                onChange={(e) => handleConditionChange('compareValue', parseFloat(e.target.value))}
                size="small"
                fullWidth
                disabled={disabled}
                InputProps={{ sx: { fontSize: '0.875rem' } }}
                InputLabelProps={{ sx: { fontSize: '0.875rem' } }}
                placeholder="예: 0.5"
              />
            </Grid>
          )}

          {needsSlopePeriod && (
            <Grid item xs={12}>
              <TextField
                label="기울기 기간 (일)"
                type="number"
                value={slopePeriod || ''}
                onChange={(e) => handleConditionChange('slopePeriod', parseInt(e.target.value))}
                size="small"
                fullWidth
                disabled={disabled}
                InputProps={{ sx: { fontSize: '0.875rem' } }}
                InputLabelProps={{ sx: { fontSize: '0.875rem' } }}
                placeholder="예: 5"
                inputProps={{ min: 1, max: 100 }}
              />
            </Grid>
          )}

          {needsHoldDays && (
            <Grid item xs={12}>
              <TextField
                label="유지 일수 (일)"
                type="number"
                value={holdDays || ''}
                onChange={(e) => handleConditionChange('holdDays', parseInt(e.target.value))}
                size="small"
                fullWidth
                disabled={disabled}
                InputProps={{ sx: { fontSize: '0.875rem' } }}
                InputLabelProps={{ sx: { fontSize: '0.875rem' } }}
                placeholder="예: 3"
                inputProps={{ min: 1, max: 30 }}
              />
            </Grid>
          )}
        </Grid>
      </Box>
    );
  };

  // 과매수선/과매도선 라벨 변환 함수
  const getOverboughtLabel = (baseLabel: string): string => {
    // 예: "과매수선(70)" → "과열진입(70)" (매수) 또는 "과열이탈(70)" (매도)
    if (signalType === 'buy') {
      return baseLabel.replace('과매수선', '과열진입');
    } else {
      return baseLabel.replace('과매수선', '과열이탈');
    }
  };

  const getOversoldLabel = (baseLabel: string): string => {
    // 예: "과매도선(30)" → "침체이탈(30)" (매수) 또는 "침체진입(30)" (매도)
    if (signalType === 'buy') {
      return baseLabel.replace('과매도선', '침체이탈');
    } else {
      return baseLabel.replace('과매도선', '침체진입');
    }
  };

  // RSI 조건 상세 정보
  const getRsiConditionDetails = () => {
    // ✅ 실제 설정된 RSI 기간값 읽기
    const rsiPeriod = indicatorSettings.rsiPeriod || 9;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'RSI_VALUE', label: `RSI 값(${rsiPeriod}일)` },
      { value: 'OVERBOUGHT_70', label: getOverboughtLabel('과매수선(70)') },
      { value: 'NEUTRAL_50', label: '중립선(50)' },
      { value: 'OVERSOLD_30', label: getOversoldLabel('과매도선(30)') },
    ];
    return createCommonConditionUI(fieldOptions, 'RSI_VALUE', 'OVERBOUGHT_70', 'RSI_VALUE');
  };

  // Stochastic 조건 상세 정보
  const getStochasticConditionDetails = () => {
    // ✅ 실제 설정된 Stochastic 기간값 읽기
    const stochKPeriod = indicatorSettings.stochasticKPeriod || 12;
    const stochDPeriod = indicatorSettings.stochasticDPeriod || 5;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'STOCH_K', label: `Stochastic %K(${stochKPeriod}일)` },
      { value: 'STOCH_D', label: `Stochastic %D(${stochDPeriod}일)` },
      { value: 'OVERBOUGHT_80', label: getOverboughtLabel('과매수선(80)') },
      { value: 'NEUTRAL_50', label: '중립선(50)' },
      { value: 'OVERSOLD_20', label: getOversoldLabel('과매도선(20)') },
    ];
    return createCommonConditionUI(fieldOptions, 'STOCH_K', 'STOCH_D', 'STOCH_K');
  };

  // CCI 조건 상세 정보
  const getCciConditionDetails = () => {
    // ✅ 실제 설정된 CCI 기간값 읽기
    const cciPeriod = indicatorSettings.cciPeriod || 13;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'CCI_VALUE', label: `CCI 값(${cciPeriod}일)` },
      { value: 'OVERBOUGHT_100', label: getOverboughtLabel('과매수선(100)') },
      { value: 'NEUTRAL_0', label: '중립선(0)' },
      { value: 'OVERSOLD_NEG100', label: getOversoldLabel('과매도선(-100)') },
    ];
    return createCommonConditionUI(fieldOptions, 'CCI_VALUE', 'OVERBOUGHT_100', 'CCI_VALUE');
  };

  // ADX 조건 상세 정보
  const getAdxConditionDetails = () => {
    // ✅ 실제 설정된 ADX 기간값 읽기
    const adxPeriod = indicatorSettings.adxPeriod || 14;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'ADX_VALUE', label: `ADX 값(${adxPeriod}일)` },
      { value: 'ADX_25', label: '기준선(25)' },
      { value: 'ADX_50', label: '강한추세선(50)' },
    ];
    return createCommonConditionUI(fieldOptions, 'ADX_VALUE', 'ADX_25', 'ADX_VALUE');
  };

  // TRIX 조건 상세 정보
  const getTrixConditionDetails = () => {
    // ✅ 실제 설정된 TRIX 기간값 읽기
    const trixPeriod = indicatorSettings.trixPeriod || 12;
    const trixSignalPeriod = indicatorSettings.trixSignalPeriod || 9;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'TRIX_VALUE', label: `TRIX 값(${trixPeriod}일)` },
      { value: 'TRIX_SIGNAL', label: `TRIX 시그널(${trixSignalPeriod}일)` },
      { value: 'ZERO_LINE', label: '0선' },
    ];
    return createCommonConditionUI(fieldOptions, 'TRIX_VALUE', 'TRIX_SIGNAL', 'TRIX_VALUE');
  };

  // DMI 조건 상세 정보
  const getDmiConditionDetails = () => {
    // ✅ 실제 설정된 DMI 기간값 읽기
    const dmiPeriod = indicatorSettings.dmiPeriod || 14;
    const dmiOverbought = indicatorSettings.dmiOverbought || 30;
    const dmiMiddle = indicatorSettings.dmiMiddle || 20;
    const dmiOversold = indicatorSettings.dmiOversold || 10;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'PDI', label: `DI+(${dmiPeriod}일)` },
      { value: 'MDI', label: `DI-(${dmiPeriod}일)` },
      { value: 'OVERBOUGHT_30', label: `${getOverboughtLabel('과열')}(${dmiOverbought})` },
      { value: 'MIDDLE_20', label: `중간값(${dmiMiddle})` },
      { value: 'OVERSOLD_10', label: `${getOversoldLabel('침체')}(${dmiOversold})` },
    ];
    return createCommonConditionUI(fieldOptions, 'PDI', 'MDI', 'PDI');
  };

  // OBV 조건 상세 정보
  const getObvConditionDetails = () => {
    // ✅ 실제 설정된 OBV 기간값 읽기
    const obvPeriod = indicatorSettings.obvPeriod || 9;
    const obvSignalPeriod = indicatorSettings.obvSignalPeriod || 9;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'OBV_LINE', label: `OBV선(${obvPeriod}일)` },
      { value: 'OBV_SIGNAL', label: `신호선(${obvSignalPeriod}일)` },
    ];
    return createCommonConditionUI(fieldOptions, 'OBV_LINE', 'OBV_SIGNAL', 'OBV_LINE');
  };

  // VOLUME 조건 상세 정보
  const getVolumeConditionDetails = () => {
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'VOLUME_VALUE', label: '거래량' },
      { value: 'VOLUME_MA', label: '거래량 이동평균' },
    ];
    return createCommonConditionUI(fieldOptions, 'VOLUME_VALUE', 'VOLUME_MA', 'VOLUME_VALUE');
  };

  // MA 조건 상세 정보 (기존 getMAConditionDetails 대체)
  const getMaConditionDetails = () => {
    // ✅ 실제 설정된 MA 라인을 읽어서 동적으로 목록 생성
    const maLines = visibilitySettings.maLines || [];
    const enabledMAs = maLines.filter(ma => ma.enabled);
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      // ✅ 활성화된 MA를 표시
      ...enabledMAs.map((ma, index) => ({
          value: `MA${ma.period}`, // MA5, MA10, MA20... (기간값 사용 - 기존 호환성)
          label: `MA${index + 1}(${ma.period}일)`, // MA1(5일), MA2(10일), MA3(20일) 형식
          period: ma.period
        })),
      { value: 'CLOSE_PRICE', label: '종가' },
    ];
    
    // 기본값: 첫 번째, 두 번째 활성화된 MA (없으면 CLOSE_PRICE)
    const defaultValue1 = enabledMAs.length > 0 ? `MA${enabledMAs[0].period}` : 'CLOSE_PRICE';
    const defaultValue2 = enabledMAs.length > 1 ? `MA${enabledMAs[1].period}` : 'CLOSE_PRICE';
    
    return createCommonConditionUI(fieldOptions, defaultValue1, defaultValue2, defaultValue1);
  };

  // DISPARITY 조건 상세 정보
  const getDisparityConditionDetails = () => {
    // ✅ 실제 설정된 이격도 기간값 읽기
    const ultraShortPeriod = indicatorSettings.disparityUltraShortPeriod || 5;
    const shortPeriod = indicatorSettings.disparityShortPeriod || 10;
    const midPeriod = indicatorSettings.disparityMidPeriod || 20;
    const longPeriod = indicatorSettings.disparityLongPeriod || 60;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: `DISPARITY${ultraShortPeriod}`, label: `초단기 이격도(${ultraShortPeriod}일)` },
      { value: `DISPARITY${shortPeriod}`, label: `단기 이격도(${shortPeriod}일)` },
      { value: `DISPARITY${midPeriod}`, label: `중기 이격도(${midPeriod}일)` },
      { value: `DISPARITY${longPeriod}`, label: `장기 이격도(${longPeriod}일)` },
      { value: 'NEUTRAL_100', label: '100선' },
    ];
    
    const defaultValue1 = fieldOptions[1].value; // 초단기
    return createCommonConditionUI(fieldOptions, defaultValue1, 'NEUTRAL_100', defaultValue1);
  };

  // NEW_PSYCHOLOGICAL 조건 상세 정보
  const getNewPsychologicalConditionDetails = () => {
    // ✅ 실제 설정된 신심리도 기간값 읽기
    const newPsyPeriod = indicatorSettings.newPsychologicalPeriod || 12;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'NEW_PSY_VALUE', label: `신심리도 값(${newPsyPeriod}일)` },
      { value: 'OVERBOUGHT_75', label: getOverboughtLabel('과매수선(75)') },
      { value: 'NEUTRAL_50', label: '중립선(50)' },
      { value: 'OVERSOLD_25', label: getOversoldLabel('과매도선(25)') },
    ];
    return createCommonConditionUI(fieldOptions, 'NEW_PSY_VALUE', 'OVERBOUGHT_75', 'NEW_PSY_VALUE');
  };

  // INVEST_PSYCHOLOGICAL 조건 상세 정보
  const getInvestPsychologicalConditionDetails = () => {
    // ✅ 실제 설정된 투자심리도 기간값 읽기
    const investPsyPeriod = indicatorSettings.investPsychologicalPeriod || 24;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'INVEST_PSY_VALUE', label: `투자심리도 값(${investPsyPeriod}일)` },
      { value: 'OVERBOUGHT_75', label: getOverboughtLabel('과매수선(75)') },
      { value: 'NEUTRAL_50', label: '중립선(50)' },
      { value: 'OVERSOLD_25', label: getOversoldLabel('과매도선(25)') },
    ];
    return createCommonConditionUI(fieldOptions, 'INVEST_PSY_VALUE', 'OVERBOUGHT_75', 'INVEST_PSY_VALUE');
  };

  // WILLIAMS_R 조건 상세 정보
  const getWilliamsRConditionDetails = () => {
    // ✅ 실제 설정된 Williams %R 기간값 읽기
    const williamsRPeriod = indicatorSettings.williamsRPeriod || 14;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'WILLIAMS_R_VALUE', label: `Williams %R 값(${williamsRPeriod}일)` },
      { value: 'OVERBOUGHT_NEG20', label: getOverboughtLabel('과매수선(-20)') },
      { value: 'NEUTRAL_NEG50', label: '중립선(-50)' },
      { value: 'OVERSOLD_NEG80', label: getOversoldLabel('과매도선(-80)') },
    ];
    return createCommonConditionUI(fieldOptions, 'WILLIAMS_R_VALUE', 'OVERBOUGHT_NEG20', 'WILLIAMS_R_VALUE');
  };

  // BWI 조건 상세 정보
  const getBwiConditionDetails = () => {
    // ✅ 실제 설정된 BWI 기간값 읽기
    const bwiPeriod = indicatorSettings.bwiPeriod || 20;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'BWI_VALUE', label: `BWI 값(${bwiPeriod}일)` },
      { value: 'OVERBOUGHT_80', label: getOverboughtLabel('과매수선(80)') },
      { value: 'NEUTRAL_50', label: '중립선(50)' },
      { value: 'OVERSOLD_20', label: getOversoldLabel('과매도선(20)') },
    ];
    return createCommonConditionUI(fieldOptions, 'BWI_VALUE', 'OVERBOUGHT_80', 'BWI_VALUE');
  };

  // VR 조건 상세 정보
  const getVrConditionDetails = () => {
    // ✅ 실제 설정된 VR 기간값 읽기
    const vrPeriod = indicatorSettings.vrPeriod || 10;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'VR_VALUE', label: `VR 값(${vrPeriod}일)` },
      { value: 'OVERBOUGHT_200', label: getOverboughtLabel('과매수선(200)') },
      { value: 'NEUTRAL_100', label: '중립선(100)' },
      { value: 'OVERSOLD_50', label: getOversoldLabel('과매도선(50)') },
    ];
    return createCommonConditionUI(fieldOptions, 'VR_VALUE', 'OVERBOUGHT_200', 'VR_VALUE');
  };

  // VOLUME_OSC 조건 상세 정보
  const getVolumeOscConditionDetails = () => {
    // ✅ 실제 설정된 Volume OSC 기간값 읽기
    const shortPeriod = indicatorSettings.volumeOscShortPeriod || 5;
    const longPeriod = indicatorSettings.volumeOscLongPeriod || 10;
    
    const fieldOptions = [
      { value: 'NONE', label: '선택안함' },
      { value: 'VOLUME_OSC_VALUE', label: `거래량 오실레이터 값(${shortPeriod}일/${longPeriod}일)` },
      { value: 'ZERO_LINE', label: '0선' },
    ];
    return createCommonConditionUI(fieldOptions, 'VOLUME_OSC_VALUE', 'ZERO_LINE', 'VOLUME_OSC_VALUE');
  };

  // 조건 노드의 상세 정보
  const getConditionDetails = () => {
    if (node.type !== 'CONDITION' || !node.condition) return null;

    const { indicatorType, conditionType, targetValue, period } = node.condition;
    
    // 일목균형표는 특별한 UI 사용
    if (indicatorType === 'ICHIMOKU') {
      return getIchimokuConditionDetails();
    }
    
    // 볼린저밴드는 특별한 UI 사용
    if (indicatorType === 'BOLLINGER') {
      return getBollingerConditionDetails();
    }
    
    // MACD는 특별한 UI 사용
    if (indicatorType === 'MACD') {
      return getMacdConditionDetails();
    }
    
    // RSI는 특별한 UI 사용
    if (indicatorType === 'RSI') {
      return getRsiConditionDetails();
    }
    
    // Stochastic는 특별한 UI 사용
    if (indicatorType === 'STOCHASTIC') {
      return getStochasticConditionDetails();
    }
    
    // CCI는 특별한 UI 사용
    if (indicatorType === 'CCI') {
      return getCciConditionDetails();
    }
    
    // ADX는 특별한 UI 사용
    if (indicatorType === 'ADX') {
      return getAdxConditionDetails();
    }
    
    // TRIX는 특별한 UI 사용
    if (indicatorType === 'TRIX') {
      return getTrixConditionDetails();
    }
    
    // DMI는 특별한 UI 사용
    if (indicatorType === 'DMI') {
      return getDmiConditionDetails();
    }
    
    // OBV는 특별한 UI 사용
    if (indicatorType === 'OBV') {
      return getObvConditionDetails();
    }
    
    // VOLUME는 특별한 UI 사용
    if (indicatorType === 'VOLUME') {
      return getVolumeConditionDetails();
    }
    
    // MA는 특별한 UI 사용
    if (indicatorType === 'MA') {
      return getMaConditionDetails();
    }
    
    // DISPARITY는 특별한 UI 사용
    if (indicatorType === 'DISPARITY') {
      return getDisparityConditionDetails();
    }
    
    // NEW_PSYCHOLOGICAL는 특별한 UI 사용
    if (indicatorType === 'NEW_PSYCHOLOGICAL') {
      return getNewPsychologicalConditionDetails();
    }
    
    // INVEST_PSYCHOLOGICAL는 특별한 UI 사용
    if (indicatorType === 'INVEST_PSYCHOLOGICAL') {
      return getInvestPsychologicalConditionDetails();
    }
    
    // WILLIAMS_R는 특별한 UI 사용
    if (indicatorType === 'WILLIAMS_R') {
      return getWilliamsRConditionDetails();
    }
    
    // BWI는 특별한 UI 사용
    if (indicatorType === 'BWI') {
      return getBwiConditionDetails();
    }
    
    // VR는 특별한 UI 사용
    if (indicatorType === 'VR') {
      return getVrConditionDetails();
    }
    
    // VOLUME_OSC는 특별한 UI 사용
    if (indicatorType === 'VOLUME_OSC') {
      return getVolumeOscConditionDetails();
    }
    
    // EMA는 MA와 동일한 UI 사용
    if (indicatorType === 'EMA') {
      return getMAConditionDetails();
    }
    
    // 해당 지표의 기간 옵션 (설정값 기반)
    const periodOptions = getPeriodOptionsForIndicator(indicatorType);
    
    // 해당 지표의 조건 옵션
    const conditionOptions = getConditionOptionsForIndicator(indicatorType);
    
    return (
      <Box sx={{ mt: 1.5 }}>
        <Grid container spacing={1.5}>
          {/* 기간 선택 (드롭다운) */}
          {periodOptions.length > 0 && (
            <Grid item xs={12} sm={4}>
              <FormControl size="small" fullWidth disabled={disabled}>
                <InputLabel sx={{ fontSize: '0.875rem' }}>기간</InputLabel>
                <Select
                  value={period || periodOptions[0]?.value || ''}
                  label="기간"
                  onChange={(e) => handleConditionChange('period', Number(e.target.value))}
                  sx={{ 
                    '& .MuiSelect-select': { 
                      fontSize: '0.875rem',
                      py: 0.75,
                    }
                  }}
                >
                  {periodOptions.map((option) => (
                    <MenuItem key={option.value} value={option.value}>
                      {option.label}
                    </MenuItem>
                  ))}
                </Select>
              </FormControl>
            </Grid>
          )}

          {/* 조건 타입 선택 (드롭다운) */}
          <Grid item xs={12} sm={periodOptions.length > 0 ? 4 : 6}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>조건</InputLabel>
              <Select
                value={conditionType || ''}
                label="조건"
                onChange={(e) => handleConditionChange('conditionType', e.target.value)}
                sx={{ 
                  '& .MuiSelect-select': { 
                    fontSize: '0.875rem',
                    py: 0.75,
                  }
                }}
              >
                {conditionOptions.map((option) => (
                  <MenuItem key={option.value} value={option.value}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>

          {/* 목표값 선택 (드롭다운) */}
          <Grid item xs={12} sm={periodOptions.length > 0 ? 4 : 6}>
            <FormControl size="small" fullWidth disabled={disabled}>
              <InputLabel sx={{ fontSize: '0.875rem' }}>목표값</InputLabel>
              <Select
                value={targetValue !== undefined ? targetValue : ''}
                label="목표값"
                onChange={(e) => handleConditionChange('targetValue', Number(e.target.value))}
                sx={{ 
                  '& .MuiSelect-select': { 
                    fontSize: '0.875rem',
                    py: 0.75,
                  }
                }}
              >
                {getTargetValueOptionsForIndicator(indicatorType, conditionType || '').map((option) => (
                  <MenuItem key={option.value} value={option.value}>
                    {option.label}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Grid>
        </Grid>
      </Box>
    );
  };

  return (
    <Box sx={{ ml: `${indentSize}px`, mb: 1 }}>
      <Paper
        ref={(el) => {
          setDragRef(el);
          setDropRef(el);
        }}
        elevation={isDragging ? 4 : isOver ? 2 : 0}
        sx={{
          p: 1.5,
          backgroundColor: isOver ? 
            theme.palette.action.hover : 
            theme.palette.background.paper,
          border: `2px solid ${getNodeColor()}`,
          borderStyle: isDragging ? 'dashed' : 'solid',
          opacity: isDragging ? 0.5 : 1,
          cursor: disabled ? 'default' : 'move',
          transition: 'all 0.2s ease',
          position: 'relative',
          '&:hover': {
            boxShadow: theme.shadows[2],
          },
        }}
        {...dragAttributes}
        {...dragListeners}
      >
        {/* 노드 헤더 */}
        <Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', mb: 1, gap: 1 }}>
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flex: 1, minWidth: 0, overflow: 'hidden' }}>
            <Chip
              icon={getNodeIcon()}
              label={getNodeLabel()}
              size="small"
              sx={{
                backgroundColor: getNodeColor(),
                color: theme.palette.getContrastText(getNodeColor()),
                fontWeight: 'bold',
                flexShrink: 0,
              }}
            />
            {node.description && (
              <Typography variant="caption" color="text.secondary" noWrap sx={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>
                {node.description}
              </Typography>
            )}
          </Box>

          {/* 액션 버튼들 */}
          <Box sx={{ display: 'flex', gap: 0.25, flexShrink: 0, ml: 'auto' }}>
            {/* 자식 추가 (AND/OR/NOT만) */}
            {node.type !== 'CONDITION' && onAddChild && (
              <Tooltip title="자식 노드 추가">
                <IconButton
                  size="small"
                  onClick={(e) => {
                    e.stopPropagation();
                    onAddChild(node.id);
                  }}
                  disabled={disabled}
                  sx={{ color: theme.palette.success.main }}
                >
                  <AddIcon fontSize="small" />
                </IconButton>
              </Tooltip>
            )}

            {/* 템플릿으로 저장 (조건 노드만) */}
            {node.type === 'CONDITION' && (
              <Tooltip title="템플릿으로 저장">
                <IconButton
                  size="small"
                  onClick={(e) => {
                    e.stopPropagation();
                    handleSaveAsTemplate();
                  }}
                  disabled={disabled}
                  sx={{ color: theme.palette.primary.main }}
                >
                  <SaveIcon fontSize="small" />
                </IconButton>
              </Tooltip>
            )}

            {/* 삭제 */}
            {onDelete && (
              <Tooltip title="노드 삭제">
                <IconButton
                  size="small"
                  onClick={(e) => {
                    e.stopPropagation();
                    onDelete(node.id);
                  }}
                  disabled={disabled}
                  sx={{ color: theme.palette.error.main }}
                >
                  <DeleteIcon fontSize="small" />
                </IconButton>
              </Tooltip>
            )}
          </Box>
        </Box>

        {/* 조건 노드의 상세 정보 */}
        {getConditionDetails()}

        {/* 자식 노드들 */}
        {node.children && node.children.length > 0 && (
          <Box sx={{ mt: 1, ml: 0.5, borderLeft: `2px solid ${getNodeColor()}`, pl: 1 }}>
            {node.children.map((child, index) => (
              <TreeNode
                key={child.id}
                node={child}
                onChange={(updatedChild) => {
                  if (!onChange) return;
                  const updatedChildren = [...node.children!];
                  updatedChildren[index] = updatedChild;
                  onChange({ ...node, children: updatedChildren });
                }}
                onEdit={onEdit}
                onDelete={onDelete}
                onAddChild={onAddChild}
                depth={depth + 1}
                disabled={disabled}
                signalType={signalType}
              />
            ))}
          </Box>
        )}

        {/* 드롭 영역 힌트 - 자식 노드들 아래에 표시 */}
        {isOver && node.type !== 'CONDITION' && (
          <Box
            sx={{
              mt: 1,
              p: 0.75,
              border: `2px dashed ${theme.palette.primary.main}`,
              backgroundColor: theme.palette.action.hover,
              textAlign: 'center',
            }}
          >
            <Typography variant="caption" color="primary">
              여기에 드롭하세요
            </Typography>
          </Box>
        )}

        {/* 빈 자식 안내 */}
        {node.type !== 'CONDITION' && (!node.children || node.children.length === 0) && (
          <Box
            sx={{
              mt: 1,
              p: 1.5,
              border: `1px dashed ${theme.palette.divider}`,
              textAlign: 'center',
              backgroundColor: theme.palette.action.hover,
            }}
          >
            <Typography variant="caption" color="text.secondary">
              {node.type === 'NOT' ? 
                '자식 노드를 1개 추가하세요' : 
                '자식 노드를 추가하세요 (드래그 또는 + 버튼)'}
            </Typography>
          </Box>
        )}
      </Paper>

      {/* 템플릿 저장 다이얼로그 */}
      <Dialog 
        open={saveDialogOpen} 
        onClose={() => setSaveDialogOpen(false)}
        maxWidth="sm"
        fullWidth
      >
        <DialogTitle>템플릿으로 저장</DialogTitle>
        <DialogContent>
          <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, mt: 1 }}>
            <TextField
              label="템플릿 이름"
              value={templateName}
              onChange={(e) => setTemplateName(e.target.value)}
              fullWidth
              autoFocus
              helperText="기존 템플릿 이름으로 저장하면 업데이트, 새 이름으로 저장하면 새로 생성됩니다."
            />
            
            <TextField
              label="설명 (선택사항)"
              value={templateDescription}
              onChange={(e) => setTemplateDescription(e.target.value)}
              fullWidth
              multiline
              rows={2}
              placeholder="이 전략에 대한 설명을 입력하세요"
            />

            <FormControl component="fieldset">
              <Typography variant="subtitle2" sx={{ mb: 1 }}>
                신호 타입
              </Typography>
              <RadioGroup
                value={templateSignal}
                onChange={(e) => setTemplateSignal(e.target.value as 'buy' | 'sell')}
                row
              >
                <FormControlLabel 
                  value="buy" 
                  control={<Radio />} 
                  label="매수 신호" 
                />
                <FormControlLabel 
                  value="sell" 
                  control={<Radio />} 
                  label="매도 신호" 
                />
              </RadioGroup>
            </FormControl>

            <Box sx={{ 
              p: 2, 
              backgroundColor: theme.palette.grey[100], 
              borderRadius: 1,
              border: `1px solid ${theme.palette.divider}`
            }}>
              <Typography variant="caption" color="text.secondary">
                <strong>현재 조건:</strong><br />
                {node.condition && `${node.condition.indicatorType} - ${node.condition.conditionType}`}
              </Typography>
            </Box>
          </Box>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setSaveDialogOpen(false)} color="inherit">
            취소
          </Button>
          <Button 
            onClick={handleSaveTemplate} 
            variant="contained" 
            color="primary"
            startIcon={<SaveIcon />}
          >
            저장
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  );
};

export default TreeNode;
