import { useState } from 'react';
import { useCompanies, useTrends, useRecommendations, usePositions, useModelPerformance, useModelFailures } from '../api/hooks';
import { useTradingMetrics, useTradingMetricsHistory } from '../api/tradingHooks';
import { TrendArrow, StatusBadge, ConfidenceBar, LoadingSpinner, DateRangeSelector, TickerFilter, Card } from '../components/ui';
import {
  BarChart, Bar,
  XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid,
  LineChart, Line,
} from 'recharts';

type DashboardId = 'gallery' | 'symbol-overview' | 'sentiment-heatmap' | 'prediction-accuracy' | 'paper-pnl' | 'model-quality';

const dashboards: Array<{ id: DashboardId; title: string; description: string }> = [
  { id: 'symbol-overview', title: 'Symbol Overview', description: 'Company cards with trend direction, latest recommendation, position status' },
  { id: 'sentiment-heatmap', title: 'Sentiment Heatmap', description: 'Sector × time matrix colored by aggregated sentiment' },
  { id: 'prediction-accuracy', title: 'Prediction Accuracy', description: 'Predicted confidence vs realized price move' },
  { id: 'paper-pnl', title: 'Paper Trading PnL', description: 'Equity curve, daily PnL bars, win rate metrics' },
  { id: 'model-quality', title: 'Model Quality', description: 'Extraction success rate, latency distribution, retry rate' },
];

