/* AcquiCup — prediction detail (score entry, X2 bonus, potential points) */
const { useState, useEffect, useRef, useMemo } = React;

// Re-render once when `targetMs` is reached so a time-based lock can flip live —
// a SINGLE timeout at the kickoff instant, not a perpetual interval. Returns "now"
// in ms. No tick is scheduled for a kickoff already passed or more than 24h out
// (the user won't sit on the page that long — a reload refreshes it). Used so the
// prediction form freezes the moment a match starts, matching the server lock.
function useNowUntil(targetMs) {
  const [now, setNow] = useState(() => Date.now());
  useEffect(() => {
    if (targetMs == null) return;
    const delay = targetMs - Date.now();
    if (delay <= 0 || delay > 86400000) return;
    const id = setTimeout(() => setNow(Date.now()), delay + 250);
    return () => clearTimeout(id);
  }, [targetMs]);
  return now;
}

function Stepper({ value, onChange, disabled }) {
  const set = (v) => !disabled && onChange(Math.max(0, Math.min(15, v)));
  return (
    <div className="col center gap-8 stepper">
      <button className="btn btn-ghost on-hero" disabled={disabled} onClick={() => set((+value || 0) + 1)}
        style={{ width: 44, height: 36, padding: 0, justifyContent: "center", borderRadius: 10 }}>
        <Icon name="chevronDown" size={18} style={{ transform: "rotate(180deg)" }} />
      </button>
      <div className="score-num" style={{ fontSize: 56, fontWeight: 700, width: 72, textAlign: "center",
        color: value === "" || value == null ? "color-mix(in srgb, var(--hero-ink) 45%, transparent)" : "var(--hero-ink)" }}>
        {value === "" || value == null ? "–" : value}
      </div>
      <button className="btn btn-ghost on-hero" disabled={disabled} onClick={() => set((+value || 0) - 1)}
        style={{ width: 44, height: 36, padding: 0, justifyContent: "center", borderRadius: 10 }}>
        <Icon name="chevronDown" size={18} />
      </button>
    </div>
  );
}

function BreakLine({ label, value, on, doubled }) {
  return (
    <div className="row between" style={{ padding: "9px 0", opacity: on ? 1 : .4 }}>
      <span style={{ fontSize: 13.5, color: on ? "var(--ink-2)" : "var(--ink-soft)" }}>{label}</span>
      <span className="mono" style={{ fontWeight: 600, fontSize: 13.5 }}>
        {on ? "+" + value : "—"}{doubled && on ? <span className="badge gold" style={{ marginLeft: 6, padding: "1px 6px" }}>×2</span> : null}
      </span>
    </div>
  );
}

