import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import { Link } from "react-router-dom";
import { timeOnly, dateKey } from "@/lib/format";
import { type Lang, dict, teamShort, roundLabel as tRound, dayName, monthEn } from "@/lib/i18n";
import type { Match, MatchPhase } from "@/lib/types";
import TeamFlag from "./TeamFlag";

// 칩용 짧은 날짜: "6.12 (금)" / "Jun 12 (Fri)"
function shortDate(iso: string, lang: Lang): string {
  const m = iso.match(/(\d{4})-(\d{2})-(\d{2})/);
  if (!m) return iso;
  const [, y, mo, d] = m;
  const dow = dayName(lang, new Date(Date.UTC(+y, +mo - 1, +d)).getUTCDay());
  return lang === "en" ? `${monthEn(+mo)} ${+d} (${dow})` : `${+mo}.${+d} (${dow})`;
}

const PHASE_CLS: Record<MatchPhase, string> = {
  open: "border-[#94FBE0] text-[#94FBE0]",
  scheduled: "border-[var(--line-d)] text-[var(--ink-muted)]",
  locked: "border-[var(--line-d)] text-white/45",
  live: "border-[#FF5B5B] text-[#FF5B5B]",
  finished: "border-white/15 text-white/55",
};

type Tab = "date" | "group";

export default function ScheduleBoard({
  matches,
  lang = "ko",
}: {
  matches: Match[];
  lang?: Lang;
}) {
  const t = dict(lang);
  const [tab, setTab] = useState<Tab>("date");

  // 날짜·조 목록 (정렬)
  const dates = useMemo(
    () => Array.from(new Set(matches.map((m) => dateKey(m.kickoffKst)))).sort(),
    [matches],
  );
  const groups = useMemo(
    () => Array.from(new Set(matches.map((m) => m.group))).sort(),
    [matches],
  );

  // 기본 선택: 오늘(없으면 첫 날짜) / A조
  const todayKey = useMemo(() => new Date().toISOString().slice(0, 10), []);
  const [selDate, setSelDate] = useState(
    () => (dates.includes(todayKey) ? todayKey : dates[0]) ?? "",
  );
  const [selGroup, setSelGroup] = useState(
    () => (groups.includes("A") ? "A" : groups[0]) ?? "",
  );

  const shown = useMemo(() => {
    const list =
      tab === "date"
        ? matches.filter((m) => dateKey(m.kickoffKst) === selDate)
        : matches.filter((m) => m.group === selGroup);
    return [...list].sort(
      (a, b) => new Date(a.kickoffKst).getTime() - new Date(b.kickoffKst).getTime(),
    );
  }, [matches, tab, selDate, selGroup]);

  const tabLabel = (k: Tab) =>
    k === "date" ? (lang === "en" ? "By date" : "날짜별") : lang === "en" ? "Groups" : "조별리그";

  return (
    <section className="mt-6">
      <div className="mb-3 flex items-baseline gap-2.5">
        <h2 className="shrink-0 text-[22px] font-extrabold">{t.schedTitle}</h2>
        <span className="whitespace-nowrap text-[12px] text-white/55">{t.schedGuide}</span>
      </div>

      {/* 탭: 날짜별 / 조별리그 */}
      <div className="mb-3 flex gap-5 border-b border-[var(--line-d)]">
        {(["date", "group"] as Tab[]).map((k) => (
          <button
            key={k}
            onClick={() => setTab(k)}
            className={`-mb-px border-b-2 pb-2 text-[15px] font-bold transition ${
              tab === k
                ? "border-[var(--green)] text-white"
                : "border-transparent text-white/45"
            }`}
          >
            {tabLabel(k)}
          </button>
        ))}
      </div>

      {/* 칩: 날짜 또는 조 — 단일 줄 가로 스크롤 + 양 끝 화살표(PC에서 마우스로 넘김, 끝 도달 시 숨김) */}
      <ChipScroller resetKey={tab}>
        {tab === "date"
          ? dates.map((d) => (
              <Chip key={d} active={d === selDate} onClick={() => setSelDate(d)}>
                {shortDate(d, lang)}
              </Chip>
            ))
          : groups.map((g) => (
              <Chip key={g} active={g === selGroup} onClick={() => setSelGroup(g)}>
                {lang === "en" ? `Group ${g}` : `${g}조`}
              </Chip>
            ))}
      </ChipScroller>

      {/* 경기 카드 */}
      <div className="flex flex-col gap-2.5">
        {shown.length === 0 && (
          <p className="py-6 text-center text-[13px] text-white/45">
            {lang === "en" ? "No matches" : "경기가 없습니다"}
          </p>
        )}
        {shown.map((m) => (
          <MatchCard key={m.matchId} match={m} lang={lang} />
        ))}
      </div>
    </section>
  );
}

