import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  ScatterChart,
  Scatter,
  XAxis,
  YAxis,
  ZAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  ReferenceLine,
  ReferenceArea,
} from 'recharts';

// Lazy-loaded by TickerDetailPage so recharts stays out of the main ticker chunk.

export interface FieldPoint {
  symbol: string;
  composite: number;
  momentum: number;
}

interface StandingMatrixProps {
  symbol: string;
  composite: number | null; // X for the highlighted dot (authoritative, from the scores endpoint)
  momentum: number | null; // Y for the highlighted dot (residual 12-1 momentum percentile)
  field: FieldPoint[]; // every tracked ticker, for the background cloud
  gateMomentum: number; // Y divider = the activation gate's momentum percentile
  status: 'top-pick' | 'qualified' | 'none';
  confidence?: number | null; // long confidence, for the verdict sidebar
}

// X divider: composite midpoint between "amber" (40–70) and clearly good (>70).
const QUALITY_DIV = 60;

type Tone = 'emerald' | 'amber' | 'sky' | 'slate';

const TONE: Record<Tone, { text: string; dot: string }> = {
  emerald: { text: 'text-emerald-300', dot: '#10b981' },
  amber: { text: 'text-amber-300', dot: '#f59e0b' },
  sky: { text: 'text-sky-300', dot: '#38bdf8' },
  slate: { text: 'text-gray-300', dot: '#94a3b8' },
};

function verdict(composite: number, momentum: number, gate: number): { label: string; tone: Tone; note: string } {
  const q = composite >= QUALITY_DIV;
  const m = momentum >= gate;
  if (m && q) return { label: 'Strong Buy', tone: 'emerald', note: 'Solid quality and top-tier momentum — clears the gate.' };
  if (m && !q) return { label: 'Momentum', tone: 'amber', note: 'Trending hard, but quality is thin — speculative.' };
  if (!m && q) return { label: 'Accumulate', tone: 'sky', note: 'Good quality; momentum not yet in the top tier.' };
  return { label: 'Pass', tone: 'slate', note: 'Neither quality nor momentum stands out yet.' };
}

function MatrixTip({ active, payload }: { active?: boolean; payload?: { payload: FieldPoint }[] }) {
  if (!active || !payload?.length) return null;
  const p = payload[0].payload;
  return (
    <div className="glass px-2.5 py-1.5 text-[11px]">
      <div className="text-gray-200">{p.symbol}</div>
      <div className="text-gray-400">
        quality <span className="text-gray-200">{Math.round(p.composite)}</span> · momentum{' '}
        <span className="text-gray-200">{Math.round(p.momentum)}</span>
      </div>
    </div>
  );
}

function StatRow({ label, value }: { label: string; value: string }) {
  return (
    <div className="flex items-baseline justify-between">
      <span>{label}</span>
      <span className="num text-gray-300">{value}</span>
    </div>
  );
}