function PredictionDetail({ match, store, back, save, openX2, removeX2 }) {
  const tz = useTimezone();
  const A = window.ACQ;
  const existing = store.predictions[match.id] || {};
  const settled = match.status === "finished";
  // A knockout fixture with placeholder participants (empty iso, e.g. "Winner
  // Match 73") has no real teams yet — not predictable until the bracket resolves.
  const tbd = isTbd(match);
  // Mirror the server's matchLock.isMatchEditable: a pick freezes BOTH when the
  // status leaves "upcoming" AND once the stored kickoff instant has passed. Status
  // alone is unsafe — nothing flips it automatically, so between real kickoff and the
  // next sync/admin status change a match sits in "upcoming" past its start. matchInstant()
  // is the client mirror of the server's kickoffTimestamp (interpreted in the source zone);
  // useNowUntil re-renders at kickoff so the form locks live without a refresh.
  const kickoffMs = matchInstant(match.date, match.time, matchSourceTz());
  const now = useNowUntil(kickoffMs);
  const started = kickoffMs != null && now >= kickoffMs;
  const editable = match.status === "upcoming" && !tbd && !started;
  const hasPick = existing.home != null;
  // Default to a 0–0 scoreline. It is NOT recorded until "Save pick" is pressed.
  const [home, setHome] = useState(hasPick ? existing.home : 0);
  const [away, setAway] = useState(hasPick ? existing.away : 0);
  const x2MatchIds = store.x2MatchIds || [];
  const x2Here = x2MatchIds.includes(match.id);
  const x2Remaining = Math.max(0, 2 - x2MatchIds.length);
  const x2Used = !x2Here && x2Remaining <= 0; // both bonuses spent elsewhere

  const outcome = outcomeOf(home, away);
  const ven = V(match.venue);

  // potential breakdown if this EXACT scoreline happens (outcome points + exact reward)
  const outcomePts = outcome ? match.points[outcome] : 0;
  const exactPts = outcome ? exactBonus(match, outcome) : 0;
  const subtotal = outcomePts + exactPts;
  const total = x2Here ? subtotal * 2 : subtotal;
  // Label reflects the exact-score mode: a ×N multiplier (default) or a flat +bonus.
  const exactLabel = match.exactScoreMode === "add"
    ? "Exact score bonus"
    : `Exact score (×${match.exactScoreMultiplier || 2})`;

  // A 0–0 default with no saved pick still needs saving; a saved pick only once edited.
  const dirty = !hasPick || +home !== existing.home || +away !== existing.away;
  const canSave = home !== "" && away !== "";

  function doSave() {
    save(match.id, { home: +home, away: +away });
    // Stay on the detail page so the "Saved" confirmation shows; the Back button
    // returns to the matches list.
  }

  return (
    <div className="col gap-20" style={{ maxWidth: 760, margin: "0 auto" }}>
      <button className="btn btn-ghost btn-sm" style={{ alignSelf: "flex-start" }} onClick={back}>
        <Icon name="chevron" size={14} style={{ transform: "rotate(180deg)" }} />Back to matches
      </button>

      {/* scoreboard */}
      <div className="card" style={{ overflow: "hidden" }}>
        <div className="row between" style={{ padding: "12px 18px", borderBottom: "1px solid var(--line-2)" }}>
          <div className="row gap-8">
            <span className="badge">{match.stage}{match.group ? " · Group " + match.group : ""}</span>
            <span className="muted" style={{ fontSize: 12.5 }}>{fmtMatchDay(match, tz)} · {fmtMatchTime(match, tz)} · {[ven.stadium, ven.city].filter(Boolean).join(", ")}</span>
          </div>
          <StatusPill status={tbd ? "tbd" : (started && match.status === "upcoming" ? "locked" : match.status)} minute={match.minute} />
        </div>

        <div className="pred-hero" style={{ background: "var(--hero-bg)", color: "var(--hero-ink)", padding: "26px 20px 28px", position: "relative" }}>
          <div className="row between center" style={{ gap: 6 }}>
            <div className="col center gap-10 grow"><TeamBadge code={match.home} size="lg" /><span style={{ fontWeight: 700, fontSize: 16 }}>{T(match.home).name}</span><span className="eyebrow" style={{ color: "color-mix(in srgb,var(--hero-ink) 60%,transparent)" }}>Home</span></div>
            {editable ? (
              <div className="row center" style={{ gap: 8 }}>
                <Stepper value={home} onChange={setHome} />
                <span className="score-num" style={{ fontSize: 40, opacity: .4 }}>:</span>
                <Stepper value={away} onChange={setAway} />
              </div>
            ) : (
              <div className="row center gap-12">
                <span className="score-num" style={{ fontSize: 60, fontWeight: 700 }}>{settled || match.status === "live" ? match.homeScore : "–"}</span>
                <span className="score-num" style={{ fontSize: 40, opacity: .4 }}>:</span>
                <span className="score-num" style={{ fontSize: 60, fontWeight: 700 }}>{settled || match.status === "live" ? match.awayScore : "–"}</span>
              </div>
            )}
            <div className="col center gap-10 grow"><TeamBadge code={match.away} size="lg" /><span style={{ fontWeight: 700, fontSize: 16 }}>{T(match.away).name}</span><span className="eyebrow" style={{ color: "color-mix(in srgb,var(--hero-ink) 60%,transparent)" }}>Away</span></div>
          </div>
          {!editable && existing.home != null && (
            <div className="row center" style={{ marginTop: 18 }}>
              <span className="badge" style={{ background: "color-mix(in srgb,var(--hero-ink) 14%,transparent)", color: "var(--hero-ink)" }}>
                Your prediction · {existing.home}–{existing.away}
              </span>
            </div>
          )}
        </div>

        {/* odds */}
        <div className="card-pad" style={{ padding: "16px 18px" }}>
          <div className="row between" style={{ marginBottom: 10 }}>
            <span className="eyebrow">Outcome points · odds-based</span>
            <span className="muted" style={{ fontSize: 12 }}>Bigger upset → bigger reward</span>
          </div>
          <OddsRow match={match} picked={outcome} size="lg" />
        </div>
      </div>

      {editable ? (
        <>
          {/* X2 */}
          <div className="card card-pad col gap-12" style={{ padding: "16px 18px",
            border: x2Here ? "1.5px solid var(--gold)" : "1px solid var(--line)",
            background: x2Here ? "color-mix(in srgb, var(--brand-yellow) 12%, var(--surface))" : "var(--surface)" }}>
            <div className="row between">
              <div className="row gap-12">
                <div style={{ width: 40, height: 40, borderRadius: 11, display: "flex", alignItems: "center", justifyContent: "center",
                  background: x2Here ? "var(--brand-yellow)" : "var(--chip-bg)", color: x2Here ? "#5a4400" : "var(--ink-2)" }}>
                  <Icon name="bolt" size={20} fill />
                </div>
                <div className="col" style={{ lineHeight: 1.3 }}>
                  <span style={{ fontWeight: 700, fontSize: 15 }}>X2 Bonus {x2Here && <span className="badge gold" style={{ marginLeft: 4 }}>Active here</span>}</span>
                  <span className="muted" style={{ fontSize: 12.5 }}>Two per tournament · doubles every point this match earns.</span>
                </div>
              </div>
              {x2Here
                ? <button className="btn btn-ghost btn-sm" onClick={() => removeX2 && removeX2(match.id)}>Remove</button>
                : x2Used
                  ? <span className="badge" style={{ whiteSpace: "nowrap" }}>Both used</span>
                  : <button className="btn btn-soft btn-sm" onClick={() => openX2(match.id)}>Use X2 here</button>}
            </div>
            {!x2Here && x2MatchIds.length > 0 && (
              <div className="row gap-8 muted" style={{ fontSize: 12.5, borderTop: "1px solid var(--line-2)", paddingTop: 10 }}>
                <Icon name="lock" size={13} />
                {x2Used ? "Both X2 bonuses are on " : "1 of 2 X2 bonuses on "}
                {x2MatchIds.map((id, i) => { const mm = A.MATCHES.find((x) => x.id === id); const lbl = mm ? `${T(mm.home).code}–${T(mm.away).code}` : "another match"; return (i === 0 ? "" : ", ") + lbl; }).join("")}
                {x2Used ? ". Remove one (while its match is open) to move it." : "."}
              </div>
            )}
          </div>

          {/* potential points */}
          <div className="card card-pad col" style={{ padding: "16px 18px" }}>
            <div className="row between" style={{ marginBottom: 4 }}>
              <span className="eyebrow">If this exact result happens</span>
              {x2Here && <span className="badge gold mono"><Icon name="bolt" size={11} fill />X2 doubling</span>}
            </div>
            <BreakLine label={`Correct outcome (${outcome === "home" ? T(match.home).name : outcome === "away" ? T(match.away).name : outcome === "draw" ? "Draw" : "pick a score"})`} value={outcomePts} on={!!outcome} doubled={x2Here} />
            <hr className="hr" style={{ opacity: .5 }} />
            <BreakLine label={exactLabel} value={exactPts} on={!!outcome} doubled={x2Here} />
            <div className="row between" style={{ marginTop: 12, paddingTop: 14, borderTop: "1.5px solid var(--line)" }}>
              <span style={{ fontWeight: 700, fontSize: 15 }}>Maximum potential</span>
              <span className="mono" style={{ fontWeight: 700, fontSize: 26, color: "var(--accent)" }}>{total}<span className="muted" style={{ fontSize: 13, fontWeight: 500 }}> pts</span></span>
            </div>
            <span className="muted" style={{ fontSize: 11.5, marginTop: 6 }}>You still earn the outcome points for the correct winner even if the exact score is off.</span>
          </div>

          <div className="row between wrap gap-12 card card-pad" style={{ padding: "13px 16px", marginTop: 2 }}>
            <span className="muted" style={{ fontSize: 12.5 }}><Icon name="lock" size={12} style={{ verticalAlign: "-2px" }} /> Editable until kickoff · {fmtMatchTime(match, tz)}</span>
            <div className="row gap-10">
              <button className="btn btn-ghost" onClick={back}>Back</button>
              {dirty
                ? <button className={"btn " + (hasPick ? "btn-primary" : "btn-danger")} disabled={!canSave} onClick={doSave}>{hasPick ? "Update pick" : "Save pick"}<Icon name="check" size={15} stroke={2.4} /></button>
                : <span className="badge pos mono" style={{ padding: "9px 14px" }}><Icon name="check" size={14} stroke={2.5} />Saved</span>}
            </div>
          </div>
        </>
      ) : (
        /* read-only settled / locked */
        <ResultPanel match={match} pred={existing} x2Here={x2Here} />
      )}
    </div>
  );
}

