"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useParlay, legKey, type ParlayLeg } from "@/contexts/ParlayContext";
import { useAuth } from "@/contexts/AuthContext";
import GradeBadge from "@/components/vyndr/GradeBadge";
import SportBadge from "@/components/vyndr/SportBadge";
import ArchetypeBadge from "@/components/vyndr/ArchetypeBadge";
import { statLabel } from "@/lib/gradeAdapter";

/**
 * Parlay Lab (Wave 4B) — the CORRELATION BUILDER / PARLAY SLIP surface.
 *
 * The correlation MATH already lives in parlayService + /api/parlay/grade +
 * ParlayContext (combined grade, correlation, payout, tier-aware maxLegs). The
 * only thing missing was a leg source INDEPENDENT of the live slate: this page
 * browses tonight's PRE-GRADED props from /api/snapshot/:sport (and resolves a
 * player via /api/players/search), so a slip can be assembled even with no games
 * on screen. Legs go in via useParlay().addLeg (deduped by legKey); the slip
 * reads the combined grade / correlation flag / payout straight off the context.
 */

type Sport = ParlayLeg["sport"]; // 'NBA' | 'MLB' | 'WNBA'
const SPORTS: Sport[] = ["MLB", "NBA", "WNBA"];
const TIER_MAX = { free: 2, analyst: 4, desk: 6 } as const;
function tierMaxLegs(tier: string): number {
  return TIER_MAX[tier as keyof typeof TIER_MAX] ?? 2;
}

interface SnapshotGrade {
  player?: string;
  player_name?: string;
  stat_type?: string;
  stat?: string;
  line?: number;
  side?: string;
  grade?: string;
  confidence?: number;
  team?: string;
  game?: string;
  archetype?: string;
}

interface BrowseProp {
  player: string;
  stat: string; // canonical stat key (for addLeg + statLabel)
  line: number;
  direction: "over" | "under";
  grade: string;
  confidence: number;
  team?: string;
  game?: string;
  archetype?: string;
  key: string; // legKey
}

function toBrowseProp(g: SnapshotGrade): BrowseProp | null {
  const player = String(g.player || g.player_name || "").trim();
  const stat = String(g.stat_type || g.stat || "").toLowerCase().trim();
  const line = typeof g.line === "number" && Number.isFinite(g.line) ? g.line : NaN;
  if (!player || !stat || Number.isNaN(line)) return null;
  const direction = String(g.side || "over").toLowerCase().startsWith("u") ? "under" : "over";
  const grade = String(g.grade || "").trim();
  if (!grade || grade === "—") return null; // only graded props are addable legs
  return {
    player,
    stat,
    line,
    direction,
    grade,
    confidence: typeof g.confidence === "number" ? g.confidence : 0,
    team: g.team ? String(g.team) : undefined,
    game: g.game ? String(g.game) : undefined,
    archetype: g.archetype ? String(g.archetype) : undefined,
    key: legKey({ player, stat, line, direction }),
  };
}

