/**
 * @file Leaderboard page component showing top players across categories.
 * @copyright nhcarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */
/* eslint-disable max-lines-per-function -- Complex component with many render paths */
/* eslint-disable complexity -- Many conditional render paths for categories and entries */
import { useEffect, useState, type JSX } from "react";
import type { LeaderboardCategory, LeaderboardEntry } from "@elysium/types";

interface CategoryConfig {
  id:          LeaderboardCategory;
  label:       string;
  icon:        string;
  formatValue: (value: number)=> string;
}

const goldSuffixes = [
  "",
  "K",
  "M",
  "B",
  "T",
  "Qa",
  "Qt",
  "S",
  "Sp",
  "O",
  "N",
  "D",
];

/**
 * Formats a gold value with a short suffix.
 * @param value - The gold amount to format.
 * @returns The formatted string.
 */
const formatGold = (value: number): string => {
  if (value === 0) {
    return "0";
  }
  const tier = Math.floor(Math.log10(Math.abs(value)) / 3);
  const clamped = Math.min(tier, goldSuffixes.length - 1);
  const scaled = value / Math.pow(1000, clamped);
  return `${String(Number.parseFloat(scaled.toFixed(2)))}${goldSuffixes[clamped] ?? ""}`;
};

const categories: Array<CategoryConfig> = [
  {
    formatValue: (v): string => {
      return formatGold(v);
    },
    icon:  "🪙",
    id:    "totalGold",
    label: "Lifetime Gold",
  },
  {
    formatValue: (v): string => {
      return v.toLocaleString();
    },
    icon:  "💀",
    id:    "bossesDefeated",
    label: "Bosses Defeated",
  },
  {
    formatValue: (v): string => {
      return v.toLocaleString();
    },
    icon:  "📜",
    id:    "questsCompleted",
    label: "Quests Completed",
  },
  {
    formatValue: (v): string => {
      return v.toLocaleString();
    },
    icon:  "🏆",
    id:    "achievementsUnlocked",
    label: "Achievements",
  },
  {
    formatValue: (v): string => {
      return v.toLocaleString();
    },
    icon:  "⭐",
    id:    "prestigeCount",
    label: "Prestige",
  },
  {
    formatValue: (v): string => {
      return v.toLocaleString();
    },
    icon:  "🌌",
    id:    "transcendenceCount",
    label: "Transcendence",
  },
  {
    formatValue: (v): string => {
      return v.toLocaleString();
    },
    icon:  "✨",
    id:    "apotheosisCount",
    label: "Apotheosis",
  },
];

const rankBadges: Record<number, string> = { 1: "🥇", 2: "🥈", 3: "🥉" };

/**
 * Renders the leaderboard page with category tabs and player rankings.
 * @returns The JSX element.
 */
const LeaderboardPage = (): JSX.Element => {
  const [ category, setCategory ] = useState<LeaderboardCategory>("totalGold");
  const [ entries, setEntries ] = useState<Array<LeaderboardEntry>>([]);
  const [ loading, setLoading ] = useState(true);
  const [ error, setError ] = useState<string | null>(null);

  useEffect(() => {
    setLoading(true);
    setError(null);
    fetch(`/api/leaderboards?category=${category}&limit=100`).
      then(async(response) => {
        if (!response.ok) {
          throw new Error("Failed to load leaderboard");
        }
        // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- API response cast
        const data = (await response.json()) as {
          entries: Array<LeaderboardEntry>;
        };
        setEntries(data.entries);
      }).
      catch((error_: unknown) => {
        setError(
          error_ instanceof Error
            ? error_.message
            : "Failed to load leaderboard",
        );
      }).
      finally(() => {
        setLoading(false);
      });
  }, [ category ]);

  const currentConfig
    = categories.find((cat) => {
      return cat.id === category;
    }) ?? categories[0];

  return (
    <div className="leaderboard-page">
      <div className="leaderboard-card">
        <div className="leaderboard-header">
          <h1 className="leaderboard-title">{"🏆 Leaderboards"}</h1>
          <p className="leaderboard-subtitle">
            {"The mightiest adventurers in Elysium"}
          </p>
          <p className="leaderboard-update-note">
            {"🔄 Rankings update when you prestige."}
          </p>
        </div>

        <div className="leaderboard-tabs">
          {categories.map((cat) => {
            function handleCategoryClick(): void {
              setCategory(cat.id);
            }
            return (
              <button
                className={`leaderboard-tab ${
                  category === cat.id
                    ? "leaderboard-tab--active"
                    : ""
                }`}
                key={cat.id}
                onClick={handleCategoryClick}
                type="button"
              >
                {cat.icon} {cat.label}
              </button>
            );
          })}
        </div>

        {loading
          ? <div className="leaderboard-loading">{"Loading…"}</div>
          : null}

        {error === null
          ? null
          : <div className="leaderboard-error">
            {"⚠️ "}
            {error}
          </div>
        }

        {!loading && error === null && entries.length === 0
          && <div className="leaderboard-empty">
            {"No entries yet — be the first on the board!"}
          </div>
        }

        {!loading && error === null && entries.length > 0
          && <div className="leaderboard-table">
            <div className="leaderboard-table-header">
              <span className="leaderboard-col-rank">{"Rank"}</span>
              <span className="leaderboard-col-player">{"Player"}</span>
              <span className="leaderboard-col-value">
                {currentConfig?.icon} {currentConfig?.label}
              </span>
            </div>
            {entries.map((entry) => {
              const avatarUrl
                = entry.avatar === null
                  ? `https://cdn.discordapp.com/embed/avatars/${String(Number.parseInt(entry.discordId, 10) % 5)}.png`
                  : `https://cdn.discordapp.com/avatars/${entry.discordId}/${entry.avatar}.png?size=32`;
              const displayName
                = entry.characterName === ""
                  ? entry.username
                  : entry.characterName;

              return (
                <a
                  className={`leaderboard-row ${
                    entry.rank <= 3
                      ? `leaderboard-row--top${String(entry.rank)}`
                      : ""
                  }`}
                  href={`/character/${entry.discordId}`}
                  key={entry.discordId}
                >
                  <span className="leaderboard-col-rank">
                    {rankBadges[entry.rank] ?? `#${String(entry.rank)}`}
                  </span>
                  <span className="leaderboard-col-player">
                    <img
                      alt={displayName}
                      className="leaderboard-avatar"
                      src={avatarUrl}
                    />
                    <span className="leaderboard-player-info">
                      <span className="leaderboard-player-name">
                        {displayName}
                      </span>
                      {entry.activeTitle === ""
                        ? null
                        : <span className="leaderboard-player-title">
                          {entry.activeTitle}
                        </span>
                      }
                    </span>
                  </span>
                  <span className="leaderboard-col-value">
                    {currentConfig?.formatValue(entry.value)}
                  </span>
                </a>
              );
            })}
          </div>
        }

        <div className="leaderboard-footer">
          <a className="leaderboard-play-link" href="/">
            {"⚔️ Play Elysium"}
          </a>
          <p className="leaderboard-privacy-note">
            {"Players can opt out via their profile settings."}
          </p>
        </div>
      </div>
    </div>
  );
};

export { LeaderboardPage };