function ResultPanel({ match, pred, x2Here }) {
  const settled = match.status === "finished";
  if (!pred || pred.home == null) {
    return <div className="card card-pad col center gap-8" style={{ padding: 34, textAlign: "center" }}>
      <Icon name="lock" size={22} style={{ color: "var(--ink-soft)" }} />
      <span style={{ fontWeight: 700 }}>Prediction locked</span>
      <span className="muted" style={{ fontSize: 13 }}>This match started before you submitted a prediction. No points — but no penalty either.</span>
    </div>;
  }
  const e = pred.earned;
  if (!settled || !e) {
    return <div className="card card-pad col center gap-8" style={{ padding: 30, textAlign: "center" }}>
      <Icon name={match.status === "live" ? "whistle" : "lock"} size={22} style={{ color: "var(--ink-soft)" }} />
      <span style={{ fontWeight: 700 }}>{match.status === "live" ? "Match in play — prediction locked" : "Prediction locked"}</span>
      <span className="muted" style={{ fontSize: 13 }}>Your {pred.home}–{pred.away} is in. Points settle when the match finishes.</span>
    </div>;
  }
  return (
    <div className="card card-pad col" style={{ padding: "16px 18px" }}>
      <span className="eyebrow" style={{ marginBottom: 6 }}>Your result</span>
      <BreakLine label="Correct outcome" value={e.outcome} on={e.outcome > 0} doubled={x2Here} />
      <hr className="hr" style={{ opacity: .5 }} />
      <BreakLine label={match.exactScoreMode === "add" ? "Exact score bonus" : `Exact score (×${match.exactScoreMultiplier || 2})`} value={e.exact} on={!!e.isExact} doubled={x2Here} />
      <div className="row between" style={{ marginTop: 12, paddingTop: 14, borderTop: "1.5px solid var(--line)" }}>
        <span style={{ fontWeight: 700, fontSize: 15 }}>Points earned</span>
        <span className="mono" style={{ fontWeight: 700, fontSize: 26, color: "var(--pos-tx)" }}>+{e.total}</span>
      </div>
    </div>
  );
}

Object.assign(window, { PredictionDetail });