export default function ParlayLabPage() {
  const { legs, addLeg, removeLeg, clear, combined, correlation, payout, grading, hasLeg, maxLegs, setMaxLegs, atCap } = useParlay();
  const { tier } = useAuth();
  const fullLab = tier === "desk" || tier === "analyst";

  const [sport, setSport] = useState<Sport>("MLB");
  const [rawProps, setRawProps] = useState<BrowseProp[]>([]);
  const [loading, setLoading] = useState(false);
  const [q, setQ] = useState("");
  const [suggest, setSuggest] = useState<string[]>([]);

  // Tier -> leg cap (free 2 / analyst 4 / desk 6), same wiring as ParlayPanel.
  useEffect(() => { setMaxLegs(tierMaxLegs(tier || "free")); }, [tier, setMaxLegs]);

  // Leg source #1 — the pre-graded slate (independent of the live board).
  useEffect(() => {
    let alive = true;
    setLoading(true);
    fetch(`/api/snapshot/${sport.toLowerCase()}`)
      .then((r) => (r.ok ? r.json() : null))
      .then((d) => {
        if (!alive) return;
        const grades: SnapshotGrade[] = d && Array.isArray(d.grades) ? d.grades : [];
        const mapped = grades.map(toBrowseProp).filter((p): p is BrowseProp => !!p);
        // Dedupe by legKey, keep highest confidence, sort A+ -> F then confidence.
        const byKey = new Map<string, BrowseProp>();
        for (const p of mapped) {
          const prev = byKey.get(p.key);
          if (!prev || p.confidence > prev.confidence) byKey.set(p.key, p);
        }
        setRawProps(Array.from(byKey.values()));
      })
      .catch(() => { if (alive) setRawProps([]); })
      .finally(() => { if (alive) setLoading(false); });
    return () => { alive = false; };
  }, [sport]);

  // Leg source #2 — the canonical player resolver, so search works even for a
  // player with no graded prop tonight (honest "no reads yet" instead of blank).
  useEffect(() => {
    const term = q.trim();
    if (term.length < 2) { setSuggest([]); return; }
    let alive = true;
    const t = setTimeout(() => {
      fetch(`/api/players/search?sport=${sport}&q=${encodeURIComponent(term)}`)
        .then((r) => (r.ok ? r.json() : null))
        .then((d) => {
          if (!alive) return;
          const players = d && Array.isArray(d.players) ? d.players : [];
          setSuggest(players.map((p: { full_name?: string }) => String(p.full_name || "")).filter(Boolean).slice(0, 6));
        })
        .catch(() => { if (alive) setSuggest([]); });
    }, 220);
    return () => { alive = false; clearTimeout(t); };
  }, [q, sport]);

  const filtered = useMemo(() => {
    const term = q.trim().toLowerCase();
    const list = term ? rawProps.filter((p) => p.player.toLowerCase().includes(term)) : rawProps;
    return list.slice(0, 40);
  }, [rawProps, q]);

  const toggle = useCallback((p: BrowseProp) => {
    const existing = legs.find((l) => legKey(l) === p.key);
    if (existing) { removeLeg(existing.id); return; }
    if (atCap) { if (typeof window !== "undefined" && !fullLab && window.__goPaywall) window.__goPaywall(); return; }
    addLeg({
      sport,
      player: p.player,
      stat: p.stat,
      line: p.line,
      direction: p.direction,
      grade: p.grade,
      confidence: p.confidence,
      team: p.team,
      game: p.game,
      archetype: p.archetype,
    });
  }, [legs, removeLeg, addLeg, atCap, fullLab, sport]);

  const searchedButEmpty = q.trim().length >= 2 && filtered.length === 0;

  return (
    <div style={{ maxWidth: 1040, margin: "0 auto", padding: "12px 16px 120px" }}>
      {/* Header */}
      <div style={{ marginBottom: 14 }}>
        <h1 className="mono" style={{ fontSize: 13, fontWeight: 700, letterSpacing: "0.28em", color: "var(--text-0)" }}>CORRELATION BUILDER</h1>
        <p className="mono" style={{ fontSize: 10.5, letterSpacing: "0.14em", color: "var(--text-2)", marginTop: 4 }}>
          PARLAY MATH · THE STAKE-DOWN SIGNAL · TAP TO BUILD
        </p>
      </div>

      {/* Sport tabs */}
      <div style={{ display: "flex", gap: 6, marginBottom: 12, flexWrap: "wrap" }}>
        {SPORTS.map((s) => (
          <button
            key={s}
            type="button"
            onClick={() => setSport(s)}
            className="mono"
            style={{
              padding: "6px 12px", borderRadius: 8, fontSize: 11, fontWeight: 700, letterSpacing: "0.08em", cursor: "pointer",
              background: s === sport ? "var(--g-a)" : "var(--bg-2)",
              color: s === sport ? "#06060B" : "var(--text-1)",
              border: `1px solid ${s === sport ? "var(--g-a)" : "var(--border)"}`,
            }}
          >
            {s}
          </button>
        ))}
      </div>

      {/* Search — independent of the slate; resolves via /api/players/search */}
      <input
        value={q}
        onChange={(e) => setQ(e.target.value)}
        placeholder="Search a player…"
        aria-label="Search a player"
        className="mono"
        style={{
          width: "100%", padding: "10px 12px", marginBottom: 6, borderRadius: 9, fontSize: 13,
          background: "var(--bg-2)", border: "1px solid var(--border)", color: "var(--text-0)",
        }}
      />
      {suggest.length > 0 && (
        <div className="mono" style={{ fontSize: 10.5, color: "var(--text-2)", marginBottom: 10, letterSpacing: "0.04em" }}>
          {suggest.join(" · ")}
        </div>
      )}

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, alignItems: "start" }} className="parlay-lab-grid">
        {/* LEFT — tonight's A/B reads (the leg source) */}
        <div style={{ borderRadius: 16, background: "var(--bg-1)", border: "1px solid var(--border)", overflow: "hidden" }}>
          <div style={{ padding: "12px 16px", borderBottom: "1px solid var(--border)", display: "flex", alignItems: "center", gap: 8 }}>
            <SportBadge sport={sport} />
            <span className="mono" style={{ fontSize: 10, fontWeight: 700, letterSpacing: "0.18em", color: "var(--text-0)" }}>TONIGHT&apos;S GRADED READS</span>
            <span className="mono" style={{ fontSize: 9, letterSpacing: "0.12em", color: "var(--text-2)", marginLeft: "auto" }}>TAP TO ADD</span>
          </div>

          {loading ? (
            <div className="mono" style={{ padding: 24, textAlign: "center", fontSize: 12, color: "var(--text-2)" }}>Loading tonight&apos;s reads…</div>
          ) : filtered.length === 0 ? (
            <div className="mono" style={{ padding: 24, textAlign: "center", fontSize: 12, color: "var(--text-2)", lineHeight: 1.6 }}>
              {searchedButEmpty
                ? `No graded ${sport} reads for “${q.trim()}” yet — grades post on the next snapshot.`
                : `No graded ${sport} reads on the board right now. Check back after the next snapshot.`}
            </div>
          ) : (
            <div>
              {filtered.map((p) => {
                const active = hasLeg(p.key);
                return (
                  <button
                    key={p.key}
                    type="button"
                    onClick={() => toggle(p)}
                    style={{
                      width: "100%", display: "flex", alignItems: "center", gap: 12, padding: "11px 16px",
                      borderTop: "1px solid var(--border)", background: active ? "rgba(0,212,160,.08)" : "transparent",
                      cursor: "pointer", textAlign: "left",
                    }}
                    aria-pressed={active}
                  >
                    <span style={{
                      width: 18, height: 18, flex: "none", borderRadius: 5, display: "flex", alignItems: "center", justifyContent: "center",
                      border: `1.5px solid ${active ? "var(--g-a)" : "var(--border-hi)"}`, background: active ? "var(--g-a)" : "transparent",
                      color: "#06060B", fontWeight: 800, fontSize: 12,
                    }} className="mono">{active ? "✓" : ""}</span>
                    <span style={{ flex: 1, minWidth: 0 }}>
                      <span style={{ fontSize: 13, fontWeight: 600, color: "var(--text-0)" }}>{p.player} </span>
                      <span className="mono" style={{ fontSize: 12, color: "var(--text-1)" }}>{p.direction === "under" ? "u" : "o"}{p.line} {statLabel(p.stat)}</span>
                      <span className="mono" style={{ display: "block", fontSize: 8.5, letterSpacing: "0.1em", color: "var(--text-2)", marginTop: 2 }}>
                        {sport}{p.team ? ` · ${p.team}` : ""}
                      </span>
                    </span>
                    {p.archetype && <ArchetypeBadge archetype={p.archetype} size="sm" variant="tint" />}
                    <GradeBadge grade={p.grade} size="sm" />
                  </button>
                );
              })}
            </div>
          )}
        </div>

        {/* RIGHT — the PARLAY SLIP (reads combined/correlation/payout from context) */}
        <div style={{ borderRadius: 16, background: "var(--bg-1)", border: "1px solid var(--border-hi)", overflow: "hidden", position: "sticky", top: 96 }}>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "12px 16px", borderBottom: "1px solid var(--border)" }}>
            <span className="mono" style={{ fontSize: 10, fontWeight: 700, letterSpacing: "0.22em", color: "var(--text-0)" }}>PARLAY SLIP</span>
            <span className="mono" style={{ fontSize: 10, letterSpacing: "0.12em", color: "var(--text-2)" }}>{legs.length} LEG{legs.length === 1 ? "" : "S"}</span>
          </div>

          {/* legs */}
          <div style={{ padding: "8px 10px", minHeight: 96, display: "flex", flexDirection: "column", gap: 6 }}>
            {legs.length === 0 ? (
              <div className="mono" style={{ padding: "22px 6px", textAlign: "center", fontSize: 12, color: "var(--text-2)", lineHeight: 1.6 }}>
                No legs yet — tap a graded read to start building. We grade the combined correlation and flag legs that secretly fight each other.
              </div>
            ) : (
              legs.map((l) => (
                <div key={l.id} style={{ display: "flex", alignItems: "center", gap: 9, padding: "8px 10px", background: "var(--bg-2)", borderRadius: 8, border: "1px solid var(--border)" }}>
                  {l.archetype && <ArchetypeBadge archetype={l.archetype} size="sm" variant="tint" />}
                  <span style={{ fontSize: 13, fontWeight: 700, color: "var(--text-0)", whiteSpace: "nowrap" }}>{l.player}</span>
                  <span className="mono" style={{ fontSize: 11, color: "var(--text-1)" }}>{statLabel(l.stat)} {l.direction === "under" ? "U" : "O"}{l.line}</span>
                  <GradeBadge grade={l.grade} size="sm" />
                  <button type="button" onClick={() => removeLeg(l.id)} aria-label={`Remove ${l.player}`} className="mono" style={{ marginLeft: "auto", background: "transparent", border: "none", color: "var(--miss)", cursor: "pointer", fontSize: 14 }}>✕</button>
                </div>
              ))
            )}
          </div>

          {/* leg-cap notice (tier-aware) */}
          {legs.length >= maxLegs && (
            <div className="mono" style={{ fontSize: 11, color: "var(--amber)", padding: "0 12px 10px" }}>
              {fullLab ? `Max ${maxLegs} legs on your plan.` : "Free tier caps at 2 legs — upgrade to Desk for 6."}
            </div>
          )}

          {/* CAUTION · CORRELATION FLAG — surfaces parlayService's warning */}
          {correlation?.warning && (
            <div style={{ margin: "0 12px 12px", padding: "11px 13px", borderRadius: 10, background: "rgba(255,179,71,.08)", border: "1px solid rgba(255,179,71,.28)" }}>
              <div className="mono" style={{ fontSize: 9, letterSpacing: "0.16em", color: "var(--amber)", fontWeight: 700, marginBottom: 5 }}>⚠ CAUTION · CORRELATION FLAG</div>
              <div className="mono" style={{ fontSize: 10.5, lineHeight: 1.45, color: "var(--text-1)" }}>{correlation.warning}</div>
            </div>
          )}

          {/* combined / grade / stake */}
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 1, background: "var(--border)", borderTop: "1px solid var(--border)" }}>
            <div style={{ background: "var(--bg-1)", padding: "13px 15px" }}>
              <div className="mono" style={{ fontSize: 9, letterSpacing: "0.14em", color: "var(--text-2)", marginBottom: 6 }}>CORRELATION</div>
              <div className="mono" style={{ fontSize: 15, fontWeight: 800, color: (correlation?.avg ?? 0) > 0.3 ? "var(--amber)" : "var(--g-a)" }}>
                {legs.length >= 2 && correlation ? correlation.avg.toFixed(2) : "—"}
              </div>
            </div>
            <div style={{ background: "var(--bg-1)", padding: "13px 15px" }}>
              <div className="mono" style={{ fontSize: 9, letterSpacing: "0.14em", color: "var(--text-2)", marginBottom: 6 }}>GRADE</div>
              {legs.length >= 2 && combined ? <GradeBadge grade={combined.grade} size="md" glow /> : <span className="mono" style={{ fontSize: 15, fontWeight: 800, color: "var(--text-2)" }}>{grading ? "…" : "—"}</span>}
            </div>
            <div style={{ background: "var(--bg-1)", padding: "13px 15px" }}>
              <div className="mono" style={{ fontSize: 9, letterSpacing: "0.14em", color: "var(--text-2)", marginBottom: 6 }}>EST · $10</div>
              {legs.length < 2 ? (
                <span className="mono" style={{ fontSize: 15, fontWeight: 800, color: "var(--text-2)" }}>—</span>
              ) : fullLab ? (
                <span className="mono" style={{ fontSize: 15, fontWeight: 800, color: "var(--g-a)" }}>{payout ? `$${payout.amount.toFixed(2)}` : grading ? "…" : "—"}</span>
              ) : (
                <span style={{ position: "relative", display: "inline-block" }}>
                  <span className="mono" style={{ fontSize: 15, fontWeight: 800, color: "var(--g-a)", filter: "blur(6px)", userSelect: "none" }}>$38.50</span>
                  <button type="button" onClick={() => typeof window !== "undefined" && window.__goPaywall && window.__goPaywall()} className="mono" style={{ position: "absolute", inset: 0, background: "transparent", border: "none", color: "var(--g-a)", cursor: "pointer", fontSize: 10, fontWeight: 700 }}>Upgrade →</button>
                </span>
              )}
            </div>
          </div>

          {legs.length > 0 && (
            <button type="button" onClick={clear} className="mono" style={{ width: "100%", padding: 11, borderRadius: 0, fontWeight: 700, letterSpacing: "0.06em", fontSize: 11, cursor: "pointer", background: "transparent", border: "none", borderTop: "1px solid var(--border)", color: "var(--miss)" }}>
              CLEAR SLIP
            </button>
          )}
        </div>
      </div>
    </div>
  );
}
