import { useMemo, useRef, useEffect, useState } from 'react';
import { useMarketStore } from '../stores/marketStore';
import type { Trade } from '../types/models';

export type TradeSide = 'buy' | 'sell';

interface UseRecentTradesOptions {
  symbol?: string;
  maxTrades?: number;
  enableSound?: boolean;
}

interface TradeWithAnimation extends Trade {
  isNew?: boolean;
}

export function useRecentTrades({
  symbol,
  maxTrades = 20,
  enableSound = false,
}: UseRecentTradesOptions = {}) {
  const recentTrades = useMarketStore((state) => state.recentTrades);
  const prevTradesRef = useRef<Trade[]>([]);
  const [animatedTrades, setAnimatedTrades] = useState<TradeWithAnimation[]>([]);
  const audioContextRef = useRef<AudioContext | null>(null);

  // Initialize audio context for sound effects
  useEffect(() => {
    if (enableSound && typeof window !== 'undefined') {
      try {
        audioContextRef.current = new (window.AudioContext || (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext)();
      } catch {
        // Audio not supported
      }
    }
    return () => {
      audioContextRef.current?.close();
    };
  }, [enableSound]);

  // Play trade sound effect
  const playTradeSound = (side: TradeSide) => {
    if (!enableSound || !audioContextRef.current) return;

    try {
      const ctx = audioContextRef.current;
      const oscillator = ctx.createOscillator();
      const gainNode = ctx.createGain();

      oscillator.connect(gainNode);
      gainNode.connect(ctx.destination);

      if (side === 'buy') {
        // Higher pitch for buy
        oscillator.frequency.setValueAtTime(800, ctx.currentTime);
        oscillator.frequency.exponentialRampToValueAtTime(400, ctx.currentTime + 0.1);
      } else {
        // Lower pitch for sell
        oscillator.frequency.setValueAtTime(400, ctx.currentTime);
        oscillator.frequency.exponentialRampToValueAtTime(200, ctx.currentTime + 0.1);
      }

      gainNode.gain.setValueAtTime(0.1, ctx.currentTime);
      gainNode.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.1);

      oscillator.start(ctx.currentTime);
      oscillator.stop(ctx.currentTime + 0.1);
    } catch {
      // Ignore audio errors
    }
  };

  // Filter trades by symbol and add animation state
  const trades = useMemo(() => {
    const filtered = symbol
      ? recentTrades.filter((t) => t.symbol === symbol)
      : recentTrades;

    return filtered.slice(0, maxTrades);
  }, [recentTrades, symbol, maxTrades]);

  // Detect new trades and trigger animations
  useEffect(() => {
    const prevIds = new Set(prevTradesRef.current.map((t) => t.id));
    const newTrades = trades.filter((t) => !prevIds.has(t.id));

    // Play sound for new trades
    newTrades.forEach((trade) => {
      playTradeSound(trade.side);
    });

    // Mark new trades for animation
    const tradesWithAnimation = trades.map((trade) => ({
      ...trade,
      isNew: newTrades.some((nt) => nt.id === trade.id),
    }));

    setAnimatedTrades(tradesWithAnimation);

    // Clear animation flag after animation completes
    if (newTrades.length > 0) {
      const timer = setTimeout(() => {
        setAnimatedTrades((current) =>
          current.map((t) => ({ ...t, isNew: false }))
        );
      }, 500);
      return () => clearTimeout(timer);
    }

    prevTradesRef.current = trades;
  }, [trades, enableSound]);

  // Calculate trade statistics
  const stats = useMemo(() => {
    const buyTrades = trades.filter((t) => t.side === 'buy');
    const sellTrades = trades.filter((t) => t.side === 'sell');

    const buyVolume = buyTrades.reduce((sum, t) => sum + t.quantity, 0);
    const sellVolume = sellTrades.reduce((sum, t) => sum + t.quantity, 0);
    const totalVolume = buyVolume + sellVolume;

    const buyValue = buyTrades.reduce((sum, t) => sum + t.total, 0);
    const sellValue = sellTrades.reduce((sum, t) => sum + t.total, 0);

    return {
      buyCount: buyTrades.length,
      sellCount: sellTrades.length,
      buyVolume,
      sellVolume,
      totalVolume,
      buyValue,
      sellValue,
      buyRatio: totalVolume > 0 ? (buyVolume / totalVolume) * 100 : 50,
    };
  }, [trades]);

  return {
    trades: animatedTrades,
    stats,
    isLoading: trades.length === 0,
  };
}
