'use client';

import React, { useState, useMemo, useEffect } from 'react';
import { useSandboxStore } from '@/lib/store';
import { predictCryptoTrend, calculateBetaPosterior } from '@/lib/math/statistics';
import 'katex/dist/katex.min.css';
import { BlockMath, InlineMath } from 'react-katex';
import CryptoMathModal from './CryptoMathModal';
import {
  Cpu, Search, RefreshCw, BarChart2, TrendingUp, AlertCircle, Info,
  ChevronDown, ChevronUp, ArrowUpRight, ArrowDownRight, Compass, ShieldAlert, Sparkles,
  BookOpen, Check
} from 'lucide-react';

interface TrackerState {
  alpha: number;
  beta: number;
}
type TrackersMap = Record<string, TrackerState>;

const ESTIMATORS = [
  { id: 'rf', name: 'Random Forest' },
  { id: 'gb', name: 'XGBoost / GB' },
  { id: 'lr', name: 'Logistic Regression' },
  { id: 'svm', name: 'Support Vector Machine' },
  { id: 'mlp', name: 'Multi-Layer Perceptron' }
] as const;

const HORIZONS = [
  { id: 'T1', name: 'T+1 Day', days: 1 },
  { id: 'T5', name: 'T+5 Days', days: 5 },
  { id: 'T10', name: 'T+10 Days', days: 10 }
] as const;

interface CoinData {
  ticker: string;
  name: string;
  price: string;
  change24h: number;
  fundingRate: number; // in %
  openInterestChange: number; // in %
  longShortRatio: number;
  whaleInflow: number; // net flows
  exchangeReserves: number; // in %
  liqLong: string;
  liqShort: string;
}

const defaultCoins: Record<string, CoinData> = {
  'BTC': {
    ticker: 'BTC',
    name: 'Bitcoin',
    price: '$69,450',
    change24h: 2.4,
    fundingRate: -0.015,
    openInterestChange: 8.2,
    longShortRatio: 0.92,
    whaleInflow: 480,
    exchangeReserves: -1.4,
    liqLong: '$68,200',
    liqShort: '$70,500'
  },
  'ETH': {
    ticker: 'ETH',
    name: 'Ethereum',
    price: '$3,820',
    change24h: -1.2,
    fundingRate: 0.045,
    openInterestChange: -3.5,
    longShortRatio: 1.34,
    whaleInflow: -120,
    exchangeReserves: 0.8,
    liqLong: '$3,710',
    liqShort: '$3,920'
  },
  'SOL': {
    ticker: 'SOL',
    name: 'Solana',
    price: '$184.20',
    change24h: 5.8,
    fundingRate: 0.082,
    openInterestChange: 14.5,
    longShortRatio: 1.62,
    whaleInflow: 1250,
    exchangeReserves: -2.8,
    liqLong: '$176.00',
    liqShort: '$192.50'
  }
};

interface Forecast {
  id: string;
  ticker: string;
  entryPrice: number;
  resolved: boolean;
  timestamp: number;
  predictions: Record<string, Record<string, number>>;
  targetTimes: Record<string, number>;
  results?: Record<string, 'SUCCESS' | 'FAILURE'>;
}