export default function StandingMatrix({
  symbol,
  composite,
  momentum,
  field,
  gateMomentum,
  status,
  confidence,
}: StandingMatrixProps) {
  const navigate = useNavigate();
  const gate = gateMomentum > 0 ? gateMomentum : 80;
  const sym = symbol.toUpperCase();

  const here = useMemo<FieldPoint | null>(
    () => (composite != null && momentum != null ? { symbol: sym, composite, momentum } : null),
    [sym, composite, momentum],
  );
  // Background cloud excludes this ticker — it's drawn separately, highlighted.
  const others = useMemo(() => field.filter((p) => p.symbol.toUpperCase() !== sym), [field, sym]);

  const v = here ? verdict(here.composite, here.momentum, gate) : null;

  return (
    <div className="glass p-5">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <div className="text-[11px] uppercase tracking-wider text-gray-500">
          Standing — quality × momentum vs. the field
        </div>
        {status === 'top-pick' && (
          <span className="rounded-full border border-blue-500/30 bg-blue-500/15 px-2.5 py-0.5 text-[11px] font-medium text-blue-300">
            ★ Top Pick
          </span>
        )}
        {status === 'qualified' && (
          <span className="rounded-full border border-emerald-500/30 bg-emerald-500/15 px-2.5 py-0.5 text-[11px] font-medium text-emerald-300">
            ✓ Qualified
          </span>
        )}
      </div>

      <div className="mt-3 grid gap-4 lg:grid-cols-5">
        <div className="h-72 lg:col-span-3">
          <ResponsiveContainer width="100%" height="100%">
            <ScatterChart margin={{ top: 10, right: 16, bottom: 22, left: 0 }}>
              {/* Quadrant shading (behind everything) */}
              <ReferenceArea x1={QUALITY_DIV} x2={100} y1={gate} y2={100} fill="#10b981" fillOpacity={0.07} stroke="none" />
              <ReferenceArea x1={0} x2={QUALITY_DIV} y1={gate} y2={100} fill="#f59e0b" fillOpacity={0.06} stroke="none" />
              <ReferenceArea x1={QUALITY_DIV} x2={100} y1={0} y2={gate} fill="#38bdf8" fillOpacity={0.06} stroke="none" />
              <ReferenceArea x1={0} x2={QUALITY_DIV} y1={0} y2={gate} fill="#94a3b8" fillOpacity={0.05} stroke="none" />
              <CartesianGrid stroke="rgba(255,255,255,0.04)" />
              <ReferenceLine x={QUALITY_DIV} stroke="rgba(255,255,255,0.12)" />
              <ReferenceLine y={gate} stroke="rgba(255,255,255,0.12)" strokeDasharray="4 4" />
              <XAxis
                type="number"
                dataKey="composite"
                domain={[0, 100]}
                ticks={[0, 20, 40, 60, 80, 100]}
                tick={{ fill: '#6b7280', fontSize: 10 }}
                tickLine={false}
                axisLine={{ stroke: 'rgba(255,255,255,0.08)' }}
                label={{ value: 'Quality (composite) →', position: 'insideBottom', offset: -12, fill: '#6b7280', fontSize: 10 }}
              />
              <YAxis
                type="number"
                dataKey="momentum"
                domain={[0, 100]}
                ticks={[0, 20, 40, 60, 80, 100]}
                tick={{ fill: '#6b7280', fontSize: 10 }}
                width={30}
                tickLine={false}
                axisLine={false}
                label={{ value: 'Momentum pct', angle: -90, position: 'insideLeft', fill: '#6b7280', fontSize: 10 }}
              />
              <ZAxis range={[20, 20]} />
              <Tooltip cursor={{ strokeDasharray: '3 3', stroke: 'rgba(255,255,255,0.2)' }} content={<MatrixTip />} />
              <Scatter
                data={others}
                isAnimationActive={false}
                onClick={(p: any) => p?.symbol && navigate(`/ticker/${p.symbol}`)}
                shape={(props: { cx?: number; cy?: number }) => (
                  <circle cx={props.cx} cy={props.cy} r={3} fill="rgba(148,163,184,0.35)" className="cursor-pointer" />
                )}
              />
              {here && v && (
                <Scatter
                  data={[here]}
                  isAnimationActive={false}
                  shape={(props: { cx?: number; cy?: number }) => (
                    <circle
                      cx={props.cx}
                      cy={props.cy}
                      r={7}
                      fill="#ffffff"
                      stroke={TONE[v.tone].dot}
                      strokeWidth={3}
                      style={{ filter: `drop-shadow(0 0 6px ${TONE[v.tone].dot}66)` }}
                    />
                  )}
                />
              )}
            </ScatterChart>
          </ResponsiveContainer>
        </div>

        <div className="flex flex-col justify-center lg:col-span-2">
          {v && here ? (
            <>
              <div className={`text-2xl font-semibold ${TONE[v.tone].text}`}>{v.label}</div>
              <p className="mt-1 text-sm leading-snug text-gray-400">{v.note}</p>
              <div className="mt-3 space-y-1 text-xs text-gray-500">
                <StatRow label="Quality (composite)" value={`${Math.round(here.composite)}`} />
                <StatRow label="Residual momentum percentile" value={`${Math.round(here.momentum)}`} />
                {confidence != null && <StatRow label="Long confidence" value={`${Math.round(confidence)}%`} />}
              </div>
            </>
          ) : (
            <p className="text-sm leading-relaxed text-gray-500">
              {composite != null && momentum == null
                ? 'Setup is present, but residual momentum rank is missing — the activation gate treats unranked setups as not qualified. Refresh this ticker (or wait for the daily scan) so universe ranks are attached.'
                : 'No active setup, so this ticker isn’t ranked on the momentum axis yet. Run the scanner to place it.'}
            </p>
          )}
        </div>
      </div>

      <div className="mt-2 grid grid-cols-1 gap-x-4 gap-y-1 text-[11px] text-gray-500 sm:grid-cols-2">
        <span><span className="text-emerald-400">Strong Buy</span> — quality + momentum (top-right)</span>
        <span><span className="text-amber-400">Momentum</span> — trend without the quality</span>
        <span><span className="text-sky-400">Accumulate</span> — quality, awaiting momentum</span>
        <span><span className="text-gray-400">Pass</span> — neither stands out</span>
      </div>
      <p className="mt-2 text-[11px] leading-relaxed text-gray-600">
        Each dot is a tracked ticker; <span className="text-gray-300">this one is highlighted</span>. The dashed line is the
        activation gate ({Math.round(gate)}th-pct residual momentum) — above it qualifies for a top pick. Click any peer to open it.
      </p>
    </div>
  );
}
