/* eslint-disable */
/* Solo championship screens */

function PlayModeScreen({ onNavigate }) {
  const user = window.Auth.getUser();
  const [leaders, setLeaders] = useState(window.SoloOps.loadLeaderboard ? window.SoloOps.loadLeaderboard() : []);
  const [busy, setBusy] = useState(false);
  const toast = useToast();

  useEffect(() => {
    window.SoloOps.refreshLeaderboard?.().then(setLeaders).catch(() => {});
  }, []);

  async function startSolo() {
    if (!user) {
      onNavigate("auth");
      return;
    }
    setBusy(true);
    try {
      const attempt = await window.SoloOps.start();
      window.Sound.submit();
      onNavigate(`solo/game/${attempt.id}`);
    } catch (error) {
      toast(error.message);
      window.Sound.error();
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="shell play-mode-shell">
      <Topbar onHome={() => onNavigate("home")} />
      <div className="play-mode-wrap">
        <div className="text-center play-mode-hero">
          <div className="label-up">Выберите формат</div>
          <h1 className="display-2">Как играем?</h1>
        </div>

        <div className="play-mode-grid">
          <button className="card-dark play-mode-card is-solo" onClick={startSolo} disabled={busy}>
            <div className="play-mode-icon"><StarIcon size={32}/></div>
            <div>
              <h2>Одиночная игра</h2>
              <p>Общий чемпионат сайта: одна минута, случайная комбинация, очки и скорость в таблице рекордов.</p>
            </div>
            <strong>{busy ? "Готовим…" : "Начать"}</strong>
          </button>

          <button className="card-dark play-mode-card" onClick={() => onNavigate(user ? "create" : "auth")}>
            <div className="play-mode-icon is-friends">+</div>
            <div>
              <h2>Игра с друзьями</h2>
              <p>Создайте комнату, пригласите друзей или добавьте ботов. Раунд стартует, когда все готовы.</p>
            </div>
            <strong>Создать комнату</strong>
          </button>
        </div>

        {leaders.length > 0 && (
          <div className="card-dark solo-leaders-card">
            <div className="between" style={{ marginBottom: 12 }}>
              <h3 className="h-section">Лидеры одиночной игры</h3>
              <button className="btn btn-ghost btn-sm" onClick={() => onNavigate("stats")}>Все лидеры</button>
            </div>
            <div className="col" style={{ gap: 8 }}>
              {leaders.slice(0, 5).map(leader => (
                <div key={leader.username} className="solo-leader-row">
                  <div className="solo-rank">{leader.rank}</div>
                  <Avatar player={leader} size="sm"/>
                  <div className="grow">
                    <strong>{leader.name}</strong>
                    <span className="text-muted">{leader.games} игр · лучшее {leader.bestWord || "—"}</span>
                  </div>
                  <b>{leader.totalScore}</b>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function SoloGameScreen({ onNavigate, attemptId }) {
  const [attempt, setAttempt] = useState(null);
  const [slots, setSlots] = useState([]);
  const [starPickerIdx, setStarPickerIdx] = useState(null);
  const [secondsLeft, setSecondsLeft] = useState(60);
  const [submitted, setSubmitted] = useState(false);
  const [errorShake, setErrorShake] = useState(false);
  const finishingRef = useRef(false);
  const toast = useToast();

  useEffect(() => {
    let alive = true;
    window.SoloOps.fetchAttempt(attemptId)
      .then(next => {
        if (!alive) return;
        setAttempt(next);
        if (next?.submittedAt) onNavigate(`solo/results/${next.id}`);
      })
      .catch(error => {
        toast(error.message);
        onNavigate("play");
      });
    return () => { alive = false; };
  }, [attemptId]);

  useEffect(() => {
    setSlots([]);
    setSubmitted(false);
    setStarPickerIdx(null);
    finishingRef.current = false;
  }, [attemptId]);

  useEffect(() => {
    if (!attempt || attempt.submittedAt) return;
    function tick() {
      const elapsed = (Date.now() - attempt.startedAt) / 1000;
      const remaining = Math.max(0, Math.ceil(attempt.roundTime - elapsed));
      setSecondsLeft(remaining);
      if (remaining === 0 && !finishingRef.current) {
        finishingRef.current = true;
        submit(true);
      }
    }
    tick();
    const interval = setInterval(tick, 250);
    return () => clearInterval(interval);
  }, [attempt?.id, attempt?.startedAt]);

  if (!attempt) {
    return (
      <div className="shell game-shell">
        <Topbar onHome={() => onNavigate("home")} />
        <div className="card-dark text-center" style={{ maxWidth: 520, margin: "40px auto" }}>Готовим комбинацию…</div>
      </div>
    );
  }

  const letters = attempt.letters || [];
  const usedIdx = slots.map(s => s.idx);
  const currentWord = slots.map(s => s.asLetter || letters[s.idx]).join("");
  const starCount = slots.filter(s => letters[s.idx] === "★").length;
  const wordValid = slots.length >= 2 && slots.every(s => letters[s.idx] !== "★" || s.asLetter);
  const effectiveSubmitted = submitted || Boolean(attempt.submittedAt);

  function pickLetter(i) {
    if (effectiveSubmitted) return;
    if (usedIdx.includes(i)) return;
    if (letters[i] === "★") {
      setStarPickerIdx(i);
      return;
    }
    setSlots([...slots, { idx: i }]);
    window.Sound.pick();
  }

  function chooseStarLetter(letter) {
    if (starPickerIdx == null) return;
    setSlots([...slots, { idx: starPickerIdx, asLetter: letter }]);
    setStarPickerIdx(null);
    window.Sound.pick();
  }

  function popLetter() {
    if (effectiveSubmitted || !slots.length) return;
    setSlots(slots.slice(0, -1));
    window.Sound.unpick();
  }

  function clearWord() {
    if (effectiveSubmitted) return;
    setSlots([]);
    window.Sound.unpick();
  }

  function popAt(pos) {
    if (effectiveSubmitted) return;
    setSlots(slots.slice(0, pos));
    window.Sound.unpick();
  }

  async function submit(missed = false) {
    if (effectiveSubmitted && !missed) return;
    if (!missed && !wordValid) {
      setErrorShake(true);
      setTimeout(() => setErrorShake(false), 400);
      window.Sound.error();
      toast("Слово должно быть не короче 2 букв");
      return;
    }
    try {
      const result = await window.SoloOps.submitWord(attempt.id, {
        word: missed ? "" : currentWord.toUpperCase(),
        slots: missed ? [] : [...slots],
        starCount: missed ? 0 : starCount,
        missed,
      });
      setSubmitted(true);
      window.Sound.submit();
      onNavigate(`solo/results/${result.id}`);
    } catch (error) {
      finishingRef.current = false;
      toast(error.message);
      window.Sound.error();
    }
  }

  return (
    <div className="shell game-shell solo-game-shell" style={{ paddingBottom: 16 }}>
      <div className="between game-topbar" style={{ marginBottom: 20 }}>
        <Brand onClick={() => onNavigate("home")}/>
        <div className="row game-status-row" style={{ gap: 12 }}>
          <div className="game-status-left">
            <HeaderProfileBadge />
            <HeaderMenuButton />
          </div>
          <div className="game-status-right">
            <div className="card-dark game-mini-card solo-mini-mode">Одиночная</div>
            <TimerRing secondsLeft={secondsLeft} total={attempt.roundTime}/>
          </div>
        </div>
      </div>

      <div className={"card-dark game-word-card " + (errorShake ? "shake" : "")} style={{
        marginBottom: 24,
        padding: "20px 24px",
        minHeight: 110,
        display: "flex",
        flexDirection: "column",
        gap: 10,
      }}>
        <div className="between game-word-head">
          <div className="label-up">Ваше слово</div>
          <div className="text-muted game-word-score" style={{ fontSize: 13 }}>
            {slots.length} букв
            {starCount > 0 && <span> · ★ −{starCount}</span>}
            {" · "}<strong style={{ color: "var(--gold)" }}>{Math.max(0, slots.length - starCount)} очков</strong>
          </div>
        </div>
        <div className="row wrap" style={{ gap: 8, minHeight: 56, alignItems: "center" }}>
          {slots.length === 0 && (
            <div className="text-muted" style={{ fontStyle: "italic", fontSize: 15 }}>
              нажимайте на буквы внизу, чтобы составить слово…
            </div>
          )}
          {slots.map((s, pos) => {
            const isStar = letters[s.idx] === "★";
            return (
              <button key={pos} className="pop-in" onClick={() => popAt(pos)} disabled={effectiveSubmitted} style={{
                width: 48, height: 48, borderRadius: 12, border: "none",
                cursor: effectiveSubmitted ? "default" : "pointer",
                background: isStar ? "var(--tile-star-bg)" : "linear-gradient(135deg, var(--gold), var(--gold-deep))",
                color: "var(--ink-1)",
                fontFamily: "var(--font-display)", fontWeight: 800, fontSize: 24,
                display: "flex", alignItems: "center", justifyContent: "center",
                boxShadow: "0 4px 0 var(--gold-deep)",
                position: "relative",
              }}>
                {s.asLetter || (isStar ? <StarIcon size={22}/> : letters[s.idx])}
                {isStar && s.asLetter && (
                  <span style={{
                    position: "absolute", top: -6, right: -6,
                    width: 18, height: 18, borderRadius: "50%",
                    background: "white", color: "var(--gold-deep)",
                    display: "flex", alignItems: "center", justifyContent: "center",
                    fontSize: 10,
                  }}><StarIcon size={10}/></span>
                )}
              </button>
            );
          })}
        </div>
      </div>

      <div className="card-dark game-letter-card" style={{ padding: 24, marginBottom: 20 }}>
        <div className="between" style={{ marginBottom: 16 }}>
          <div className="label-up">Доступные буквы</div>
        </div>
        <div className="row wrap letter-pool letter-pool-grid" style={{ gap: 12, justifyContent: "center" }}>
          {letters.map((l, i) => {
            if (l === "★") {
              return (
                <React.Fragment key={i}>
                  <button type="button" className="game-letter-action" onClick={popLetter} disabled={slots.length === 0} aria-label="Стереть последнюю букву">←</button>
                  <div className="letter-pool-star">
                    <LetterTile letter={l} used={usedIdx.includes(i)} onClick={() => pickLetter(i)} animateDrop dropDelay={i * 80}/>
                  </div>
                  <button type="button" className="game-letter-action" onClick={clearWord} disabled={slots.length === 0} aria-label="Очистить слово">×</button>
                </React.Fragment>
              );
            }
            return <LetterTile key={i} letter={l} used={usedIdx.includes(i)} onClick={() => pickLetter(i)} animateDrop dropDelay={i * 80}/>;
          })}
        </div>
      </div>

      <div className="row wrap game-controls game-submit-row solo-submit-row" style={{ gap: 10, justifyContent: "center", marginBottom: 18 }}>
        <button className="btn btn-primary btn-lg" onClick={() => submit(false)} disabled={!wordValid || effectiveSubmitted}>
          Отправить
        </button>
      </div>

      <Modal open={starPickerIdx !== null} onClose={() => setStarPickerIdx(null)} title="Какую букву заменит звезда?" width={560}>
        <p className="text-muted" style={{ fontSize: 13, marginBottom: 16 }}>
          ⭐ Звезда заменит выбранную букву в слове. <strong style={{ color: "var(--coral)" }}>−1 очко</strong> за каждую звезду.
        </p>
        <div className="solo-star-grid">
          {"АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ".split("").map(letter => (
            <button key={letter} onClick={() => chooseStarLetter(letter)}>{letter}</button>
          ))}
        </div>
        <div className="row" style={{ justifyContent: "flex-end", marginTop: 16 }}>
          <button className="btn btn-ghost btn-sm" onClick={() => setStarPickerIdx(null)}>Отмена</button>
        </div>
      </Modal>
    </div>
  );
}

function renderSoloWordWithStars(word, letters, slots = null) {
  if (!word) return "—";
  const chars = String(word).split("");
  let starMarks = [];
  if (Array.isArray(slots) && slots.length) {
    starMarks = slots.map(slot => letters?.[slot.idx] === "★");
  } else {
    starMarks = window.GameLogic.markStarPositions(word, letters || []);
  }
  return chars.map((ch, i) => {
    const isStar = Boolean(starMarks[i]);
    return (
      <span key={`${ch}-${i}`} className={isStar ? "result-letter-star" : ""}>
        {ch}
        {isStar && <StarIcon size={10}/>}
      </span>
    );
  });
}

function SoloResultsScreen({ onNavigate, attemptId }) {
  const [attempt, setAttempt] = useState(null);
  const [busy, setBusy] = useState(false);
  const toast = useToast();

  useEffect(() => {
    let alive = true;
    window.SoloOps.fetchAttempt(attemptId)
      .then(next => { if (alive) setAttempt(next); })
      .catch(error => {
        toast(error.message);
        onNavigate("play");
      });
    return () => { alive = false; };
  }, [attemptId]);

  useEffect(() => {
    const isPending = attempt && (attempt.accepted === null || attempt.verifiedReason === "pending" || attempt.verifiedReason === "fetch-failed");
    if (!isPending) return;
    let alive = true;
    const timer = setInterval(() => {
      window.SoloOps.fetchAttempt(attemptId)
        .then(next => { if (alive) setAttempt(next); })
        .catch(() => {});
    }, 3500);
    return () => {
      alive = false;
      clearInterval(timer);
    };
  }, [attemptId, attempt?.accepted, attempt?.verifiedReason]);

  async function playNext() {
    setBusy(true);
    try {
      const next = await window.SoloOps.start();
      window.Sound.pick();
      onNavigate(`solo/game/${next.id}`);
    } catch (error) {
      toast(error.message);
      window.Sound.error();
    } finally {
      setBusy(false);
    }
  }

  if (!attempt) {
    return (
      <div className="shell">
        <Topbar onHome={() => onNavigate("home")} />
        <div className="card-dark text-center" style={{ maxWidth: 520, margin: "40px auto" }}>Загружаем результат…</div>
      </div>
    );
  }

  const board = attempt.leaderboard || { top: [], mine: null, totalAttempts: 0 };
  const reasonText = {
    timeout: "время вышло",
    "too-short": "слишком короткое слово",
    letters: "слово не из букв",
    dictionary: "слово не найдено в словаре",
    "proper-noun": "имя собственное не принимается",
    "inflected-form": "нужна начальная форма единственного числа",
    "not-noun": "принимаем только существительные",
    "no-page": "слово не найдено в Викисловаре",
    "no-russian": "нет русской словарной статьи",
    pending: "проверяем слово в Викисловаре…",
    "fetch-failed": "проверяем слово в Викисловаре…",
  }[attempt.verifiedReason] || "";
  const wiktHref = attempt.word
    ? `https://ru.wiktionary.org/wiki/${encodeURIComponent(attempt.word.toLowerCase())}`
    : "";
  const isPending = attempt.accepted === null || attempt.verifiedReason === "pending" || attempt.verifiedReason === "fetch-failed";

  return (
    <div className="shell solo-results-shell">
      <Topbar onHome={() => onNavigate("home")} />
      <div className="solo-results-hero">
        <div className="label-up">Одиночная игра</div>
        <h1 className="display-2">Результат комбинации</h1>
        <div className="row results-letters" style={{ justifyContent: "center", gap: 6, marginTop: 14 }}>
          {attempt.letters.map((l, i) => (
            <span key={i} style={{
              display: "inline-flex", alignItems: "center", justifyContent: "center",
              width: 38, height: 38, borderRadius: 8,
              background: l === "★" ? "var(--tile-star-bg)" : "white",
              color: "var(--ink-1)",
              fontFamily: "var(--font-display)", fontWeight: 800, fontSize: 20,
            }}>{l === "★" ? <StarIcon size={18}/> : l}</span>
          ))}
        </div>
      </div>

      <div className="card-dark solo-result-card">
        <div className="between solo-result-head">
          <div>
            <div className="label-up">Ваше слово</div>
            <div className="solo-result-word" style={{ color: attempt.accepted ? "var(--gold)" : isPending ? "var(--cyan)" : "var(--ink-on-dark-3)" }}>
              {renderSoloWordWithStars(attempt.word, attempt.letters, attempt.slots)}
            </div>
            {!attempt.accepted && reasonText && <div className="text-muted" style={{ marginTop: 4 }}>{reasonText}</div>}
          </div>
          <div className="solo-result-score">
            {isPending ? "…" : `+${attempt.total}`}
            <span>{attempt.durationMs != null ? formatDuration(attempt.durationMs) : "—"}</span>
          </div>
        </div>
        <div className="solo-rank-note">
          {isPending ? "Результат обновится автоматически после проверки." : (board.mine ? `Ваше место по этой комбинации: ${board.mine.rank} из ${board.totalAttempts}` : "Результат сохранён")}
          {!isPending && attempt.global?.rank && <span> · общий зачёт: место {attempt.global.rank}, {attempt.global.totalScore} очков</span>}
        </div>
        {wiktHref && (
          <div className="solo-wikt-check">
            <a
              className={"result-check-link " + (attempt.accepted ? "is-ok" : isPending ? "is-pending" : "is-bad")}
              href={wiktHref}
              target="_blank"
              rel="noopener"
            >
              📖 Викисловарь
            </a>
          </div>
        )}
      </div>

      <div className="card-dark solo-combo-board">
        <div className="between" style={{ marginBottom: 12 }}>
          <h3 className="h-section">Топ-5 по этой комбинации</h3>
          <span className="text-muted">{board.totalAttempts} попыток</span>
        </div>
        <div className="col" style={{ gap: 8 }}>
          {board.top.length === 0 ? (
            <div className="text-muted text-center" style={{ padding: 16 }}>Вы первый прошли эту комбинацию.</div>
          ) : board.top.map(row => (
            <div key={row.id} className={"solo-leader-row " + (row.userId === attempt.player.userId ? "is-me" : "")}>
              <div className="solo-rank">{row.rank}</div>
              <Avatar player={row} size="sm"/>
              <div className="grow">
                <strong>{row.name}</strong>
                <span className="text-muted">
                  {row.word ? (
                    <a
                      className="solo-word-link"
                      href={`https://ru.wiktionary.org/wiki/${encodeURIComponent(row.word.toLowerCase())}`}
                      target="_blank"
                      rel="noopener"
                    >
                      {renderSoloWordWithStars(row.word, attempt.letters)}
                    </a>
                  ) : "—"}
                  {" · "}{row.durationMs != null ? formatDuration(row.durationMs) : "—"}
                </span>
              </div>
              <b>{row.total}</b>
            </div>
          ))}
        </div>
      </div>

      {board.mine && board.mine.rank > 5 && (
        <div className="card-dark solo-my-rank">
          <div className="solo-leader-row is-me">
            <div className="solo-rank">{board.mine.rank}</div>
            <Avatar player={board.mine} size="sm"/>
            <div className="grow">
              <strong>{board.mine.name}</strong>
              <span className="text-muted">
                {board.mine.word ? (
                  <a
                    className="solo-word-link"
                    href={`https://ru.wiktionary.org/wiki/${encodeURIComponent(board.mine.word.toLowerCase())}`}
                    target="_blank"
                    rel="noopener"
                  >
                    {renderSoloWordWithStars(board.mine.word, attempt.letters)}
                  </a>
                ) : "—"}
                {" · "}{board.mine.durationMs != null ? formatDuration(board.mine.durationMs) : "—"}
              </span>
            </div>
            <b>{board.mine.total}</b>
          </div>
        </div>
      )}

      <div className="solo-results-actions">
        <button className="btn btn-primary btn-lg" onClick={playNext} disabled={busy}>
          {busy ? "Готовим…" : <>Играть дальше <StarIcon size={18}/></>}
        </button>
        <button className="btn btn-ghost" onClick={() => onNavigate("home")}>На главную</button>
      </div>
    </div>
  );
}

Object.assign(window, { PlayModeScreen, SoloGameScreen, SoloResultsScreen });
