import { useState, useEffect, useRef } from 'react';
import { ChartDataService } from '../services/chartDataService';
import type { CandlestickData, MarketData, ChartInterval } from '../types';

interface UseChartDataOptions {
  symbol: string;
  interval: ChartInterval;
  enableRealtime?: boolean;
}

export function useChartData({ symbol, interval, enableRealtime = true }: UseChartDataOptions) {
  const [data, setData] = useState<CandlestickData[]>([]);
  const [marketData, setMarketData] = useState<MarketData | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  
  const unsubscribeRef = useRef<(() => void) | null>(null);

  // Fetch historical data
  useEffect(() => {
    let cancelled = false;

    const fetchData = async () => {
      try {
        setIsLoading(true);
        setError(null);

        const { start, end } = ChartDataService.getDefaultDateRange(interval);
        const historicalData = await ChartDataService.getHistoricalData(
          symbol,
          interval,
          start,
          end
        );

        if (!cancelled) {
          setData(historicalData);
        }

        // Fetch current market data
        const currentData = await ChartDataService.getRealtimeData(symbol);
        if (!cancelled) {
          setMarketData(currentData);
        }
      } catch (err) {
        if (!cancelled) {
          setError(err instanceof Error ? err.message : 'Failed to load chart data');
        }
      } finally {
        if (!cancelled) {
          setIsLoading(false);
        }
      }
    };

    fetchData();

    return () => {
      cancelled = true;
    };
  }, [symbol, interval]);

  // Subscribe to real-time updates
  useEffect(() => {
    if (!enableRealtime || isLoading || error) return;

    const handleRealtimeUpdate = (newCandle: CandlestickData) => {
      setData(prevData => {
        const lastCandle = prevData[prevData.length - 1];
        
        // Check if this is an update to the current candle or a new one
        if (lastCandle && lastCandle.time === newCandle.time) {
          // Update existing candle
          return [...prevData.slice(0, -1), newCandle];
        } else {
          // Add new candle
          return [...prevData, newCandle];
        }
      });

      // Update market data
      setMarketData(prev => {
        if (!prev) return prev;
        
        const change = newCandle.close - (prev.previousClose || prev.price);
        const changePercent = (change / (prev.previousClose || prev.price)) * 100;

        return {
          ...prev,
          price: newCandle.close,
          change,
          changePercent,
          high: Math.max(prev.high, newCandle.high),
          low: Math.min(prev.low, newCandle.low),
          volume: prev.volume + (newCandle.volume || 0),
          timestamp: new Date().toISOString(),
        };
      });
    };

    const handleError = (error: Error) => {
      console.error('Real-time data error:', error);
    };

    unsubscribeRef.current = ChartDataService.subscribeToRealtime(
      symbol,
      handleRealtimeUpdate,
      handleError
    );

    return () => {
      if (unsubscribeRef.current) {
        unsubscribeRef.current();
        unsubscribeRef.current = null;
      }
    };
  }, [symbol, enableRealtime, isLoading, error]);

  const refresh = async () => {
    const { start, end } = ChartDataService.getDefaultDateRange(interval);
    
    try {
      setIsLoading(true);
      const newData = await ChartDataService.getHistoricalData(symbol, interval, start, end);
      setData(newData);
      
      const currentData = await ChartDataService.getRealtimeData(symbol);
      setMarketData(currentData);
      
      setError(null);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to refresh data');
    } finally {
      setIsLoading(false);
    }
  };

  return {
    data,
    marketData,
    isLoading,
    error,
    refresh,
  };
}