// 단일 줄 가로 스크롤 + 양 끝 화살표. 끝에 닿으면 해당 방향 화살표를 숨긴다.
// resetKey 가 바뀌면(탭 전환 등) 맨 앞으로 되감고 재측정한다.
function ChipScroller({
  children,
  resetKey,
}: {
  children: React.ReactNode;
  resetKey?: string | number;
}) {
  const ref = useRef<HTMLDivElement>(null);
  const [atStart, setAtStart] = useState(true);
  const [atEnd, setAtEnd] = useState(true);

  const measure = () => {
    const el = ref.current;
    if (!el) return;
    const max = el.scrollWidth - el.clientWidth;
    setAtStart(el.scrollLeft <= 1);
    setAtEnd(el.scrollLeft >= max - 1);
  };

  // 탭/목록 변경 시 맨 앞으로 + 재측정 (레이아웃 확정 후)
  useLayoutEffect(() => {
    const el = ref.current;
    if (el) el.scrollLeft = 0;
    measure();
  }, [resetKey]);

  useEffect(() => {
    measure();
    const el = ref.current;
    if (!el) return;
    el.addEventListener("scroll", measure, { passive: true });
    window.addEventListener("resize", measure);
    return () => {
      el.removeEventListener("scroll", measure);
      window.removeEventListener("resize", measure);
    };
  }, []);

  const nudge = (dir: 1 | -1) =>
    ref.current?.scrollBy({ left: dir * 220, behavior: "smooth" });

  return (
    <div className="relative mb-4">
      <div
        ref={ref}
        className="flex gap-2 overflow-x-auto pb-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
      >
        {children}
      </div>

      {!atStart && (
        <div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pr-8 bg-gradient-to-r from-[var(--bg)] via-[var(--bg)] to-transparent">
          <button
            type="button"
            aria-label="이전"
            onClick={() => nudge(-1)}
            className="pointer-events-auto grid h-7 w-7 place-items-center rounded-full border border-[var(--line-d)] bg-[var(--bg2)] text-[15px] leading-none text-white/80 shadow transition hover:text-white active:scale-95"
          >
            ‹
          </button>
        </div>
      )}
      {!atEnd && (
        <div className="pointer-events-none absolute inset-y-0 right-0 flex items-center justify-end pl-8 bg-gradient-to-l from-[var(--bg)] via-[var(--bg)] to-transparent">
          <button
            type="button"
            aria-label="다음"
            onClick={() => nudge(1)}
            className="pointer-events-auto grid h-7 w-7 place-items-center rounded-full border border-[var(--line-d)] bg-[var(--bg2)] text-[15px] leading-none text-white/80 shadow transition hover:text-white active:scale-95"
          >
            ›
          </button>
        </div>
      )}
    </div>
  );
}

function Chip({
  active,
  onClick,
  children,
}: {
  active: boolean;
  onClick: () => void;
  children: React.ReactNode;
}) {
  return (
    <button
      onClick={onClick}
      className={`shrink-0 whitespace-nowrap rounded-full border px-3.5 py-1.5 text-[13px] font-bold transition ${
        active
          ? "border-[#94FBE0] text-[#94FBE0]"
          : "border-[var(--line-d)] text-white/55"
      }`}
    >
      {children}
    </button>
  );
}

