import { useState, useEffect, useRef, useCallback } from 'react';
import { Client, StompSubscription } from '@stomp/stompjs';
import SockJS from 'sockjs-client';
import axios from 'axios';
import { getApiBaseUrl } from '../services/apiConfig';

interface RealtimeCandleData {
  market: string;
  interval: string;
  candles?: any[];
  indicators?: any[];
  timestamp: number;
  type?: 'snapshot' | 'update';
}

interface UseRealtimeCandlesOptions {
  market: string;
  interval: string;
  enabled?: boolean;
  onData?: (data: RealtimeCandleData) => void;
  onError?: (error: any) => void;
}

type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';

const API_BASE_URL = getApiBaseUrl(); // https://exdev.co.kr/api

/**
 * 실시간 캔들 + 보조지표 WebSocket Hook
 * - Backend WebSocket 연결
 * - 자동 재연결
 * - Fallback: REST API
 */
export const useRealtimeCandles = ({
  market,
  interval,
  enabled = true,
  onData,
  onError,
}: UseRealtimeCandlesOptions) => {
  const [status, setStatus] = useState<ConnectionStatus>('disconnected');
  const [data, setData] = useState<RealtimeCandleData | null>(null);
  const [useFallback, setUseFallback] = useState(false);

  const stompClientRef = useRef<Client | null>(null);
  const subscriptionRef = useRef<StompSubscription | null>(null);
  const fallbackIntervalRef = useRef<NodeJS.Timeout | null>(null);
  const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  /**
   * REST API Fallback
   */
  const fetchDataViaREST = useCallback(async () => {
    try {
      console.log('[Realtime Candles] Fetching via REST API...');
      const response = await axios.get(`${API_BASE_URL}/api/candles/realtime`, {
        params: { market, interval, count: 200 },
      });

      if (response.data.success) {
        const candleData: RealtimeCandleData = {
          market,
          interval,
          candles: response.data.candles,
          indicators: response.data.indicators,
          timestamp: response.data.timestamp,
          type: 'snapshot',
        };

        setData(candleData);
        onData?.(candleData);
      }
    } catch (error) {
      console.error('[Realtime Candles] REST API error:', error);
      onError?.(error);
    }
  }, [market, interval, onData, onError]);

  /**
   * WebSocket 연결
   */
  const connect = useCallback(() => {
    if (!enabled) return;

    if (stompClientRef.current && stompClientRef.current.connected) {
      console.log('[Realtime Candles] Already connected');
      return;
    }

    setStatus('connecting');
    // ✅ WebSocket은 /ws 경로 사용 (API_BASE_URL에서 /api 제거)
    const baseUrl = API_BASE_URL.replace('/api', '');
    const wsUrl = `${baseUrl}/ws`;
    console.log('[Realtime Candles] API_BASE_URL:', API_BASE_URL);
    console.log('[Realtime Candles] Base URL (without /api):', baseUrl);
    console.log('[Realtime Candles] WebSocket URL:', wsUrl);
    console.log('[Realtime Candles] Connecting to WebSocket...');

    const client = new Client({
      brokerURL: wsUrl.replace('http', 'ws'),
      webSocketFactory: () => {
        console.log('[Realtime Candles] Creating SockJS connection to:', wsUrl);
        return new SockJS(wsUrl);
      },
      reconnectDelay: 5000,
      heartbeatIncoming: 10000,
      heartbeatOutgoing: 10000,
      debug: (str) => {
        console.log('[STOMP Debug]', str);
      },
      onConnect: () => {
        console.log('[Realtime Candles] Connected to WebSocket');
        setStatus('connected');
        setUseFallback(false);

        // 구독 요청
        const topic = `/topic/candles/${market}/${interval}`;
        subscriptionRef.current = client.subscribe(topic, (message) => {
          try {
            const candleData: RealtimeCandleData = JSON.parse(message.body);
            console.log('[Realtime Candles] Received data:', candleData.type);
            
            setData(candleData);
            onData?.(candleData);
          } catch (error) {
            console.error('[Realtime Candles] Error parsing message:', error);
            onError?.(error);
          }
        });

        // 구독 시작 메시지 전송
        client.publish({
          destination: '/app/candles/subscribe',
          body: JSON.stringify({ market, interval }),
        });

        console.log(`[Realtime Candles] Subscribed to ${topic}`);
      },
      onDisconnect: () => {
        console.log('[Realtime Candles] Disconnected from WebSocket');
        setStatus('disconnected');
        
        // Fallback으로 전환
        if (enabled) {
          setUseFallback(true);
        }
      },
      onStompError: (frame) => {
        console.error('[Realtime Candles] ❌ STOMP error:', frame.headers.message);
        console.error('[Realtime Candles] Error details:', frame.body);
        console.error('[Realtime Candles] Full frame:', frame);
        setStatus('error');
        onError?.(frame);

        // Fallback으로 전환
        setUseFallback(true);
      },
      onWebSocketClose: (event) => {
        console.error('[Realtime Candles] ❌ WebSocket closed:', event);
        console.error('[Realtime Candles] Code:', event.code, 'Reason:', event.reason);
      },
      onWebSocketError: (event) => {
        console.error('[Realtime Candles] ❌ WebSocket error:', event);
        console.error('[Realtime Candles] Target URL:', wsUrl);
      },
    });

    client.activate();
    stompClientRef.current = client;
  }, [market, interval, enabled, onData, onError]);

  /**
   * WebSocket 연결 해제
   */
  const disconnect = useCallback(() => {
    if (stompClientRef.current) {
      const client = stompClientRef.current;

      // 구독 해제 메시지 전송
      if (client.connected) {
        try {
          client.publish({
            destination: '/app/candles/unsubscribe',
            body: JSON.stringify({ market, interval }),
          });
        } catch (error) {
          console.error('[Realtime Candles] Error sending unsubscribe:', error);
        }
      }

      // STOMP 구독 해제
      if (subscriptionRef.current) {
        subscriptionRef.current.unsubscribe();
        subscriptionRef.current = null;
      }

      // 연결 종료
      client.deactivate();
      stompClientRef.current = null;
    }

    // Fallback 인터벌 정리
    if (fallbackIntervalRef.current) {
      clearInterval(fallbackIntervalRef.current);
      fallbackIntervalRef.current = null;
    }

    // 재연결 타이머 정리
    if (reconnectTimeoutRef.current) {
      clearTimeout(reconnectTimeoutRef.current);
      reconnectTimeoutRef.current = null;
    }

    setStatus('disconnected');
  }, [market, interval]);

  /**
   * Fallback 모드 (REST API 폴링)
   */
  useEffect(() => {
    if (useFallback && enabled) {
      console.log('[Realtime Candles] Using REST API fallback');
      
      // 즉시 한 번 실행
      fetchDataViaREST();

      // 10초마다 폴링
      fallbackIntervalRef.current = setInterval(fetchDataViaREST, 10000);

      // 1분 후 WebSocket 재연결 시도
      reconnectTimeoutRef.current = setTimeout(() => {
        console.log('[Realtime Candles] Retrying WebSocket connection...');
        setUseFallback(false);
        connect();
      }, 60000);

      return () => {
        if (fallbackIntervalRef.current) {
          clearInterval(fallbackIntervalRef.current);
        }
        if (reconnectTimeoutRef.current) {
          clearTimeout(reconnectTimeoutRef.current);
        }
      };
    }
  }, [useFallback, enabled, fetchDataViaREST, connect]);

  /**
   * 초기화 및 정리
   */
  useEffect(() => {
    if (!enabled) {
      disconnect();
      return;
    }

    connect();

    return () => {
      disconnect();
    };
  }, [market, interval, enabled, connect, disconnect]);

  /**
   * 수동 새로고침
   */
  const refresh = useCallback(async () => {
    if (useFallback) {
      await fetchDataViaREST();
    } else {
      // WebSocket 재연결
      disconnect();
      setTimeout(connect, 100);
    }
  }, [useFallback, fetchDataViaREST, disconnect, connect]);

  return {
    data,
    status,
    isConnected: status === 'connected',
    useFallback,
    refresh,
  };
};