export function DashboardsPage() {
  const [active, setActive] = useState<DashboardId>('gallery');
  const [hours, setHours] = useState(168);
  const [ticker, setTicker] = useState('');

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h1 className="text-xl font-semibold text-gray-100">Dashboards</h1>
        <div className="flex items-center gap-3">
          <TickerFilter value={ticker} onChange={setTicker} />
          <DateRangeSelector value={hours} onChange={setHours} />
        </div>
      </div>

      {/* Gallery / nav */}
      {active === 'gallery' ? (
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
          {dashboards.map((d) => (
            <Card key={d.id} className="cursor-pointer transition-colors hover:border-brand-500/50">
              <button className="w-full text-left" onClick={() => setActive(d.id)}>
                <div className="font-medium text-gray-200">{d.title}</div>
                <div className="mt-1 text-xs text-gray-500">{d.description}</div>
              </button>
            </Card>
          ))}
        </div>
      ) : (
        <div>
          <button onClick={() => setActive('gallery')} className="mb-3 text-sm text-brand-400 hover:underline">
            ← Back to gallery
          </button>
          {active === 'symbol-overview' && <SymbolOverview ticker={ticker} />}
          {active === 'sentiment-heatmap' && <SentimentHeatmap />}
          {active === 'prediction-accuracy' && <PredictionAccuracy />}
          {active === 'paper-pnl' && <PaperPnl />}
          {active === 'model-quality' && <ModelQuality hours={hours} />}
        </div>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Symbol Overview (unchanged — already uses PostgreSQL hooks)
// ---------------------------------------------------------------------------

function SymbolOverview({ ticker }: { ticker: string }) {
  const { data: companies, isLoading: cLoading } = useCompanies({ ticker: ticker || undefined });
  const { data: trends } = useTrends({ ticker: ticker || undefined, window: '7d', limit: 100 });
  const { data: recs } = useRecommendations({ ticker: ticker || undefined, limit: 100 });
  const { data: positions } = usePositions(ticker || undefined);

  if (cLoading) return <LoadingSpinner />;

  const trendMap = new Map((trends ?? []).map((t) => [t.entity_id, t]));
  const recMap = new Map((recs ?? []).map((r) => [r.ticker, r]));
  const posMap = new Map((positions ?? []).map((p) => [p.ticker, p]));

  return (
    <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
      {(companies ?? []).map((c) => {
        const trend = trendMap.get(c.ticker);
        const rec = recMap.get(c.ticker);
        const pos = posMap.get(c.ticker);
        return (
          <Card key={c.id}>
            <div className="flex items-center justify-between">
              <span className="font-mono font-semibold text-brand-300">{c.ticker}</span>
              {trend && <TrendArrow direction={trend.trend_direction} />}
            </div>
            <div className="mt-1 text-xs text-gray-500">{c.legal_name}</div>
            {trend && (
              <div className="mt-2 flex items-center gap-3 text-xs">
                <span className="text-gray-500">Strength</span>
                <ConfidenceBar value={trend.trend_strength} />
              </div>
            )}
            {rec && (
              <div className="mt-2 flex items-center gap-2">
                <StatusBadge status={rec.action} />
                <ConfidenceBar value={rec.confidence} />
              </div>
            )}
            {pos && (
              <div className="mt-2 text-xs">
                <span className="text-gray-500">Position: </span>
                <span className="text-gray-300">{pos.quantity} @ ${pos.avg_entry_price.toFixed(2)}</span>
                {pos.unrealized_pnl != null && (
                  <span className={pos.unrealized_pnl >= 0 ? 'ml-2 text-green-400' : 'ml-2 text-red-400'}>
                    {pos.unrealized_pnl >= 0 ? '+' : ''}{pos.unrealized_pnl.toFixed(2)}
                  </span>
                )}
              </div>
            )}
          </Card>
        );
      })}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Sentiment Heatmap — powered by useTrends (PostgreSQL)
// ---------------------------------------------------------------------------

function SentimentHeatmap() {
  const { data: trends, isLoading } = useTrends({ limit: 500 });
  const { data: companies } = useCompanies();

  if (isLoading) return <LoadingSpinner />;
  if (!trends?.length) return <p className="text-sm text-gray-500">No sentiment data available</p>;

  // Build sector lookup from companies
  const sectorMap = new Map((companies ?? []).map((c) => [c.ticker, c.sector ?? 'Unknown']));

  // Aggregate trend_strength by sector
  const sectorAgg = new Map<string, { total: number; count: number }>();
  for (const t of trends) {
    const sector = sectorMap.get(t.entity_id) ?? 'Unknown';
    const entry = sectorAgg.get(sector) ?? { total: 0, count: 0 };
    entry.total += t.trend_strength;
    entry.count += 1;
    sectorAgg.set(sector, entry);
  }

  const sectorData = Array.from(sectorAgg.entries())
    .map(([sector, { total, count }]) => ({
      sector,
      avgStrength: Math.round((total / count) * 100) / 100,
      count,
    }))
    .sort((a, b) => b.avgStrength - a.avgStrength);

  // Also build per-ticker chart
  const tickerAgg = new Map<string, { total: number; count: number }>();
  for (const t of trends) {
    const entry = tickerAgg.get(t.entity_id) ?? { total: 0, count: 0 };
    entry.total += t.trend_strength;
    entry.count += 1;
    tickerAgg.set(t.entity_id, entry);
  }

  const tickerData = Array.from(tickerAgg.entries())
    .map(([ticker, { total, count }]) => ({
      ticker,
      strength: Math.round((total / count) * 100) / 100,
    }))
    .sort((a, b) => b.strength - a.strength)
    .slice(0, 25);

  return (
    <div className="space-y-4">
      <Card>
        <h2 className="mb-3 text-sm font-medium text-gray-400">Average Trend Strength by Sector</h2>
        <ResponsiveContainer width="100%" height={300}>
          <BarChart data={sectorData}>
            <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
            <XAxis dataKey="sector" tick={{ fill: '#6b7280', fontSize: 10 }} angle={-20} textAnchor="end" height={60} />
            <YAxis tick={{ fill: '#6b7280', fontSize: 10 }} />
            <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
            <Bar dataKey="avgStrength" fill="#3b82f6" name="Avg Trend Strength" />
          </BarChart>
        </ResponsiveContainer>
      </Card>

      <Card>
        <h2 className="mb-3 text-sm font-medium text-gray-400">Trend Strength by Ticker (Top 25)</h2>
        <ResponsiveContainer width="100%" height={300}>
          <BarChart data={tickerData}>
            <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
            <XAxis dataKey="ticker" tick={{ fill: '#6b7280', fontSize: 10 }} />
            <YAxis tick={{ fill: '#6b7280', fontSize: 10 }} />
            <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
            <Bar dataKey="strength" fill="#8b5cf6" name="Trend Strength" />
          </BarChart>
        </ResponsiveContainer>
      </Card>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Prediction Accuracy — powered by useRecommendations (PostgreSQL)
// ---------------------------------------------------------------------------

function PredictionAccuracy() {
  const { data: recs, isLoading } = useRecommendations({ limit: 500 });

  if (isLoading) return <LoadingSpinner />;
  if (!recs?.length) return <p className="text-sm text-gray-500">No recommendation data available</p>;

  // Confidence distribution buckets
  const buckets = [
    { label: '<0.40', min: 0, max: 0.4 },
    { label: '0.40–0.55', min: 0.4, max: 0.55 },
    { label: '0.55–0.75', min: 0.55, max: 0.75 },
    { label: '0.75–1.00', min: 0.75, max: 1.01 },
  ];

  const confidenceData = buckets.map((b) => ({
    bucket: b.label,
    count: recs.filter((r) => r.confidence >= b.min && r.confidence < b.max).length,
  }));

  // Action distribution
  const actionCounts = new Map<string, number>();
  for (const r of recs) {
    actionCounts.set(r.action, (actionCounts.get(r.action) ?? 0) + 1);
  }
  const actionData = Array.from(actionCounts.entries())
    .map(([action, count]) => ({ action, count }))
    .sort((a, b) => b.count - a.count);

  return (
    <div className="space-y-4">
      <Card>
        <h2 className="mb-3 text-sm font-medium text-gray-400">Confidence Distribution</h2>
        <ResponsiveContainer width="100%" height={250}>
          <BarChart data={confidenceData}>
            <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
            <XAxis dataKey="bucket" tick={{ fill: '#6b7280', fontSize: 10 }} />
            <YAxis tick={{ fill: '#6b7280', fontSize: 10 }} />
            <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
            <Bar dataKey="count" fill="#3b82f6" name="Recommendations" />
          </BarChart>
        </ResponsiveContainer>
      </Card>

      <Card>
        <h2 className="mb-3 text-sm font-medium text-gray-400">Action Distribution</h2>
        <ResponsiveContainer width="100%" height={250}>
          <BarChart data={actionData}>
            <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
            <XAxis dataKey="action" tick={{ fill: '#6b7280', fontSize: 10 }} />
            <YAxis tick={{ fill: '#6b7280', fontSize: 10 }} />
            <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
            <Bar dataKey="count" fill="#22c55e" name="Count" />
          </BarChart>
        </ResponsiveContainer>
      </Card>

      <p className="text-xs text-gray-600">
        Note: Showing confidence and action distributions from recommendations. Realized price move comparison will be available once outcome tracking is implemented.
      </p>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Paper PnL — powered by trading engine API (PostgreSQL)
// ---------------------------------------------------------------------------

function PaperPnl() {
  const { data: metrics, isLoading: metricsLoading } = useTradingMetrics();
  const { data: snapshots, isLoading: historyLoading } = useTradingMetricsHistory();

  if (metricsLoading || historyLoading) return <LoadingSpinner />;

  const hasMetrics = !!metrics;
  const hasSnapshots = snapshots && snapshots.length > 0;

  if (!hasMetrics && !hasSnapshots) {
    return (
      <Card>
        <p className="text-sm text-gray-500">Paper trading metrics will appear after the first trading day.</p>
      </Card>
    );
  }

  const equityCurve = (snapshots ?? [])
    .map((s) => ({
      date: s.snapshot_date,
      value: s.portfolio_value,
      dailyReturn: s.daily_return != null ? Math.round(s.daily_return * 10000) / 100 : 0,
    }))
    .sort((a, b) => a.date.localeCompare(b.date));

  const winRate = metrics ? (metrics.win_rate * 100).toFixed(1) : '—';
  const winCount = metrics?.win_count ?? 0;
  const lossCount = metrics?.loss_count ?? 0;

  return (
    <div className="space-y-4">
      {/* Stat cards */}
      <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
        <Card className="text-center">
          <div className="text-xl font-bold text-gray-100">{winRate}%</div>
          <div className="text-xs text-gray-500">Win Rate</div>
        </Card>
        <Card className="text-center">
          <div className="text-xl font-bold text-green-400">{winCount}</div>
          <div className="text-xs text-gray-500">Wins</div>
        </Card>
        <Card className="text-center">
          <div className="text-xl font-bold text-red-400">{lossCount}</div>
          <div className="text-xs text-gray-500">Losses</div>
        </Card>
        <Card className="text-center">
          <div className={`text-xl font-bold ${(metrics?.unrealized_pnl ?? 0) >= 0 ? 'text-green-400' : 'text-red-400'}`}>
            ${(metrics?.unrealized_pnl ?? 0).toFixed(2)}
          </div>
          <div className="text-xs text-gray-500">Unrealized PnL</div>
        </Card>
      </div>

      {/* More metrics */}
      {hasMetrics && (
        <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
          <Card className="text-center">
            <div className="text-lg font-bold text-gray-100">${metrics.total_portfolio_value.toFixed(0)}</div>
            <div className="text-xs text-gray-500">Portfolio Value</div>
          </Card>
          <Card className="text-center">
            <div className="text-lg font-bold text-gray-100">{metrics.profit_factor.toFixed(2)}</div>
            <div className="text-xs text-gray-500">Profit Factor</div>
          </Card>
          <Card className="text-center">
            <div className="text-lg font-bold text-gray-100">{metrics.sharpe_ratio.toFixed(2)}</div>
            <div className="text-xs text-gray-500">Sharpe Ratio</div>
          </Card>
          <Card className="text-center">
            <div className="text-lg font-bold text-red-400">{(metrics.max_drawdown * 100).toFixed(1)}%</div>
            <div className="text-xs text-gray-500">Max Drawdown</div>
          </Card>
        </div>
      )}

      {/* Equity curve */}
      {hasSnapshots && (
        <Card>
          <h2 className="mb-3 text-sm font-medium text-gray-400">Equity Curve</h2>
          <ResponsiveContainer width="100%" height={250}>
            <LineChart data={equityCurve}>
              <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
              <XAxis dataKey="date" tick={{ fill: '#6b7280', fontSize: 10 }} />
              <YAxis tick={{ fill: '#6b7280', fontSize: 10 }} />
              <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
              <Line type="monotone" dataKey="value" stroke="#3b82f6" dot={false} name="Portfolio Value" />
            </LineChart>
          </ResponsiveContainer>
        </Card>
      )}

      {/* Daily returns */}
      {hasSnapshots && equityCurve.some((d) => d.dailyReturn !== 0) && (
        <Card>
          <h2 className="mb-3 text-sm font-medium text-gray-400">Daily Returns (%)</h2>
          <ResponsiveContainer width="100%" height={200}>
            <BarChart data={equityCurve}>
              <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
              <XAxis dataKey="date" tick={{ fill: '#6b7280', fontSize: 10 }} />
              <YAxis tick={{ fill: '#6b7280', fontSize: 10 }} />
              <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
              <Bar dataKey="dailyReturn" name="Daily Return %" fill="#3b82f6" />
            </BarChart>
          </ResponsiveContainer>
        </Card>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Model Quality — powered by ops API (PostgreSQL)
// ---------------------------------------------------------------------------

function ModelQuality({ hours }: { hours: number }) {
  const { data: perf, isLoading: perfLoading } = useModelPerformance(hours);
  const { data: failures, isLoading: failLoading } = useModelFailures(hours);

  if (perfLoading || failLoading) return <LoadingSpinner />;

  const perfData = perf as Record<string, unknown> | undefined;
  const failureList = (failures ?? []) as Array<Record<string, unknown>>;

  const totalCalls = Number(perfData?.total_calls ?? 0);
  const successCalls = Number(perfData?.successful_calls ?? 0);
  const successRate = totalCalls > 0 ? ((successCalls / totalCalls) * 100).toFixed(1) : '—';
  const avgLatency = Number(perfData?.avg_latency_ms ?? 0);
  const avgRetries = Number(perfData?.avg_retries ?? 0);

  const hasData = totalCalls > 0 || failureList.length > 0;
  if (!hasData) return <p className="text-sm text-gray-500">No model metrics available</p>;

  return (
    <div className="space-y-4">
      {/* Stat cards */}
      <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
        <Card className="text-center">
          <div className="text-xl font-bold text-gray-100">{totalCalls}</div>
          <div className="text-xs text-gray-500">Total Calls</div>
        </Card>
        <Card className="text-center">
          <div className={`text-xl font-bold ${Number(successRate) >= 90 ? 'text-green-400' : Number(successRate) >= 70 ? 'text-yellow-400' : 'text-red-400'}`}>
            {successRate}%
          </div>
          <div className="text-xs text-gray-500">Success Rate</div>
        </Card>
        <Card className="text-center">
          <div className="text-xl font-bold text-gray-100">{Math.round(avgLatency)}ms</div>
          <div className="text-xs text-gray-500">Avg Latency</div>
        </Card>
        <Card className="text-center">
          <div className="text-xl font-bold text-gray-100">{avgRetries.toFixed(2)}</div>
          <div className="text-xs text-gray-500">Avg Retries</div>
        </Card>
      </div>

      {/* Recent failures table */}
      {failureList.length > 0 && (
        <Card>
          <h2 className="mb-3 text-sm font-medium text-gray-400">Recent Failures ({failureList.length})</h2>
          <div className="overflow-x-auto">
            <table className="w-full text-left text-xs">
              <thead>
                <tr className="border-b border-surface-700 text-gray-500">
                  <th className="pb-2 pr-4">Time</th>
                  <th className="pb-2 pr-4">Model</th>
                  <th className="pb-2 pr-4">Error</th>
                  <th className="pb-2 pr-4">Retries</th>
                </tr>
              </thead>
              <tbody>
                {failureList.slice(0, 20).map((f, i) => (
                  <tr key={i} className="border-b border-surface-800">
                    <td className="py-1.5 pr-4 text-gray-400">{String(f.recorded_at ?? f.created_at ?? '').slice(0, 19)}</td>
                    <td className="py-1.5 pr-4 text-gray-300">{String(f.model_name ?? f.model ?? '—')}</td>
                    <td className="max-w-xs truncate py-1.5 pr-4 text-red-400">{String(f.error_message ?? f.error ?? '—')}</td>
                    <td className="py-1.5 pr-4 text-gray-400">{String(f.retry_count ?? '—')}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </Card>
      )}
    </div>
  );
}