function MatchCard({ match, lang }: { match: Match; lang: Lang }) {
  const t = dict(lang);
  const phase = match.phase;
  const finished = !!match.result;

  // 비투표(타 조)는 클릭 비활성, 투표 가능 조(A)는 상세로 이동
  const inner = (
    <>
      <div className="flex items-center justify-between text-[11px]">
        <span className="font-mono font-bold text-white/70">
          {timeOnly(match.kickoffKst)} <span className="text-white/40">KST</span>
          {match.roundLabel ? <> · {tRound(match.roundLabel, lang)}</> : null}
        </span>
        <span className="flex items-center gap-1.5">
          <span className="text-[11px] font-bold text-white/45">
            {lang === "en" ? `Group ${match.group}` : `${match.group}조`}
          </span>
          <span className={`rounded-md border px-2 py-0.5 font-semibold ${PHASE_CLS[phase]}`}>
            {t.phase[phase]}
          </span>
        </span>
      </div>

      <div className="mt-3 grid grid-cols-[1fr_auto_1fr] items-center gap-2">
        <div className="flex items-center gap-2">
          <TeamFlag team={match.teamA} className="h-6 w-9 shrink-0" />
          <span className="truncate text-[15px] font-extrabold">{teamShort(match.teamA, lang)}</span>
        </div>
        {match.result ? (
          <span className="whitespace-nowrap font-mono text-[18px] font-extrabold tabular-nums text-white">
            {match.result.scoreA}
            <span className="px-1.5 text-white/40">:</span>
            {match.result.scoreB}
          </span>
        ) : (
          <span className="font-impact text-[18px] italic text-[#94FBE0]">VS</span>
        )}
        <div className="flex items-center justify-end gap-2">
          <span className="truncate text-right text-[15px] font-extrabold">{teamShort(match.teamB, lang)}</span>
          <TeamFlag team={match.teamB} className="h-6 w-9 shrink-0" />
        </div>
      </div>

      {/* 투표 가능 조만: AI 픽 갈림 + 참여수 + 이동 화살표 */}
      {match.votable && (
        <div className="mt-3 flex items-center justify-between text-[11px] font-bold text-[#F4F3FE]">
          <span>
            <span className="font-semibold text-white/55">{t.aiPicks}</span>{" "}
            {aiSplit(match, lang).join(" · ")}
          </span>
          <span className="flex items-center gap-2">
            <span>{t.joined((match.crowd?.total ?? 0).toLocaleString())}</span>
            <span className="text-[#94FBE0]">→</span>
          </span>
        </div>
      )}
    </>
  );

  const base = "block rounded-2xl border-2 bg-[#171b21] p-4";
  if (match.votable && !finished) {
    return (
      <Link
        to={`/match/${match.matchId}${lang === "en" ? "?lang=en" : ""}`}
        className={`${base} border-[#94FBE0]/45 transition active:scale-[0.99] hover:border-[#94FBE0]`}
      >
        {inner}
      </Link>
    );
  }
  // 종료된 투표 경기는 결과 보기로, 비투표 경기는 표시 전용(클릭 시 상세=결과)
  if (match.votable) {
    return (
      <Link to={`/match/${match.matchId}${lang === "en" ? "?lang=en" : ""}`} className={`${base} border-white/12`}>
        {inner}
      </Link>
    );
  }
  return <div className={`${base} border-[var(--line-d)]`}>{inner}</div>;
}

function aiSplit(match: Match, lang: Lang): string[] {
  const t = dict(lang);
  const tally = { a: 0, d: 0, b: 0 };
  for (const p of match.predictions) {
    if (p.outcome === "TEAM_A_WIN") tally.a++;
    else if (p.outcome === "DRAW") tally.d++;
    else tally.b++;
  }
  const out: string[] = [];
  if (tally.a) out.push(`${teamShort(match.teamA, lang)} ${tally.a}`);
  if (tally.d) out.push(`${t.draw} ${tally.d}`);
  if (tally.b) out.push(`${teamShort(match.teamB, lang)} ${tally.b}`);
  return out.length ? out : ["-"];
}
