/**
 * MarketDepthPanel Component
 * Comprehensive market depth display with order book table and depth chart
 * Epic: OQI-003 Trading Charts
 */

import React, { useState, useCallback, useMemo } from 'react';
import {
  Bars3BottomLeftIcon,
  ChartBarIcon,
  TableCellsIcon,
  ArrowPathIcon,
  ArrowsUpDownIcon,
  FunnelIcon,
  ArrowDownTrayIcon,
} from '@heroicons/react/24/solid';

// Types
export interface OrderLevel {
  price: number;
  quantity: number;
  total: number;
  orders?: number;
  exchange?: string;
}

export interface MarketDepthData {
  symbol: string;
  bids: OrderLevel[];
  asks: OrderLevel[];
  midPrice: number;
  spread: number;
  spreadPercentage: number;
  imbalance: number; // bid volume / ask volume ratio
  lastUpdate: Date;
}

export type ViewMode = 'table' | 'chart' | 'split';
export type GroupingLevel = 'none' | '0.01' | '0.1' | '1' | '10' | '100';

interface MarketDepthPanelProps {
  data: MarketDepthData | null;
  onPriceClick?: (price: number, side: 'bid' | 'ask') => void;
  onRefresh?: () => void;
  onExport?: (format: 'csv' | 'json') => void;
  isLoading?: boolean;
  displayRows?: number;
  compact?: boolean;
}

