// components/live-carousel.jsx
// Ported from src/pages/LoginPage.tsx in illsbills24/fanish-app.
//
// JS-driven marquee carousel of upcoming featured matches with pause-and-spotlight
// on the most-imminent card. Live-ticking countdown (re-evaluates every 1s; <1h
// matches show 0:mm:ss, <24h show 14h 27m, <7d show 5d 14h, then "In N weeks").
//
// Sized for the marketing hero's 252px phone-frame interior (inner width ~234px
// after frame padding). Card width 140px to give ~1.5 cards visible — preserves
// the in-app marquee aesthetic at a smaller scale.
//
// Respects prefers-reduced-motion: the marquee animation is skipped entirely,
// and the imminent card retains its static accent treatment.

function urgencyDisplay(matchDateISO, now) {
  const diff = new Date(matchDateISO).getTime() - now;
  if (diff <= 0) return { text: "LIVE NOW", hot: true, live: true };
  const totalSec = Math.floor(diff / 1000);
  const hours = Math.floor(totalSec / 3600);
  const days = Math.floor(hours / 24);
  if (hours < 1) {
    const m = Math.floor(totalSec / 60) % 60;
    const s = totalSec % 60;
    return {
      text: `0:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`,
      hot: true, live: false,
    };
  }
  if (days < 1) {
    const m = Math.floor(totalSec / 60) % 60;
    return { text: `${hours}h ${String(m).padStart(2, "0")}m`, hot: true, live: false };
  }
  if (days < 7) return { text: `${days}d ${hours % 24}h`, hot: true, live: false };
  if (days <= 14) return { text: "In 2 weeks", hot: false, live: false };
  if (days <= 30) return { text: `In ${Math.ceil(days / 7)} weeks`, hot: false, live: false };
  return { text: `In ${days} days`, hot: false, live: false };
}

function formatShortDate(iso) {
  return new Date(iso).toLocaleDateString("en-US", { month: "short", day: "numeric" });
}

// Card-geometry defaults — props override per-instance. Hero phone-mock uses
// 140px cards; press/investors use 175px to fill the wider page container.
const CARD_W_DEFAULT = 140;
const GAP_DEFAULT = 8;
const TRACK_PADDING_X = 10;

function LiveCarousel({ matches, cardWidth = CARD_W_DEFAULT, gap = GAP_DEFAULT, size = "sm", showReadyBadge = false }) {
  const [now, setNow] = React.useState(() => Date.now());
  const [centeredIdx, setCenteredIdx] = React.useState(null);
  const trackRef = React.useRef(null);
  const containerRef = React.useRef(null);

  // 1s ticker drives the urgency display. Used for sub-1h matches that show ticking
  // seconds; longer ranges only refresh visibly once per minute / hour / day.
  React.useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id);
  }, []);

  // rAF marquee. Pauses ~1500ms each time the most-imminent card crosses the
  // container's horizontal center; during the pause the card scales 1.04× +
  // gains a shadow. Two copies of the match list rendered for seamless loop.
  React.useEffect(() => {
    if (!matches || matches.length === 0) return;
    const track = trackRef.current;
    const container = containerRef.current;
    if (!track || !container) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
      return;
    }

    const SLOT = cardWidth + gap;
    const FIRST_CARD_CENTER_OFFSET = TRACK_PADDING_X + cardWidth / 2;
    const copyWidth = SLOT * matches.length;
    const SPEED_PX_PER_MS = SLOT / 5000; // 5s per card slot — feel-match with app
    const PAUSE_MS = 1500;
    const PAUSE_TRIGGER_TOLERANCE = 6;

    let raf = 0;
    let lastTs = 0;
    let posPx = 0;
    let pauseUntil = 0;
    let pausedThisCycle = false;
    let activeCentered = null;

    function tick(ts) {
      if (!lastTs) lastTs = ts;
      const dt = ts - lastTs;
      lastTs = ts;

      if (ts < pauseUntil) {
        raf = requestAnimationFrame(tick);
        return;
      }
      if (activeCentered !== null && pauseUntil !== 0 && ts >= pauseUntil) {
        activeCentered = null;
        setCenteredIdx(null);
        pauseUntil = 0;
      }

      posPx -= SPEED_PX_PER_MS * dt;
      if (-posPx >= copyWidth) {
        posPx += copyWidth;
        pausedThisCycle = false;
      }

      // Container-centered (not viewport-centered) — the carousel lives inside the
      // phone-frame which is narrower than the viewport. Center is measured against
      // the container's own width.
      const cw = container.clientWidth;
      const targetCenter = cw / 2;
      const imminentInstances = [0, matches.length];
      for (const N of imminentInstances) {
        const centerAt = posPx + FIRST_CARD_CENTER_OFFSET + N * SLOT;
        if (Math.abs(centerAt - targetCenter) < PAUSE_TRIGGER_TOLERANCE && !pausedThisCycle) {
          pausedThisCycle = true;
          pauseUntil = ts + PAUSE_MS;
          activeCentered = N;
          setCenteredIdx(N);
          break;
        }
      }

      track.style.transform = `translateX(${posPx}px)`;
      raf = requestAnimationFrame(tick);
    }

    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [matches, cardWidth, gap]);

  if (!matches || matches.length === 0) return null;

  return (
    <div className={"live-carousel live-carousel--" + size} ref={containerRef} aria-label="Upcoming matches preview">
      <div className="live-carousel-track" ref={trackRef} style={{ gap: gap + "px" }}>
        {[...matches, ...matches].map((m, idx) => {
          const sportLabel = m.sport === "f1" ? "F1" : "WC";
          const isImminent = idx === 0 || idx === matches.length;
          const isCentered = centeredIdx === idx;
          const { text, hot, live } = urgencyDisplay(m.matchDate, now);
          const cardClass =
            "live-card" +
            (isImminent ? " imminent" : "") +
            (isCentered ? " centered" : "");
          return (
            <div key={`${m.id}-${idx}`} className={cardClass} style={{ width: cardWidth + "px" }}>
              <div className="live-card-badge-row">
                <span className={"live-card-badge live-card-badge-" + (m.sport || "wc")}>
                  {sportLabel}
                </span>
                {showReadyBadge ? (
                  <span className="live-card-ready" aria-label="Content ready for this event">
                    <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                         strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                      <polyline points="20 6 9 17 4 12" />
                    </svg>
                    <span>Ready</span>
                  </span>
                ) : null}
              </div>
              <p className="live-card-name">{m.displayName}</p>
              <p className="live-card-tagline">{m.tagline}</p>
              <div className="live-card-divider" />
              <div className="live-card-foot">
                <span className={"live-card-urgency" + (hot ? " hot" : "")}>
                  {hot ? <span className={"live-card-dot" + (live ? " pulse" : "")} aria-hidden="true" /> : null}
                  <span className="live-card-urgency-text">{text}</span>
                </span>
                <span className="live-card-date">{formatShortDate(m.matchDate)}</span>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

window.LiveCarousel = LiveCarousel;