export default function CryptoDemo() {
  const { addModelTrial } = useSandboxStore();

  // Local state for alphaSuccess and betaFailure to satisfy SSR hydration safeguarding
  const [alphaSuccess, setAlphaSuccess] = useState<number>(394);
  const [betaFailure, setBetaFailure] = useState<number>(118);
  const [forecasts, setForecasts] = useState<Forecast[]>([]);
  const [learningLoopLog, setLearningLoopLog] = useState<string>('');

  const [activeTicker, setActiveTicker] = useState<string>('BTC');
  const [searchQuery, setSearchQuery] = useState('');
  const [customCoins, setCustomCoins] = useState<Record<string, CoinData>>({});
  const [searchError, setSearchError] = useState(false);
  const [showMathAccordion, setShowMathAccordion] = useState(false);
  const [isMathModalOpen, setIsMathModalOpen] = useState(false);
  const [simulatedTrialLogged, setSimulatedTrialLogged] = useState(false);
  const [lastTrialSuccess, setLastTrialSuccess] = useState(false);

  // 15 independent Beta-Posterior trackers
  const [trackers, setTrackers] = useState<TrackersMap>({});
  const [ensemblePredictions, setEnsemblePredictions] = useState<any>(null);
  const [loadingEnsemble, setLoadingEnsemble] = useState(false);

  // Safely load counters and forecasts from localStorage on client mount
  useEffect(() => {
    const savedAlpha = localStorage.getItem('crypto_bayes_alpha');
    const savedBeta = localStorage.getItem('crypto_bayes_beta');
    const savedForecasts = localStorage.getItem('crypto_bayes_forecasts');

    let loadedAlpha = 394;
    let loadedBeta = 118;
    
    if (savedAlpha !== null) {
      loadedAlpha = parseInt(savedAlpha, 10);
      setAlphaSuccess(loadedAlpha);
    } else {
      localStorage.setItem('crypto_bayes_alpha', '394');
    }
    
    if (savedBeta !== null) {
      loadedBeta = parseInt(savedBeta, 10);
      setBetaFailure(loadedBeta);
    } else {
      localStorage.setItem('crypto_bayes_beta', '118');
    }

    // Load trackers
    const defaultPriors: Record<string, { alpha: number; beta: number }> = {
      'rf_T1': { alpha: 38, beta: 12 }, 'rf_T5': { alpha: 35, beta: 15 }, 'rf_T10': { alpha: 32, beta: 18 },
      'gb_T1': { alpha: 40, beta: 10 }, 'gb_T5': { alpha: 36, beta: 14 }, 'gb_T10': { alpha: 30, beta: 20 },
      'lr_T1': { alpha: 35, beta: 15 }, 'lr_T5': { alpha: 33, beta: 17 }, 'lr_T10': { alpha: 31, beta: 19 },
      'svm_T1': { alpha: 36, beta: 14 }, 'svm_T5': { alpha: 34, beta: 16 }, 'svm_T10': { alpha: 32, beta: 18 },
      'mlp_T1': { alpha: 39, beta: 11 }, 'mlp_T5': { alpha: 35, beta: 15 }, 'mlp_T10': { alpha: 31, beta: 19 }
    };
    const map: TrackersMap = {};
    Object.keys(defaultPriors).forEach((key) => {
      const a = localStorage.getItem(`crypto_bayes_tracker_${key}_alpha`);
      const b = localStorage.getItem(`crypto_bayes_tracker_${key}_beta`);
      const alphaVal = a !== null ? parseInt(a, 10) : defaultPriors[key].alpha;
      const betaVal = b !== null ? parseInt(b, 10) : defaultPriors[key].beta;
      map[key] = { alpha: alphaVal, beta: betaVal };
      
      if (a === null) {
        localStorage.setItem(`crypto_bayes_tracker_${key}_alpha`, String(alphaVal));
        localStorage.setItem(`crypto_bayes_tracker_${key}_beta`, String(betaVal));
      }
    });
    setTrackers(map);

    // Fetch ensemble predictions
    const fetchEnsemble = async () => {
      setLoadingEnsemble(true);
      try {
        const res = await fetch('/api/crypto/ensemble');
        if (res.ok) {
          const data = await res.json();
          setEnsemblePredictions(data.predictions || null);
        }
      } catch (err) {
        console.error("Failed to load ensemble predictions:", err);
      } finally {
        setLoadingEnsemble(false);
      }
    };
    fetchEnsemble();

    if (savedForecasts !== null) {
      try {
        const parsed = JSON.parse(savedForecasts);
        // Clean legacy formats if necessary
        if (parsed.length > 0 && parsed[0].predictions === undefined) {
          throw new Error("Legacy forecast format");
        }
        setForecasts(parsed);
      } catch (err) {
        console.log("Resetting legacy forecasts to multi-model format...");
        const now = Date.now();
        const mockForecasts: Forecast[] = [
          {
            id: 'mock-1',
            ticker: 'BTC',
            entryPrice: 65000,
            resolved: true,
            timestamp: now - 86400 * 1000 * 3,
            predictions: {
              rf: { T1: 0.62, T5: 0.58, T10: 0.54 },
              gb: { T1: 0.65, T5: 0.61, T10: 0.51 },
              lr: { T1: 0.58, T5: 0.57, T10: 0.55 },
              svm: { T1: 0.60, T5: 0.59, T10: 0.56 },
              mlp: { T1: 0.64, T5: 0.60, T10: 0.53 }
            },
            targetTimes: {
              T1: now - 86400 * 1000 * 2,
              T5: now - 86400 * 1000 * 2,
              T10: now - 86400 * 1000 * 2
            },
            results: {
              rf_T1: 'SUCCESS', rf_T5: 'SUCCESS', rf_T10: 'SUCCESS',
              gb_T1: 'SUCCESS', gb_T5: 'SUCCESS', gb_T10: 'SUCCESS',
              lr_T1: 'SUCCESS', lr_T5: 'SUCCESS', lr_T10: 'SUCCESS',
              svm_T1: 'SUCCESS', svm_T5: 'SUCCESS', svm_T10: 'SUCCESS',
              mlp_T1: 'SUCCESS', mlp_T5: 'SUCCESS', mlp_T10: 'SUCCESS'
            }
          }
        ];
        setForecasts(mockForecasts);
        localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(mockForecasts));
      }
    } else {
      const now = Date.now();
      const mockForecasts: Forecast[] = [
        {
          id: 'mock-1',
          ticker: 'BTC',
          entryPrice: 65000,
          resolved: true,
          timestamp: now - 86400 * 1000 * 3,
          predictions: {
            rf: { T1: 0.62, T5: 0.58, T10: 0.54 },
            gb: { T1: 0.65, T5: 0.61, T10: 0.51 },
            lr: { T1: 0.58, T5: 0.57, T10: 0.55 },
            svm: { T1: 0.60, T5: 0.59, T10: 0.56 },
            mlp: { T1: 0.64, T5: 0.60, T10: 0.53 }
          },
          targetTimes: {
            T1: now - 86400 * 1000 * 2,
            T5: now - 86400 * 1000 * 2,
            T10: now - 86400 * 1000 * 2
          },
          results: {
            rf_T1: 'SUCCESS', rf_T5: 'SUCCESS', rf_T10: 'SUCCESS',
            gb_T1: 'SUCCESS', gb_T5: 'SUCCESS', gb_T10: 'SUCCESS',
            lr_T1: 'SUCCESS', lr_T5: 'SUCCESS', lr_T10: 'SUCCESS',
            svm_T1: 'SUCCESS', svm_T5: 'SUCCESS', svm_T10: 'SUCCESS',
            mlp_T1: 'SUCCESS', mlp_T5: 'SUCCESS', mlp_T10: 'SUCCESS'
          }
        }
      ];
      setForecasts(mockForecasts);
      localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(mockForecasts));
    }
  }, []);

  // Client-side background learning loop evaluating forecasts against actual live returns
  useEffect(() => {
    const runLearningLoop = async () => {
      if (Object.keys(trackers).length === 0) return;
      try {
        const res = await fetch('/api/finance?region=crypto');
        if (!res.ok) return;
        const data = await res.json();
        const results = data.results || [];

        const pricesMap: Record<string, number> = {};
        results.forEach((r: any) => {
          pricesMap[r.ticker] = r.currentPrice;
          const cleanTicker = r.ticker.replace('-USD', '');
          pricesMap[cleanTicker] = r.currentPrice;
        });

        let updatedAny = false;
        const nextTrackers = { ...trackers };

        const updatedForecasts = forecasts.map((f) => {
          if (f.resolved) return f;
          
          const currentPrice = pricesMap[f.ticker] || pricesMap[`${f.ticker}-USD`];
          if (!currentPrice) return f;

          const now = Date.now();
          const resultsMap = { ...(f.results || {}) };
          let modified = false;

          HORIZONS.forEach((h) => {
            const hKey = h.id;
            const targetTime = f.targetTimes[hKey];
            
            ESTIMATORS.forEach((est) => {
              const trackerKey = `${est.id}_${hKey}`;
              if (now >= targetTime && !resultsMap[trackerKey]) {
                const priceWentUp = currentPrice > f.entryPrice;
                const predProb = f.predictions[est.id]?.[hKey] ?? 0.5;
                const predDir = predProb > 0.5 ? 'UP' : 'DOWN';
                
                const success = (predDir === 'UP' && priceWentUp) || (predDir === 'DOWN' && !priceWentUp);
                resultsMap[trackerKey] = success ? 'SUCCESS' : 'FAILURE';
                
                if (success) {
                  nextTrackers[trackerKey].alpha += 1;
                  localStorage.setItem(`crypto_bayes_tracker_${trackerKey}_alpha`, String(nextTrackers[trackerKey].alpha));
                } else {
                  nextTrackers[trackerKey].beta += 1;
                  localStorage.setItem(`crypto_bayes_tracker_${trackerKey}_beta`, String(nextTrackers[trackerKey].beta));
                }
                
                addModelTrial(success);
                updatedAny = true;
                modified = true;
              }
            });
          });

          if (modified) {
            const allResolved = ESTIMATORS.every(est => 
              HORIZONS.every(h => resultsMap[`${est.id}_${h.id}`] !== undefined)
            );
            return {
              ...f,
              results: resultsMap,
              resolved: allResolved
            };
          }
          return f;
        });

        if (updatedAny) {
          setTrackers(nextTrackers);
          setForecasts(updatedForecasts);
          localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(updatedForecasts));
          setLearningLoopLog(`Processed active ensemble forecasts. Trackers calibration updated.`);
          setTimeout(() => setLearningLoopLog(''), 6000);
        }
      } catch (err) {
        console.error("Learning loop evaluation error:", err);
      }
    };

    if (forecasts.length > 0) {
      runLearningLoop();
    }
    const interval = setInterval(runLearningLoop, 30000);
    return () => clearInterval(interval);
  }, [forecasts, trackers, addModelTrial]);

  // Active Coin data retrieval
  const activeCoin = useMemo(() => {
    return customCoins[activeTicker] || defaultCoins[activeTicker] || defaultCoins['BTC'];
  }, [activeTicker, customCoins]);

  // Helper to fetch/load prediction probabilities
  const getPredictionProb = (estimator: string, horizon: string): number => {
    if (ensemblePredictions && ensemblePredictions[activeTicker] && ensemblePredictions[activeTicker][estimator]) {
      return ensemblePredictions[activeTicker][estimator][horizon] ?? 0.5;
    }
    // Fallback static predictions
    const defaultMapping: Record<string, Record<string, Record<string, number>>> = {
      BTC: {
        rf: { T1: 0.62, T5: 0.58, T10: 0.54 },
        gb: { T1: 0.65, T5: 0.61, T10: 0.51 },
        lr: { T1: 0.58, T5: 0.57, T10: 0.55 },
        svm: { T1: 0.60, T5: 0.59, T10: 0.56 },
        mlp: { T1: 0.64, T5: 0.60, T10: 0.53 }
      },
      ETH: {
        rf: { T1: 0.60, T5: 0.59, T10: 0.54 },
        gb: { T1: 0.66, T5: 0.61, T10: 0.48 },
        lr: { T1: 0.58, T5: 0.55, T10: 0.56 },
        svm: { T1: 0.59, T5: 0.59, T10: 0.56 },
        mlp: { T1: 0.64, T5: 0.59, T10: 0.55 }
      },
      SOL: {
        rf: { T1: 0.65, T5: 0.58, T10: 0.52 },
        gb: { T1: 0.63, T5: 0.63, T10: 0.54 },
        lr: { T1: 0.59, T5: 0.58, T10: 0.54 },
        svm: { T1: 0.60, T5: 0.62, T10: 0.56 },
        mlp: { T1: 0.66, T5: 0.60, T10: 0.51 }
      }
    };
    const assetKey = defaultMapping[activeTicker] ? activeTicker : 'BTC';
    return defaultMapping[assetKey][estimator]?.[horizon] ?? 0.5;
  };

  // Compute live Random Forest baseline predictions (for legacy/visual compatibility)
  const mlPredictions = useMemo(() => {
    const inputs = {
      fundingRate: activeCoin.fundingRate,
      openInterestChange: activeCoin.openInterestChange,
      longShortRatio: activeCoin.longShortRatio,
      whaleInflow: activeCoin.whaleInflow
    };
    return predictCryptoTrend(inputs);
  }, [activeCoin]);

  // Apply Bayesian online learning error-correction posterior update (legacy/visual)
  const correctedPredictions = useMemo(() => {
    const shortTermCorrected = calculateBetaPosterior(
      alphaSuccess,
      betaFailure,
      mlPredictions.shortTermProb,
      12 // confidence scale
    );
    const mediumTermCorrected = calculateBetaPosterior(
      alphaSuccess,
      betaFailure,
      mlPredictions.mediumTermProb,
      12
    );

    return {
      shortTerm: shortTermCorrected,
      mediumTerm: mediumTermCorrected
    };
  }, [mlPredictions, alphaSuccess, betaFailure]);

  // Search/add new altcoin
  const handleAltcoinSearch = (e: React.FormEvent) => {
    e.preventDefault();
    setSearchError(false);
    const query = searchQuery.trim().toUpperCase();
    if (!query) return;

    if (defaultCoins[query]) {
      setActiveTicker(query);
      setSearchQuery('');
      return;
    }

    if (customCoins[query]) {
      setActiveTicker(query);
      setSearchQuery('');
      return;
    }

    const isBull = Math.random() > 0.45;
    const simulatedChange = isBull ? 3 + Math.random() * 8 : -2 - Math.random() * 6;
    const simulatedPrice = isBull ? 2 + Math.random() * 10 : 0.2 + Math.random() * 3;
    
    const newCoin: CoinData = {
      ticker: query,
      name: `${query} Token`,
      price: `$${simulatedPrice.toFixed(4)}`,
      change24h: parseFloat(simulatedChange.toFixed(2)),
      fundingRate: parseFloat((Math.random() * 0.12 - 0.04).toFixed(3)),
      openInterestChange: parseFloat((Math.random() * 30 - 10).toFixed(1)),
      longShortRatio: parseFloat((0.8 + Math.random() * 1.1).toFixed(2)),
      whaleInflow: Math.floor(Math.random() * 1500 - 400),
      exchangeReserves: parseFloat((Math.random() * 4 - 2).toFixed(1)),
      liqLong: `$${(simulatedPrice * 0.9).toFixed(4)}`,
      liqShort: `$${(simulatedPrice * 1.1).toFixed(4)}`
    };

    setCustomCoins(prev => ({ ...prev, [query]: newCoin }));
    setActiveTicker(query);
    setSearchQuery('');
  };

  // Manual logging of active forecast for all 15 models & horizons
  const handleLogManualForecast = () => {
    const entryPrice = parseFloat(activeCoin.price.replace(/[^0-9.]/g, ''));
    
    // Save snapshot of all predictions
    const predictionsMap: Record<string, Record<string, number>> = {};
    ESTIMATORS.forEach((est) => {
      predictionsMap[est.id] = {
        T1: getPredictionProb(est.id, 'T1'),
        T5: getPredictionProb(est.id, 'T5'),
        T10: getPredictionProb(est.id, 'T10')
      };
    });

    const now = Date.now();
    const newForecast: Forecast = {
      id: 'fc-' + now,
      ticker: activeCoin.ticker,
      entryPrice,
      resolved: false,
      timestamp: now,
      predictions: predictionsMap,
      targetTimes: {
        T1: now + 60 * 1000,   // resolves in 60s for direct visual validation
        T5: now + 300 * 1000,  // resolves in 300s
        T10: now + 600 * 1000  // resolves in 600s
      }
    };

    const nextForecasts = [newForecast, ...forecasts];
    setForecasts(nextForecasts);
    localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(nextForecasts));
    
    setLearningLoopLog(`Registered active multi-model forecast for ${activeCoin.ticker} at $${entryPrice}. Evaluating T+1 (60s), T+5 (5m), and T+10 (10m).`);
    setTimeout(() => setLearningLoopLog(''), 8000);
  };

  // Simulator for ensemble calibration (simulates trials across all 15 trackers)
  const handleSimulateEnsembleTrial = (success: boolean) => {
    if (Object.keys(trackers).length === 0) return;
    const nextTrackers = { ...trackers };
    ESTIMATORS.forEach((est) => {
      HORIZONS.forEach((h) => {
        const trackerKey = `${est.id}_${h.id}`;
        if (!nextTrackers[trackerKey]) {
          nextTrackers[trackerKey] = { alpha: 1, beta: 1 };
        }
        if (success) {
          nextTrackers[trackerKey].alpha += 1;
          localStorage.setItem(`crypto_bayes_tracker_${trackerKey}_alpha`, String(nextTrackers[trackerKey].alpha));
        } else {
          nextTrackers[trackerKey].beta += 1;
          localStorage.setItem(`crypto_bayes_tracker_${trackerKey}_beta`, String(nextTrackers[trackerKey].beta));
        }
      });
    });
    setTrackers(nextTrackers);
    setLastTrialSuccess(success);
    setSimulatedTrialLogged(true);
    setTimeout(() => setSimulatedTrialLogged(false), 2000);
  };

  const totalTrials = alphaSuccess + betaFailure;
  const priorAccuracy = (alphaSuccess / (totalTrials || 1)) * 100;

  return (
    <div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 text-slate-100 shadow-xl relative overflow-hidden">
      <div className="absolute top-0 right-0 w-32 h-32 bg-cyan-500/10 rounded-full blur-3xl -z-10" />

      {/* Header */}
      <div className="flex flex-col lg:flex-row justify-between items-start lg:items-center gap-4 border-b border-slate-800 pb-4 mb-6">
        <div>
          <span className="text-cyan-400 text-xs font-semibold uppercase tracking-wider">Level 4</span>
          <h2 className="text-2xl font-bold bg-gradient-to-r from-cyan-400 to-sky-200 bg-clip-text text-transparent">
            Predictive Crypto Models & Bayes Self-Correction
          </h2>
        </div>
        <div className="flex flex-wrap items-center gap-3">
          <span className="inline-flex items-center gap-1.5 px-3 py-2.5 rounded-xl text-xs font-bold bg-amber-500/10 text-amber-400 border border-amber-500/20 shadow-[0_0_15px_rgba(245,158,11,0.15)] h-11">
            <ShieldAlert className="w-4 h-4 text-amber-400" />
            <span>SYSTEM-AUTARK (OFFLINE-CORE)</span>
          </span>

          <button
            onClick={() => setIsMathModalOpen(true)}
            className="flex items-center gap-1.5 px-4 py-2 rounded-xl bg-slate-950/80 hover:bg-slate-900 border border-slate-800 hover:border-slate-700 transition-all font-semibold text-xs tracking-wider text-cyan-400 justify-center h-11"
          >
            <BookOpen className="w-3.5 h-3.5" />
            <span>📖 Quantitative Handbook</span>
          </button>

          <div className="bg-slate-900 border border-slate-800 rounded-xl px-4 py-2 flex items-center gap-3 h-11">
            <Cpu className="text-cyan-400 w-5 h-5 animate-spin-slow" />
            <div>
              <p className="text-slate-400 text-xs">Prior Accuracy</p>
              <p className="font-mono text-sm font-bold text-cyan-400">
                {priorAccuracy.toFixed(1)}% (n={totalTrials})
              </p>
            </div>
          </div>
        </div>
      </div>

      {/* SECTION 1: Top 3 Cards & Search Mask */}
      <div className="grid grid-cols-1 lg:grid-cols-4 gap-4 mb-6">
        
        {/* Status Cards BTC, ETH, SOL */}
        {['BTC', 'ETH', 'SOL'].map((tick) => {
          const coin = defaultCoins[tick];
          const isActive = activeTicker === tick;
          const isUp = coin.change24h >= 0;
          return (
            <div
              key={tick}
              onClick={() => setActiveTicker(tick)}
              className={`p-4 rounded-xl border cursor-pointer transition-all hover:bg-slate-850 flex items-center justify-between relative overflow-hidden ${isActive ? 'border-cyan-500/40 bg-cyan-500/5 shadow-md shadow-cyan-500/5' : 'border-slate-850 bg-slate-950/20'}`}
            >
              <div>
                <div className="text-xs text-slate-400 font-semibold">{coin.name}</div>
                <div className="text-xl font-extrabold font-mono mt-1 text-slate-100">{coin.price}</div>
                <div className={`text-[10px] font-bold font-mono mt-0.5 flex items-center gap-0.5 ${isUp ? 'text-emerald-400' : 'text-rose-400'}`}>
                  {isUp ? <ArrowUpRight className="w-3.5 h-3.5" /> : <ArrowDownRight className="w-3.5 h-3.5" />}
                  <span>{isUp ? '+' : ''}{coin.change24h}%</span>
                </div>
              </div>
              <div className="text-right">
                <span className="text-2xl font-bold font-mono text-slate-800">{tick}</span>
              </div>
            </div>
          );
        })}

        {/* Custom Search bar */}
        <div className="p-4 rounded-xl border border-slate-850 bg-slate-950/20 flex flex-col justify-center gap-2">
          <form onSubmit={handleAltcoinSearch} className="flex gap-2">
            <input
              type="text"
              required
              placeholder="Altcoin Ticker (e.g. LINK)"
              className="bg-slate-900 border border-slate-800 rounded-lg p-2 flex-1 text-slate-100 font-mono text-xs uppercase focus:outline-none focus:border-cyan-500"
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
            />
            <button
              type="submit"
              className="bg-slate-800 hover:bg-slate-700 text-cyan-400 hover:text-cyan-350 font-bold px-3 py-2 border border-slate-700 rounded-lg transition-colors text-xs"
            >
              <Search className="w-4 h-4" />
            </button>
          </form>
          {Object.keys(customCoins).length > 0 && (
            <div className="flex flex-wrap gap-1.5 mt-1 overflow-x-auto max-h-[32px]">
              {Object.keys(customCoins).map(tick => (
                <button
                  key={tick}
                  onClick={() => setActiveTicker(tick)}
                  className={`px-2 py-0.5 rounded font-mono text-[9px] border ${activeTicker === tick ? 'bg-cyan-500/10 text-cyan-400 border-cyan-500/30' : 'bg-slate-900 text-slate-500 border-slate-800'}`}
                >
                  {tick}
                </button>
              ))}
            </div>
          )}
        </div>
      </div>

      {/* SECTION 2: Derivatives & On-Chain Metrics Ledger */}
      <div className="grid grid-cols-1 xl:grid-cols-3 gap-8">
        
        {/* Left Column: Metrics Widgets */}
        <div className="xl:col-span-2 space-y-6">
          <h3 className="text-base font-bold text-white flex items-center gap-2 border-b border-slate-800 pb-3">
            <BarChart2 className="text-cyan-400 w-5 h-5" /> On-Chain &amp; Derivative Indicators ({activeCoin.ticker})
          </h3>

          <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
            
            {/* Funding & Open Interest Widget */}
            <div className="p-4 rounded-xl border border-slate-850 bg-slate-950/40 space-y-3">
              <h4 className="text-xs font-semibold text-slate-400 uppercase tracking-wider">Funding Rates &amp; Open Interest</h4>
              <div className="space-y-2">
                <div className="flex justify-between items-center text-sm font-mono">
                  <span className="text-slate-400 text-xs">Daily Funding Rate:</span>
                  <span className={`font-bold ${activeCoin.fundingRate < 0 ? 'text-emerald-400' : 'text-rose-400'}`}>
                    {activeCoin.fundingRate > 0 ? '+' : ''}{activeCoin.fundingRate.toFixed(3)}%
                  </span>
                </div>
                <div className="flex justify-between items-center text-sm font-mono">
                  <span className="text-slate-400 text-xs">Open Interest (24h Δ):</span>
                  <span className={`font-bold ${activeCoin.openInterestChange >= 0 ? 'text-emerald-400' : 'text-rose-400'}`}>
                    {activeCoin.openInterestChange > 0 ? '+' : ''}{activeCoin.openInterestChange.toFixed(1)}%
                  </span>
                </div>
              </div>
            </div>

            {/* Long/Short & Liquidation Widget */}
            <div className="p-4 rounded-xl border border-slate-850 bg-slate-950/40 space-y-3">
              <h4 className="text-xs font-semibold text-slate-400 uppercase tracking-wider">Positioning &amp; Liquidations</h4>
              <div className="space-y-2">
                <div className="flex justify-between items-center text-sm font-mono">
                  <span className="text-slate-400 text-xs">Long / Short Ratio:</span>
                  <span className="text-slate-200 font-bold">{activeCoin.longShortRatio}</span>
                </div>
                <div className="flex justify-between items-center text-xs font-mono">
                  <span className="text-slate-400">Liq Cluster:</span>
                  <span className="text-rose-400">Long: {activeCoin.liqLong} | Short: {activeCoin.liqShort}</span>
                </div>
              </div>
            </div>

            {/* Whale Flows Widget */}
            <div className="p-4 rounded-xl border border-slate-850 bg-slate-950/40 space-y-3">
              <h4 className="text-xs font-semibold text-slate-400 uppercase tracking-wider">Whale Flows (Net Inflow)</h4>
              <div className="space-y-2">
                <div className="flex justify-between items-center text-sm font-mono">
                  <span className="text-slate-400 text-xs">Net Inflow (Wallets):</span>
                  <span className={`font-bold ${activeCoin.whaleInflow >= 0 ? 'text-emerald-400' : 'text-rose-400'}`}>
                    {activeCoin.whaleInflow > 0 ? '+' : ''}{activeCoin.whaleInflow} {activeCoin.ticker}
                  </span>
                </div>
                <div className="text-[10px] text-slate-500 leading-relaxed font-sans">
                  Positive values signal that large investors are withdrawing assets from exchanges to private wallets (accumulation).
                </div>
              </div>
            </div>

            {/* Exchange Reserves Widget */}
            <div className="p-4 rounded-xl border border-slate-850 bg-slate-950/40 space-y-3">
              <h4 className="text-xs font-semibold text-slate-400 uppercase tracking-wider">Exchange Reserves (Spot)</h4>
              <div className="space-y-2">
                <div className="flex justify-between items-center text-sm font-mono">
                  <span className="text-slate-400 text-xs">Reserve Change (7d):</span>
                  <span className={`font-bold ${activeCoin.exchangeReserves <= 0 ? 'text-emerald-400' : 'text-rose-400'}`}>
                    {activeCoin.exchangeReserves > 0 ? '+' : ''}{activeCoin.exchangeReserves}%
                  </span>
                </div>
                <div className="text-[10px] text-slate-500 leading-relaxed font-sans">
                  Falling reserves at spot exchanges reduce available selling pressure and favor squeezes.
                </div>
              </div>
            </div>

          </div>
        </div>

        {/* Right Column: Multi-Model Ensemble & Walk-Forward Radar Table */}
        <div className="bg-slate-900/60 backdrop-blur-md border border-slate-800 rounded-2xl p-6 text-slate-100 shadow-xl space-y-6">
          <div className="flex justify-between items-center border-b border-slate-800 pb-3">
            <h3 className="text-base font-bold text-white flex items-center gap-2">
              <Compass className="text-cyan-400 w-5 h-5" /> Walk-Forward Ensemble Radar
            </h3>
            {loadingEnsemble && (
              <RefreshCw className="w-4 h-4 text-cyan-400 animate-spin" />
            )}
          </div>

          <div className="text-xs text-slate-400 leading-relaxed">
            Displays predictions and live calibration metrics (<InlineMath math="E[\theta] = \alpha / (\alpha + \beta)" />) across 15 independent trackers.
          </div>

          <div className="overflow-x-auto rounded-xl border border-slate-850 bg-slate-950/40">
            <table className="w-full border-collapse text-left text-[11px] font-mono">
              <thead>
                <tr className="border-b border-slate-800 text-slate-400 font-semibold bg-slate-900/40">
                  <th className="p-2">Estimator</th>
                  <th className="p-2 text-center">T+1</th>
                  <th className="p-2 text-center">T+5</th>
                  <th className="p-2 text-center">T+10</th>
                </tr>
              </thead>
              <tbody>
                {ESTIMATORS.map((est) => (
                  <tr key={est.id} className="border-b border-slate-900 hover:bg-slate-850/10">
                    <td className="p-2 font-semibold text-slate-300">{est.name}</td>
                    {HORIZONS.map((h) => {
                      const trackerKey = `${est.id}_${h.id}`;
                      const tracker = trackers[trackerKey] || { alpha: 1, beta: 1 };
                      const prob = getPredictionProb(est.id, h.id);
                      const direction = prob > 0.5 ? 'UP' : 'DOWN';
                      const expValue = tracker.alpha / (tracker.alpha + tracker.beta);
                      
                      return (
                        <td key={h.id} className="p-2 text-center border-l border-slate-900">
                          <div className="flex flex-col items-center">
                            <span className={`font-bold ${direction === 'UP' ? 'text-emerald-400' : 'text-rose-400'}`}>
                              {direction === 'UP' ? '▲' : '▼'} {(prob * 100).toFixed(0)}%
                            </span>
                            <span className="text-[9px] text-slate-500 mt-0.5">
                              {tracker.alpha}/{tracker.beta}
                            </span>
                            <span className="text-[9px] text-cyan-400 font-semibold mt-0.5">
                              E: {(expValue * 100).toFixed(1)}%
                            </span>
                          </div>
                        </td>
                      );
                    })}
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          {/* Model Calibration Log & Simulation */}
          <div className="p-4 rounded-xl border border-slate-850 bg-slate-950/40 space-y-3">
            <div className="flex items-center justify-between">
              <h4 className="text-xs font-bold text-slate-300 uppercase">Beta-Posterior Calibration</h4>
              <span className="text-[10px] text-slate-500 font-mono">Simulate Walk-Forward</span>
            </div>
            
            <div className="space-y-2">
              <p className="text-[10px] text-slate-400">
                Simulate model drift across all 15 independent trackers to calibrate Beta posterior expectations.
              </p>
              <div className="flex gap-2">
                <button
                  onClick={() => handleSimulateEnsembleTrial(true)}
                  className="flex-1 bg-emerald-500/10 hover:bg-emerald-500/20 text-emerald-400 border border-emerald-500/20 py-1.5 rounded-lg text-xs font-semibold font-mono"
                >
                  +1 Success (All)
                </button>
                <button
                  onClick={() => handleSimulateEnsembleTrial(false)}
                  className="flex-1 bg-rose-500/10 hover:bg-rose-500/20 text-rose-400 border border-rose-500/20 py-1.5 rounded-lg text-xs font-semibold font-mono"
                >
                  +1 False Alarm (All)
                </button>
              </div>
              {simulatedTrialLogged && (
                <div className="text-[10px] text-cyan-400 font-mono text-center animate-pulse">
                  Logged trial outcomes across all 15 estimators & horizons!
                </div>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* SECTION 3: Active Forecasts (Feedback Loop) */}
      <div className="grid grid-cols-1 xl:grid-cols-3 gap-8 mt-6">
        <div className="xl:col-span-2 bg-slate-950/30 rounded-xl p-4 border border-slate-850 space-y-4">
          <div className="flex justify-between items-center border-b border-slate-800 pb-3">
            <h3 className="text-sm font-bold text-white flex items-center gap-2">
              <TrendingUp className="text-cyan-400 w-4 h-4" /> Active Learning Feedback Loop
            </h3>
            <button
              onClick={handleLogManualForecast}
              className="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold py-1.5 px-3 rounded-lg text-xs transition-all active:scale-[0.96]"
            >
              Log Forecast to Feedback Loop
            </button>
          </div>

          {learningLoopLog && (
            <div className="p-3 bg-cyan-950/20 border border-cyan-900/40 rounded-lg text-xs text-cyan-300 flex items-center gap-2">
              <Info className="w-4 h-4 shrink-0" />
              <span>{learningLoopLog}</span>
            </div>
          )}

          <div className="overflow-x-auto max-h-56 scrollbar-thin">
            <table className="w-full border-collapse text-left text-xs font-mono">
              <thead>
                <tr className="border-b border-slate-800 text-slate-400 font-semibold bg-slate-900/40">
                  <th className="p-2">Ticker</th>
                  <th className="p-2">Entry Price</th>
                  <th className="p-2">Ensemble T+1</th>
                  <th className="p-2">Horizons (T1/T5/T10)</th>
                  <th className="p-2">Status</th>
                  <th className="p-2 text-right">Success Rate</th>
                </tr>
              </thead>
              <tbody>
                {forecasts.length === 0 ? (
                  <tr>
                    <td colSpan={6} className="p-4 text-center text-slate-500 italic">No forecasts registered yet.</td>
                  </tr>
                ) : (
                  forecasts.map((fc) => {
                    let avgT1Prob = 0.5;
                    if (fc.predictions) {
                      let sum = 0;
                      let count = 0;
                      Object.values(fc.predictions).forEach((hMap) => {
                        if (hMap && hMap.T1 !== undefined) {
                          sum += hMap.T1;
                          count++;
                        }
                      });
                      if (count > 0) avgT1Prob = sum / count;
                    }
                    const avgT1Dir = avgT1Prob > 0.5 ? 'UP' : 'DOWN';

                    const now = Date.now();
                    const getHorizonStatus = (hKey: 'T1' | 'T5' | 'T10') => {
                      const targetTime = fc.targetTimes[hKey];
                      const isPast = now >= targetTime;
                      
                      let successes = 0;
                      let total = 0;
                      ESTIMATORS.forEach((est) => {
                        const rKey = `${est.id}_${hKey}`;
                        if (fc.results && fc.results[rKey]) {
                          total++;
                          if (fc.results[rKey] === 'SUCCESS') successes++;
                        }
                      });

                      if (total === 5) {
                        return (
                          <span className="text-emerald-400 font-bold">
                            {successes}/5
                          </span>
                        );
                      }
                      if (isPast) {
                        return <span className="text-slate-400">Resolving...</span>;
                      }
                      const secondsLeft = Math.max(0, Math.ceil((targetTime - now) / 1000));
                      return <span className="text-slate-500 font-normal">{secondsLeft}s</span>;
                    };

                    let resolvedCount = 0;
                    let successCount = 0;
                    if (fc.results) {
                      Object.values(fc.results).forEach((r) => {
                        resolvedCount++;
                        if (r === 'SUCCESS') successCount++;
                      });
                    }

                    let statusText = 'PENDING';
                    if (resolvedCount === 15) {
                      statusText = 'RESOLVED';
                    } else if (resolvedCount > 0) {
                      statusText = `PARTIAL (${resolvedCount}/15)`;
                    }

                    return (
                      <tr key={fc.id} className="border-b border-slate-900 hover:bg-slate-850/10">
                        <td className="p-2 text-slate-200 font-bold">{fc.ticker}</td>
                        <td className="p-2 text-slate-350">${fc.entryPrice.toLocaleString()}</td>
                        <td className="p-2">
                          <span className={`px-1.5 py-0.5 rounded text-[10px] font-bold ${avgT1Dir === 'UP' ? 'bg-emerald-500/10 text-emerald-400' : 'bg-rose-500/10 text-rose-400'}`}>
                            {avgT1Dir} {(avgT1Prob * 100).toFixed(0)}%
                          </span>
                        </td>
                        <td className="p-2 text-slate-300">
                          <div className="flex gap-2 text-[10px]">
                            <span>T1: {getHorizonStatus('T1')}</span>
                            <span>T5: {getHorizonStatus('T5')}</span>
                            <span>T10: {getHorizonStatus('T10')}</span>
                          </div>
                        </td>
                        <td className="p-2 text-slate-400 text-[10px]">{statusText}</td>
                        <td className="p-2 text-right font-bold text-slate-300">
                          {resolvedCount > 0 ? (
                            <span className={successCount / resolvedCount >= 0.5 ? 'text-emerald-400' : 'text-rose-400'}>
                              {((successCount / resolvedCount) * 100).toFixed(0)}% ({successCount}/{resolvedCount})
                            </span>
                          ) : (
                            <span className="text-slate-500">-</span>
                          )}
                        </td>
                      </tr>
                    );
                  })
                )}
              </tbody>
            </table>
          </div>
        </div>

        {/* Informational overlay */}
        <div className="bg-slate-950/40 rounded-xl p-4 border border-slate-850 text-xs text-slate-400 space-y-2">
          <h4 className="font-bold text-slate-300 uppercase">Econometric Feedback Loop Spec</h4>
          <p className="leading-relaxed">
            The learning loop automatically evaluates active forecast parameters in the background against actual price histories returned by <code className="text-cyan-400 font-mono">/api/finance?region=crypto</code>.
          </p>
          <p className="leading-relaxed">
            When a logged forecast passes its evaluation target timestamp, it resolves against live market data, updating the Bayesian online calibration metrics <InlineMath math="\alpha" /> and <InlineMath math="\beta" />.
          </p>
        </div>
      </div>

      {/* SECTION 4: Mathematical LaTeX Accordion */}
      <div className="border-t border-slate-850 pt-4 mt-6">
        <button
          onClick={() => setShowMathAccordion(!showMathAccordion)}
          className="flex items-center gap-1.5 text-xs text-slate-400 hover:text-cyan-400 transition-colors focus:outline-none"
        >
          <span>{showMathAccordion ? <ChevronUp className="w-4 h-4" /> : <ChevronDown className="w-4 h-4" />}</span>
          <span className="font-semibold uppercase tracking-wider">Mathematical Formulation (Beta Update &amp; Random Forest)</span>
        </button>

        {showMathAccordion && (
          <div className="mt-4 p-4 rounded-xl border border-slate-850 bg-slate-950/40 text-xs text-slate-300 space-y-4">
            <div>
              <h4 className="font-bold text-cyan-400 mb-1">1. Bayesian Beta-Conjugate Error Correction</h4>
              <p className="mb-2">
                We model the error rate confidence interval of the model using a Beta distribution. The prior error state is represented by the parameters <InlineMath math="\alpha" /> (Successes) and <InlineMath math="\beta" /> (False Alarms):
              </p>
              <div className="py-2 overflow-x-auto text-slate-200">
                <BlockMath math="P \\sim \\text{Beta}(\\alpha, \\beta) \\quad \\text{with expected value } \\mathbb{E}[P] = \\frac{\\alpha}{\\alpha + \\beta}" />
              </div>
              <p className="mb-2">
                With a new ML signal <InlineMath math="P_{\\text{ML}}" />, we perform a conjugate Bayes update with a confidence weight <InlineMath math="w" />:
              </p>
              <div className="py-2 overflow-x-auto text-slate-200">
                <BlockMath math="\\alpha_{\\text{post}} = \\alpha + w \\cdot P_{\\text{ML}}, \\quad \\beta_{\\text{post}} = \\beta + w \\cdot (1 - P_{\\text{ML}})" />
              </div>
              <div className="py-2 overflow-x-auto text-slate-200">
                <BlockMath math="P_{\\text{Posterior}} = \\frac{\\alpha_{\\text{post}}}{\\alpha_{\\text{post}} + \\beta_{\\text{post}}}" />
              </div>
              <p className="text-slate-400">
                If the model is historically highly unstable (high <InlineMath math="\\beta" />), the Bayesian term corrects an overconfident ML signal downwards, safeguarding the robustness of the system.
              </p>
            </div>

            <div className="border-t border-slate-900 pt-3">
              <h4 className="font-bold text-cyan-400 mb-1">2. Random Forest Non-Linear Signal Mapping</h4>
              <p className="mb-2">
                The Random Forest simulates an ensemble of 10 weak decision trees. Each tree splits the data based on threshold criteria (e.g., 'Funding Rate &lt; -0.04%' and 'Open Interest &gt; 10%'):
              </p>
              <div className="py-2 overflow-x-auto text-slate-200">
                <BlockMath math="\\text{ML}_{\\text{prob}} = \\frac{1}{M} \\sum_{m=1}^{M} T_m(\\mathbf{x})" />
              </div>
              <p className="text-slate-400">
                where <InlineMath math="T_m(\\mathbf{x})" /> is the predicted output value of the <InlineMath math="m" />-th decision tree for the feature vector <InlineMath math="\\mathbf{x}" />.
              </p>
            </div>
          </div>
        )}
      </div>

      <CryptoMathModal isOpen={isMathModalOpen} onClose={() => setIsMathModalOpen(false)} />
    </div>
  );
}