const MarketDepthPanel: React.FC<MarketDepthPanelProps> = ({
  data,
  onPriceClick,
  onRefresh,
  onExport,
  isLoading = false,
  displayRows = 15,
  compact = false,
}) => {
  const [viewMode, setViewMode] = useState<ViewMode>('table');
  const [grouping, setGrouping] = useState<GroupingLevel>('none');
  const [showFilters, setShowFilters] = useState(false);
  const [minQuantity, setMinQuantity] = useState(0);
  const [highlightLarge, setHighlightLarge] = useState(true);

  // Group orders by price level
  const groupedData = useMemo(() => {
    if (!data || grouping === 'none') return data;

    const groupingValue = parseFloat(grouping);

    const groupOrders = (orders: OrderLevel[]): OrderLevel[] => {
      const grouped = new Map<number, OrderLevel>();

      for (const order of orders) {
        const groupedPrice = Math.floor(order.price / groupingValue) * groupingValue;
        const existing = grouped.get(groupedPrice);

        if (existing) {
          existing.quantity += order.quantity;
          existing.orders = (existing.orders || 1) + 1;
        } else {
          grouped.set(groupedPrice, {
            price: groupedPrice,
            quantity: order.quantity,
            total: 0,
            orders: 1,
          });
        }
      }

      // Recalculate totals
      const result = Array.from(grouped.values());
      let runningTotal = 0;
      for (const level of result) {
        runningTotal += level.quantity;
        level.total = runningTotal;
      }

      return result;
    };

    return {
      ...data,
      bids: groupOrders(data.bids),
      asks: groupOrders(data.asks),
    };
  }, [data, grouping]);

  // Filter by minimum quantity
  const filteredData = useMemo(() => {
    if (!groupedData || minQuantity === 0) return groupedData;

    return {
      ...groupedData,
      bids: groupedData.bids.filter((b) => b.quantity >= minQuantity),
      asks: groupedData.asks.filter((a) => a.quantity >= minQuantity),
    };
  }, [groupedData, minQuantity]);

  // Calculate max quantities for bar visualization
  const maxQuantity = useMemo(() => {
    if (!filteredData) return 1;
    const allQuantities = [
      ...filteredData.bids.map((b) => b.quantity),
      ...filteredData.asks.map((a) => a.quantity),
    ];
    return Math.max(...allQuantities, 1);
  }, [filteredData]);

  // Detect large orders (> 2x average)
  const largeOrderThreshold = useMemo(() => {
    if (!filteredData) return 0;
    const allQuantities = [
      ...filteredData.bids.map((b) => b.quantity),
      ...filteredData.asks.map((a) => a.quantity),
    ];
    const avg = allQuantities.reduce((a, b) => a + b, 0) / allQuantities.length;
    return avg * 2;
  }, [filteredData]);

  // Format helpers
  const formatPrice = (price: number): string => {
    if (price >= 1000) return price.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    if (price >= 1) return price.toFixed(4);
    return price.toFixed(6);
  };

  const formatQuantity = (qty: number): string => {
    if (qty >= 1000000) return `${(qty / 1000000).toFixed(2)}M`;
    if (qty >= 1000) return `${(qty / 1000).toFixed(2)}K`;
    return qty.toFixed(4);
  };

  const handleExport = useCallback((format: 'csv' | 'json') => {
    onExport?.(format);
  }, [onExport]);

  // Render order row
  const renderOrderRow = (
    level: OrderLevel,
    side: 'bid' | 'ask',
    index: number
  ) => {
    const barWidth = (level.quantity / maxQuantity) * 100;
    const isLarge = highlightLarge && level.quantity > largeOrderThreshold;
    const colorClass = side === 'bid' ? 'text-green-400' : 'text-red-400';
    const bgColorClass = side === 'bid' ? 'bg-green-500' : 'bg-red-500';

    return (
      <div
        key={`${side}-${level.price}-${index}`}
        className={`relative grid grid-cols-4 text-xs py-1 hover:bg-gray-700/50 cursor-pointer group transition-colors ${
          isLarge ? 'bg-yellow-500/10' : ''
        }`}
        onClick={() => onPriceClick?.(level.price, side)}
      >
        {/* Background bar */}
        <div
          className={`absolute ${side === 'bid' ? 'right-0' : 'left-0'} top-0 bottom-0 ${bgColorClass}/10 group-hover:${bgColorClass}/20 transition-colors`}
          style={{ width: `${barWidth}%` }}
        />

        {/* Content */}
        {side === 'bid' ? (
          <>
            <span className="relative text-gray-500 font-mono text-right pr-2">{formatQuantity(level.total)}</span>
            <span className="relative text-gray-300 font-mono text-right pr-2">{formatQuantity(level.quantity)}</span>
            <span className={`relative ${colorClass} font-mono text-right pr-2`}>{formatPrice(level.price)}</span>
            <span className="relative text-gray-600 font-mono text-center">{level.orders || '-'}</span>
          </>
        ) : (
          <>
            <span className="relative text-gray-600 font-mono text-center">{level.orders || '-'}</span>
            <span className={`relative ${colorClass} font-mono pl-2`}>{formatPrice(level.price)}</span>
            <span className="relative text-gray-300 font-mono pl-2">{formatQuantity(level.quantity)}</span>
            <span className="relative text-gray-500 font-mono pl-2">{formatQuantity(level.total)}</span>
          </>
        )}

        {/* Large order indicator */}
        {isLarge && (
          <div className="absolute right-1 top-1/2 -translate-y-1/2">
            <div className="w-1.5 h-1.5 rounded-full bg-yellow-400 animate-pulse" />
          </div>
        )}
      </div>
    );
  };

  return (
    <div className={`bg-gray-800/50 rounded-lg ${compact ? 'p-2' : 'p-4'} flex flex-col h-full`}>
      {/* Header */}
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-2">
          <Bars3BottomLeftIcon className="w-5 h-5 text-purple-400" />
          <h3 className={`font-semibold text-white ${compact ? 'text-xs' : 'text-sm'}`}>
            Market Depth
          </h3>
          {data && (
            <span className="text-xs text-gray-400 hidden sm:inline">
              {data.symbol}
            </span>
          )}
        </div>

        <div className="flex items-center gap-1">
          {/* View Mode Toggle */}
          <div className="flex items-center bg-gray-900/50 rounded p-0.5">
            <button
              onClick={() => setViewMode('table')}
              className={`p-1 rounded ${viewMode === 'table' ? 'bg-gray-700 text-white' : 'text-gray-400 hover:text-white'}`}
              title="Table View"
            >
              <TableCellsIcon className="w-4 h-4" />
            </button>
            <button
              onClick={() => setViewMode('chart')}
              className={`p-1 rounded ${viewMode === 'chart' ? 'bg-gray-700 text-white' : 'text-gray-400 hover:text-white'}`}
              title="Chart View"
            >
              <ChartBarIcon className="w-4 h-4" />
            </button>
            <button
              onClick={() => setViewMode('split')}
              className={`p-1 rounded ${viewMode === 'split' ? 'bg-gray-700 text-white' : 'text-gray-400 hover:text-white'}`}
              title="Split View"
            >
              <ArrowsUpDownIcon className="w-4 h-4" />
            </button>
          </div>

          <button
            onClick={() => setShowFilters(!showFilters)}
            className={`p-1.5 rounded transition-colors ${showFilters ? 'bg-blue-500/20 text-blue-400' : 'text-gray-400 hover:text-white hover:bg-gray-700'}`}
            title="Filters"
          >
            <FunnelIcon className="w-4 h-4" />
          </button>

          {onExport && (
            <button
              onClick={() => handleExport('csv')}
              className="p-1.5 text-gray-400 hover:text-white hover:bg-gray-700 rounded transition-colors"
              title="Export"
            >
              <ArrowDownTrayIcon className="w-4 h-4" />
            </button>
          )}

          {onRefresh && (
            <button
              onClick={onRefresh}
              disabled={isLoading}
              className="p-1.5 text-gray-400 hover:text-white hover:bg-gray-700 rounded transition-colors"
              title="Refresh"
            >
              <ArrowPathIcon className={`w-4 h-4 ${isLoading ? 'animate-spin' : ''}`} />
            </button>
          )}
        </div>
      </div>

      {/* Filters Panel */}
      {showFilters && (
        <div className="mb-3 p-3 bg-gray-900/50 rounded-lg">
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 text-xs">
            <div>
              <label className="text-gray-400 block mb-1">Price Grouping</label>
              <select
                value={grouping}
                onChange={(e) => setGrouping(e.target.value as GroupingLevel)}
                className="w-full bg-gray-800 border border-gray-700 rounded px-2 py-1 text-white text-xs"
              >
                <option value="none">None</option>
                <option value="0.01">0.01</option>
                <option value="0.1">0.1</option>
                <option value="1">1</option>
                <option value="10">10</option>
                <option value="100">100</option>
              </select>
            </div>
            <div>
              <label className="text-gray-400 block mb-1">Min Quantity</label>
              <input
                type="number"
                value={minQuantity}
                onChange={(e) => setMinQuantity(parseFloat(e.target.value) || 0)}
                min="0"
                step="0.01"
                className="w-full bg-gray-800 border border-gray-700 rounded px-2 py-1 text-white text-xs"
              />
            </div>
            <div className="col-span-2 flex items-end">
              <label className="flex items-center gap-2 cursor-pointer">
                <input
                  type="checkbox"
                  checked={highlightLarge}
                  onChange={(e) => setHighlightLarge(e.target.checked)}
                  className="rounded bg-gray-700 border-gray-600"
                />
                <span className="text-gray-300">Highlight large orders</span>
              </label>
            </div>
          </div>
        </div>
      )}

      {/* Stats Bar */}
      {data && (
        <div className="grid grid-cols-4 gap-2 mb-3 text-xs">
          <div className="bg-gray-900/50 rounded px-2 py-1.5">
            <div className="text-gray-500">Mid Price</div>
            <div className="text-white font-mono">{formatPrice(data.midPrice)}</div>
          </div>
          <div className="bg-gray-900/50 rounded px-2 py-1.5">
            <div className="text-gray-500">Spread</div>
            <div className="text-white font-mono">{data.spreadPercentage.toFixed(3)}%</div>
          </div>
          <div className="bg-gray-900/50 rounded px-2 py-1.5">
            <div className="text-gray-500">Imbalance</div>
            <div className={`font-mono ${data.imbalance > 1 ? 'text-green-400' : data.imbalance < 1 ? 'text-red-400' : 'text-white'}`}>
              {data.imbalance.toFixed(2)}
            </div>
          </div>
          <div className="bg-gray-900/50 rounded px-2 py-1.5">
            <div className="text-gray-500">Updated</div>
            <div className="text-white font-mono">
              {data.lastUpdate.toLocaleTimeString()}
            </div>
          </div>
        </div>
      )}

      {/* Main Content */}
      <div className="flex-1 overflow-hidden">
        {viewMode === 'table' && filteredData && (
          <div className="flex gap-2 h-full">
            {/* Bids Side */}
            <div className="flex-1 flex flex-col">
              <div className="grid grid-cols-4 text-xs text-gray-500 border-b border-gray-700 pb-1 mb-1">
                <span className="text-right pr-2">Total</span>
                <span className="text-right pr-2">Size</span>
                <span className="text-right pr-2 text-green-400">Bid</span>
                <span className="text-center">#</span>
              </div>
              <div className="flex-1 overflow-y-auto space-y-0.5">
                {filteredData.bids.slice(0, displayRows).map((level, idx) =>
                  renderOrderRow(level, 'bid', idx)
                )}
              </div>
            </div>

            {/* Asks Side */}
            <div className="flex-1 flex flex-col">
              <div className="grid grid-cols-4 text-xs text-gray-500 border-b border-gray-700 pb-1 mb-1">
                <span className="text-center">#</span>
                <span className="pl-2 text-red-400">Ask</span>
                <span className="pl-2">Size</span>
                <span className="pl-2">Total</span>
              </div>
              <div className="flex-1 overflow-y-auto space-y-0.5">
                {filteredData.asks.slice(0, displayRows).map((level, idx) =>
                  renderOrderRow(level, 'ask', idx)
                )}
              </div>
            </div>
          </div>
        )}

        {viewMode === 'chart' && (
          <div className="h-full flex items-center justify-center text-gray-500 text-sm">
            <div className="text-center">
              <ChartBarIcon className="w-12 h-12 mx-auto mb-2 opacity-50" />
              <p>Use OrderBookDepthVisualization for chart view</p>
            </div>
          </div>
        )}

        {viewMode === 'split' && filteredData && (
          <div className="h-full flex flex-col gap-2">
            {/* Compact table */}
            <div className="flex-1 flex gap-2 overflow-hidden">
              <div className="flex-1 overflow-y-auto">
                {filteredData.bids.slice(0, Math.floor(displayRows / 2)).map((level, idx) =>
                  renderOrderRow(level, 'bid', idx)
                )}
              </div>
              <div className="flex-1 overflow-y-auto">
                {filteredData.asks.slice(0, Math.floor(displayRows / 2)).map((level, idx) =>
                  renderOrderRow(level, 'ask', idx)
                )}
              </div>
            </div>
          </div>
        )}

        {/* Empty State */}
        {!isLoading && !data && (
          <div className="h-full flex items-center justify-center">
            <div className="text-center text-gray-500">
              <Bars3BottomLeftIcon className="w-12 h-12 mx-auto mb-2 opacity-50" />
              <p className="text-sm">No market depth data available</p>
            </div>
          </div>
        )}

        {/* Loading State */}
        {isLoading && (
          <div className="h-full flex items-center justify-center">
            <ArrowPathIcon className="w-8 h-8 text-blue-400 animate-spin" />
          </div>
        )}
      </div>

      {/* Legend */}
      {!compact && highlightLarge && (
        <div className="flex items-center gap-4 mt-2 pt-2 border-t border-gray-700 text-xs text-gray-500">
          <div className="flex items-center gap-1">
            <div className="w-1.5 h-1.5 rounded-full bg-yellow-400" />
            <span>Large order (&gt;2x avg)</span>
          </div>
          <div className="flex items-center gap-1">
            <div className="w-3 h-2 bg-green-500/20 rounded" />
            <span>Bid volume</span>
          </div>
          <div className="flex items-center gap-1">
            <div className="w-3 h-2 bg-red-500/20 rounded" />
            <span>Ask volume</span>
          </div>
        </div>
      )}
    </div>
  );
};

export default MarketDepthPanel;
