import React, { useState, useEffect } from 'react';
import { Box, Alert, useTheme } from '@mui/material';
import { useDndMonitor, useDroppable, DragEndEvent } from '@dnd-kit/core';
import TreeNode from './TreeNode';
import ConditionEditor from './ConditionEditor';
import {
  LogicNode,
  LogicNodeType,
  ConditionDSL,
  createEmptyLogicNode,
  generateNodeId,
} from '../../services/strategyDSLApi';
import { useIndicatorSettings } from '../../contexts/IndicatorSettingsContext';
import { useIndicatorVisibility } from '../../contexts/IndicatorVisibilityContext';

// ============================================================
// Props 정의
// ============================================================

export interface StrategyTreeBuilderProps {
  rootNode: LogicNode | null;
  onChange: (newRoot: LogicNode | null) => void;
  disabled?: boolean;
  onDropSuccess?: () => void;
  signalType?: 'buy' | 'sell'; // 매수/매도 탭 구분
}

// ============================================================
// StrategyTreeBuilder 컴포넌트
// ============================================================

const StrategyTreeBuilder: React.FC<StrategyTreeBuilderProps> = ({
  rootNode,
  onChange,
  disabled = false,
  onDropSuccess,
  signalType = 'buy', // 기본값: 매수
}) => {
  const theme = useTheme();
  const { indicatorSettings } = useIndicatorSettings();
  const { settings: visibilitySettings } = useIndicatorVisibility();

  // 조건 편집 다이얼로그 상태
  const [editingNodeId, setEditingNodeId] = useState<string | null>(null);
  const [editingCondition, setEditingCondition] = useState<ConditionDSL | null>(null);

  // 빈 공간에 드롭 가능하도록 설정
  const { setNodeRef: setDropRef, isOver } = useDroppable({
    id: 'empty-canvas',
    disabled: disabled,
  });

  // ============================================================
  // 노드 조작 함수들
  // ============================================================

  /**
   * 노드 찾기 (재귀)
   */
  const findNode = (node: LogicNode, targetId: string): LogicNode | null => {
    if (node.id === targetId) return node;
    
    if (node.children) {
      for (const child of node.children) {
        const found = findNode(child, targetId);
        if (found) return found;
      }
    }
    
    return null;
  };

  /**
   * 노드 업데이트 (재귀)
   */
  const updateNode = (node: LogicNode, targetId: string, updater: (n: LogicNode) => LogicNode): LogicNode => {
    if (node.id === targetId) {
      return updater(node);
    }
    
    if (node.children) {
      return {
        ...node,
        children: node.children.map(child => updateNode(child, targetId, updater)),
      };
    }
    
    return node;
  };

  /**
   * 노드 삭제 (재귀)
   */
  const deleteNode = (node: LogicNode, targetId: string): LogicNode | null => {
    if (node.id === targetId) {
      return null;
    }
    
    if (node.children) {
      const newChildren = node.children
        .map(child => deleteNode(child, targetId))
        .filter((child): child is LogicNode => child !== null);
      
      return {
        ...node,
        children: newChildren,
      };
    }
    
    return node;
  };

  /**
   * 자식 추가
   */
  const addChild = (node: LogicNode, parentId: string, newChild: LogicNode): LogicNode => {
    if (node.id === parentId) {
      // NOT 노드는 자식이 1개만 허용
      if (node.type === 'NOT' && node.children && node.children.length >= 1) {
        alert('NOT 노드는 자식을 1개만 가질 수 있습니다.');
        return node;
      }
      
      return {
        ...node,
        children: [...(node.children || []), newChild],
      };
    }
    
    if (node.children) {
      return {
        ...node,
        children: node.children.map(child => addChild(child, parentId, newChild)),
      };
    }
    
    return node;
  };

  // ============================================================
  // 이벤트 핸들러
  // ============================================================

  /**
   * 드래그 종료 이벤트 모니터링
   */
  useDndMonitor({
    onDragEnd: (event: DragEndEvent) => {
      const { active, over } = event;
      
      if (!over) return;
      
      const draggedData = active.data.current;
      const droppedData = over.data.current;
      
      if (!draggedData) return;
      
      // 팔레트에서 드래그한 경우
      if (draggedData.type === 'operator' || draggedData.type === 'indicator') {
        handlePaletteDrop(draggedData, droppedData);
      }
    },
  });

  /**
   * 지표별 기본 기간값 가져오기
   */
  const getDefaultPeriod = (indicatorType: string): number => {
    switch (indicatorType) {
      case 'RSI': return indicatorSettings.rsiPeriod;
      case 'MACD': return indicatorSettings.macdSignalPeriod;
      case 'CCI': return indicatorSettings.cciPeriod;
      case 'STOCHASTIC': return indicatorSettings.stochasticKPeriod;
      case 'ADX': return indicatorSettings.adxPeriod;
      case 'OBV': return indicatorSettings.obvPeriod;
      case 'BWI': return indicatorSettings.bwiPeriod;
      case 'DMI': return indicatorSettings.dmiPeriod;
      case 'WILLIAMS_R': return indicatorSettings.williamsRPeriod;
      case 'TRIX': return indicatorSettings.trixPeriod;
      case 'NEW_PSYCHOLOGICAL': return indicatorSettings.newPsychologicalPeriod;
      case 'INVEST_PSYCHOLOGICAL': return indicatorSettings.investPsychologicalPeriod;
      case 'VR': return indicatorSettings.vrPeriod;
      case 'VOLUME_OSC': return indicatorSettings.volumeOscShortPeriod;
      case 'DISPARITY': return indicatorSettings.disparityShortPeriod;
      case 'MA':
      case 'EMA': 
        // MA/EMA는 단기선 기간 (MA1 기본값)
        const ma1 = visibilitySettings.maLines.find(line => line.id === 'MA1');
        return ma1?.period || 5;
      case 'BOLLINGER': return 20;
      case 'ICHIMOKU': return 9;
      default: return 20;
    }
  };

  /**
   * 지표별 기본 목표값 가져오기
   */
  const getDefaultTargetValue = (indicatorType: string): number => {
    switch (indicatorType) {
      case 'RSI': return indicatorSettings.rsiMiddle;
      case 'CCI': return indicatorSettings.cciMiddle;
      case 'STOCHASTIC': return indicatorSettings.stochasticNeutral;
      case 'WILLIAMS_R': return indicatorSettings.williamsRMiddle;
      case 'BWI': return indicatorSettings.bwiMiddle;
      case 'ADX': return indicatorSettings.adxStrongThreshold;
      case 'NEW_PSYCHOLOGICAL': return indicatorSettings.newPsychologicalMiddle;
      case 'INVEST_PSYCHOLOGICAL': return indicatorSettings.investPsychologicalMiddle;
      case 'TRIX': return indicatorSettings.trixMiddle;
      case 'VR': return indicatorSettings.vrBaseLine;
      case 'DMI': return indicatorSettings.dmiOverbought;
      case 'DISPARITY': return 100;
      case 'MACD':
      case 'VOLUME_OSC': return 0;
      case 'MA':
      case 'EMA': 
        // MA/EMA는 장기선 기간 (MA3 기본값)
        const ma3 = visibilitySettings.maLines.find(line => line.id === 'MA3');
        return ma3?.period || 20;
      default: return 0;
    }
  };

  /**
   * 팔레트에서 드롭 처리
   */
  const handlePaletteDrop = (draggedData: any, droppedData: any) => {
    console.log('🎯 드롭 이벤트:', { draggedData, droppedData });
    
    let newNode: LogicNode;
    
    if (draggedData.type === 'operator') {
      // 논리 연산자 노드 생성
      newNode = createEmptyLogicNode(draggedData.value as LogicNodeType);
    } else if (draggedData.type === 'indicator') {
      // 지표 조건 노드 생성 (설정값 기반 기본값)
      const indicatorType = draggedData.value;
      
      // 일목균형표는 특별한 기본값 설정
      if (indicatorType === 'ICHIMOKU') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'ICHIMOKU',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'CONVERSION_LINE',
            rightField: 'BASE_LINE',
          },
        };
      }
      // 볼린저밴드는 특별한 기본값 설정
      else if (indicatorType === 'BOLLINGER') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'BOLLINGER',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'CLOSE_PRICE',
            rightField: 'UPPER_BAND',
          },
        };
      }
      // MACD는 특별한 기본값 설정
      else if (indicatorType === 'MACD') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'MACD',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'MACD_LINE',
            rightField: 'SIGNAL_LINE',
          },
        };
      }
      // RSI
      else if (indicatorType === 'RSI') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'RSI',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'RSI_VALUE',
            rightField: 'OVERBOUGHT_70',
          },
        };
      }
      // STOCHASTIC
      else if (indicatorType === 'STOCHASTIC') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'STOCHASTIC',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'STOCH_K',
            rightField: 'STOCH_D',
          },
        };
      }
      // CCI
      else if (indicatorType === 'CCI') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'CCI',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'CCI_VALUE',
            rightField: 'OVERBOUGHT_100',
          },
        };
      }
      // ADX
      else if (indicatorType === 'ADX') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'ADX',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'ADX_VALUE',
            rightField: 'ADX_25',
          },
        };
      }
      // TRIX
      else if (indicatorType === 'TRIX') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'TRIX',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'TRIX_VALUE',
            rightField: 'TRIX_SIGNAL',
          },
        };
      }
      // DMI
      else if (indicatorType === 'DMI') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'DMI',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'PDI',
            rightField: 'MDI',
          },
        };
      }
      // OBV
      else if (indicatorType === 'OBV') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'OBV',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'OBV_LINE',
            rightField: 'OBV_SIGNAL',
          },
        };
      }
      // VOLUME
      else if (indicatorType === 'VOLUME') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'VOLUME',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'VOLUME_VALUE',
            rightField: 'VOLUME_MA',
          },
        };
      }
      // MA (CommonOperator 기반)
      else if (indicatorType === 'MA') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'MA',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'MA5',
            rightField: 'MA20',
          },
        };
      }
      // DISPARITY
      else if (indicatorType === 'DISPARITY') {
        const ultraShortPeriod = indicatorSettings.disparityUltraShortPeriod || 5;
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'DISPARITY',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: `DISPARITY${ultraShortPeriod}`,
            rightField: 'NEUTRAL_100',
          },
        };
      }
      // NEW_PSYCHOLOGICAL
      else if (indicatorType === 'NEW_PSYCHOLOGICAL') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'NEW_PSYCHOLOGICAL',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'NEW_PSY_VALUE',
            rightField: 'OVERBOUGHT_75',
          },
        };
      }
      // INVEST_PSYCHOLOGICAL
      else if (indicatorType === 'INVEST_PSYCHOLOGICAL') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'INVEST_PSYCHOLOGICAL',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'INVEST_PSY_VALUE',
            rightField: 'OVERBOUGHT_75',
          },
        };
      }
      // WILLIAMS_R
      else if (indicatorType === 'WILLIAMS_R') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'WILLIAMS_R',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'WILLIAMS_R_VALUE',
            rightField: 'OVERBOUGHT_NEG20',
          },
        };
      }
      // BWI
      else if (indicatorType === 'BWI') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'BWI',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'BWI_VALUE',
            rightField: 'OVERBOUGHT_80',
          },
        };
      }
      // VR
      else if (indicatorType === 'VR') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'VR',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'VR_VALUE',
            rightField: 'OVERBOUGHT_200',
          },
        };
      }
      // VOLUME_OSC
      else if (indicatorType === 'VOLUME_OSC') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType: 'VOLUME_OSC',
            conditionType: signalType === 'buy' ? 'CROSS_UP' : 'CROSS_DOWN', // 매수: 상향돌파, 매도: 하향돌파
            leftField: 'VOLUME_OSC_VALUE',
            rightField: 'ZERO_LINE',
          },
        };
      }
      // EMA는 기본 조건을 GOLDEN_CROSS로 설정
      else if (indicatorType === 'EMA') {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType,
            conditionType: 'GOLDEN_CROSS',
            targetValue: getDefaultTargetValue(indicatorType),
            period: getDefaultPeriod(indicatorType),
          },
        };
      }
      // 기타 지표
      else {
        newNode = {
          id: generateNodeId(),
          type: 'CONDITION',
          condition: {
            indicatorType,
            conditionType: 'CROSS_UP',
            targetValue: getDefaultTargetValue(indicatorType),
            period: getDefaultPeriod(indicatorType),
          },
        };
      }
    } else {
      console.warn('⚠️ 알 수 없는 타입:', draggedData.type);
      return;
    }
    
    console.log('✅ 새 노드 생성:', newNode);
    
    if (!rootNode) {
      // 루트 노드가 없으면 새 노드를 루트로 설정
      console.log('📌 루트 노드로 설정');
      onChange(newNode);
      onDropSuccess?.();
    } else if (droppedData && droppedData.node) {
      // 기존 노드에 자식으로 추가
      const parentNode = droppedData.node;
      
      if (parentNode.type === 'CONDITION') {
        alert('조건 노드는 자식을 가질 수 없습니다.');
        return;
      }
      
      console.log('➕ 자식 노드로 추가:', parentNode.id);
      const updated = addChild(rootNode, parentNode.id, newNode);
      onChange(updated);
      onDropSuccess?.();
    } else if (!droppedData || !droppedData.node) {
      // 빈 공간에 드롭한 경우
      if (draggedData.type === 'operator') {
        // 논리 연산자를 빈 공간에 드롭: 기존 루트를 자식으로 포함
        console.log('🔄 기존 루트를 자식으로 포함하는 새 루트 생성');
        newNode.children = [rootNode];
        onChange(newNode);
        onDropSuccess?.();
      } else {
        // 지표를 빈 공간에 드롭: 형제 노드를 추가하려면 논리 연산자 필요
        alert('조건을 추가하려면 논리 연산자 노드(AND/OR)에 드롭하세요.');
        console.log('❌ 유효하지 않은 드롭 - 조건은 논리 연산자 노드에만 추가 가능');
      }
    }
  };

  /**
   * 노드 편집 핸들러
   */
  const handleEditNode = (nodeId: string) => {
    if (!rootNode) return;
    
    const node = findNode(rootNode, nodeId);
    if (node && node.type === 'CONDITION' && node.condition) {
      setEditingNodeId(nodeId);
      setEditingCondition(node.condition);
    }
  };

  /**
   * 조건 저장 핸들러
   */
  const handleSaveCondition = (newCondition: ConditionDSL) => {
    if (!rootNode || !editingNodeId) return;
    
    const updated = updateNode(rootNode, editingNodeId, (node) => ({
      ...node,
      condition: newCondition,
    }));
    
    onChange(updated);
    setEditingNodeId(null);
    setEditingCondition(null);
  };

  /**
   * 노드 삭제 핸들러
   */
  const handleDeleteNode = (nodeId: string) => {
    if (!rootNode) return;
    
    if (rootNode.id === nodeId) {
      // 루트 노드 삭제
      onChange(null);
    } else {
      // 자식 노드 삭제
      const updated = deleteNode(rootNode, nodeId);
      onChange(updated);
    }
  };

  /**
   * 자식 추가 핸들러 (+ 버튼)
   */
  const handleAddChild = (parentId: string) => {
    if (!rootNode) return;
    
    // 기본 AND 노드 추가
    const newChild = createEmptyLogicNode('CONDITION');
    const updated = addChild(rootNode, parentId, newChild);
    onChange(updated);
  };

  // ============================================================
  // 렌더링
  // ============================================================

  return (
    <Box
      ref={setDropRef}
      sx={{
        height: '100%',
        overflow: 'auto',
        p: 1,
        backgroundColor: isOver ? 
          theme.palette.action.hover : 
          'transparent',
        border: isOver ? `2px dashed ${theme.palette.primary.main}` : 'none',
        transition: 'all 0.2s ease',
      }}
    >
      {rootNode ? (
        <TreeNode
          node={rootNode}
          onChange={(updatedNode) => onChange(updatedNode)}
          onEdit={handleEditNode}
          onDelete={handleDeleteNode}
          onAddChild={handleAddChild}
          disabled={disabled}
          signalType={signalType}
        />
      ) : (
        <Alert 
          severity="info" 
          sx={{ 
            mt: 2,
            backgroundColor: isOver ? theme.palette.primary.light + '30' : undefined,
            border: isOver ? `2px dashed ${theme.palette.primary.main}` : undefined,
          }}
        >
          {isOver ? 
            '여기에 드롭하세요!' : 
            '왼쪽 팔레트에서 논리 연산자나 지표를 드래그하여 전략을 시작하세요.'
          }
        </Alert>
      )}

      {/* 조건 편집 다이얼로그 */}
      <ConditionEditor
        open={editingNodeId !== null}
        condition={editingCondition}
        onSave={handleSaveCondition}
        onClose={() => {
          setEditingNodeId(null);
          setEditingCondition(null);
        }}
      />
    </Box>
  );
};

export default StrategyTreeBuilder;
