"use client";

import { useEffect, useState } from "react";
import { sanitizeAlias } from "../lib/game";

const API_URL = "/kernel-panic/api/scores";

function safeScores(value) {
  if (!Array.isArray(value)) return [];
  return value
    .filter(
      (entry) =>
        entry &&
        typeof entry.alias === "string" &&
        Number.isFinite(entry.score) &&
        ["Kurslauf", "Lernmodus"].includes(entry.mode)
    )
    .slice(0, 20);
}

export default function Scoreboard({
  score,
  runId,
  runQuestionIds,
  mode,
  startedAt,
  outcomes
}) {
  const [alias, setAlias] = useState("");
  const [scores, setScores] = useState([]);
  const [status, setStatus] = useState("loading");
  const [message, setMessage] = useState("");
  const [submitted, setSubmitted] = useState(false);

  useEffect(() => {
    let active = true;
    fetch(API_URL, { headers: { Accept: "application/json" } })
      .then((response) => {
        if (!response.ok) throw new Error("scoreboard unavailable");
        return response.json();
      })
      .then((payload) => {
        if (!active) return;
        setScores(safeScores(payload.scores));
        setStatus("ready");
      })
      .catch(() => {
        if (!active) return;
        setStatus("offline");
      });
    return () => {
      active = false;
    };
  }, []);

  async function submitScore(event) {
    event.preventDefault();
    const cleanAlias = sanitizeAlias(alias);
    if (cleanAlias.length < 2) {
      setMessage("Bitte einen Alias mit mindestens zwei Zeichen wählen.");
      return;
    }

    setStatus("saving");
    setMessage("");
    const elapsed = Math.floor(
      (Date.now() - Date.parse(startedAt ?? new Date().toISOString())) / 1000
    );

    try {
      const response = await fetch(API_URL, {
        method: "POST",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          alias: cleanAlias,
          runId,
          mode,
          runQuestionIds,
          outcomes,
          durationSeconds: Math.max(30, elapsed)
        })
      });
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload.message || "Eintrag wurde abgelehnt.");
      }
      setScores(safeScores(payload.scores));
      setAlias(cleanAlias);
      setSubmitted(true);
      setStatus("ready");
      setMessage(
        payload.duplicate
          ? "Dieser Lauf war bereits eingetragen."
          : "Score gespeichert – willkommen im Maschinenraum."
      );
    } catch (error) {
      setStatus("offline");
      setMessage(
        error instanceof Error
          ? error.message
          : "Bestenliste ist gerade nicht erreichbar."
      );
    }
  }

  return (
    <section className="scoreboard" aria-labelledby="scoreboard-title">
      <div className="scoreboard-heading">
        <div>
          <p className="project-label">COMMUNITY // ANONYME BESTENLISTE</p>
          <h2 id="scoreboard-title">Hall of Tux</h2>
        </div>
        <div className="your-score">
          <span>Dein Score</span>
          <strong>{score}</strong>
          <small>/ 1000</small>
        </div>
      </div>

      <form className="score-entry" onSubmit={submitScore}>
        <label htmlFor="score-alias">
          Alias eintragen
          <small>Keine Klarnamen nötig · öffentlich sichtbar</small>
        </label>
        <div>
          <span aria-hidden="true">@</span>
          <input
            id="score-alias"
            value={alias}
            onChange={(event) => setAlias(event.target.value.slice(0, 18))}
            placeholder="tux_42"
            minLength={2}
            maxLength={18}
            autoComplete="off"
            disabled={submitted || status === "saving"}
          />
          <button type="submit" disabled={submitted || status === "saving"}>
            {status === "saving" ? "Speichere …" : "Score eintragen"}
          </button>
        </div>
      </form>

      {message && (
        <p className={submitted ? "score-message success" : "score-message"}>
          {message}
        </p>
      )}

      <ol className="score-list" aria-label="Top 10">
        {scores.slice(0, 10).map((entry, index) => (
          <li key={`${entry.alias}-${entry.createdAt}-${index}`}>
            <span>{String(index + 1).padStart(2, "0")}</span>
            <strong>{entry.alias}</strong>
            <small>
              {entry.mode} · {entry.questionCount} Fragen
            </small>
            <b>{entry.score}</b>
          </li>
        ))}
      </ol>

      {status === "loading" && (
        <p className="score-empty">Bestenliste wird geladen …</p>
      )}
      {status === "offline" && scores.length === 0 && (
        <p className="score-empty">
          Bestenliste gerade offline – dein Spielstand bleibt erhalten.
        </p>
      )}
      {status === "ready" && scores.length === 0 && (
        <p className="score-empty">
          Noch leer. Das ist deine Chance auf Platz 1.
        </p>
      )}

      <p className="score-privacy">
        Gespeichert werden nur Alias, Spielergebnis, Modus und Zeitpunkt. Keine
        Konten, E-Mail-Adressen oder IP-Adressen in der Score-Datenbank.
      </p>
    </section>
  );
}
