/**
 * @file Profile page component displaying a player's public profile.
 * @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 stat visibility checks */
import { useEffect, useState, type JSX } from "react";
import { formatNumber } from "../../utils/format.js";
import { logError } from "../../utils/logError.js";
import type { PublicProfileResponse } from "@elysium/types";

interface ProfilePageProperties {
  readonly discordId: string;
}

interface StatEntry {
  icon:  string;
  value: string;
  label: string;
  date:  boolean;
}

/**
 * Renders the public profile page for a given player.
 * @param props - The profile page properties.
 * @param props.discordId - The Discord ID of the player to display.
 * @returns The JSX element.
 */
const ProfilePage = ({ discordId }: ProfilePageProperties): JSX.Element => {
  const [ profile, setProfile ] = useState<PublicProfileResponse | null>(null);
  const [ error, setError ] = useState<string | null>(null);
  const [ copied, setCopied ] = useState(false);

  useEffect(() => {
    fetch(`/api/profile/${discordId}`).
      then(async(response) => {
        if (!response.ok) {
          throw new Error("Player not found");
        }
        // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- API response cast
        return await (response.json() as Promise<PublicProfileResponse>);
      }).
      then(setProfile).
      catch((error_: unknown) => {
        setError(
          error_ instanceof Error
            ? error_.message
            : "Failed to load profile",
        );
      });
  }, [ discordId ]);

  function handleCopy(): void {
    void navigator.clipboard.writeText(window.location.href).
      then(() => {
        setCopied(true);
        setTimeout(() => {
          setCopied(false);
        }, 2000);
      }).
      catch((error_: unknown) => {
        logError("clipboard_copy", error_);
      });
  }

  if (error !== null) {
    return (
      <div className="profile-page">
        <div className="profile-error">
          <p>
            {"⚠️ "}
            {error}
          </p>
          <a className="profile-play-link" href="/">
            {"← Play Elysium"}
          </a>
        </div>
      </div>
    );
  }

  if (profile === null) {
    return (
      <div className="profile-page">
        <div className="profile-loading">{"Loading profile…"}</div>
      </div>
    );
  }

  const settings = profile.profileSettings;
  function fmt(value: number): string {
    return formatNumber(value, settings.numberFormat);
  }

  const avatarUrl
    = profile.avatar === null
      ? `https://cdn.discordapp.com/embed/avatars/${String(Number.parseInt(discordId, 10) % 5)}.png`
      : `https://cdn.discordapp.com/avatars/${discordId}/${profile.avatar}.png?size=128`;

  const memberSince = new Date(profile.createdAt).toLocaleDateString("en-GB", {
    day:   "numeric",
    month: "long",
    year:  "numeric",
  });

  const currentRunStatsRaw: Array<StatEntry | false> = [
    settings.showCurrentGold && {
      date:  false,
      icon:  "🪙",
      label: "Gold Earned",
      value: fmt(profile.currentRunGold),
    },
    settings.showCurrentClicks && {
      date:  false,
      icon:  "👆",
      label: "Clicks",
      value: fmt(profile.currentRunClicks),
    },
    settings.showBossesDefeated && {
      date:  false,
      icon:  "💀",
      label: "Bosses Defeated",
      value: String(profile.bossesDefeated),
    },
    settings.showQuestsCompleted && {
      date:  false,
      icon:  "📜",
      label: "Quests Completed",
      value: String(profile.questsCompleted),
    },
    settings.showAdventurersRecruited && {
      date:  false,
      icon:  "⚔️",
      label: "Adventurers Recruited",
      value: fmt(profile.adventurersRecruited),
    },
    settings.showAchievementsUnlocked && {
      date:  false,
      icon:  "🏆",
      label: "Achievements Unlocked",
      value: String(profile.achievementsUnlocked),
    },
  ];
  const currentRunStats = currentRunStatsRaw.filter(
    (entry): entry is StatEntry => {
      return entry !== false;
    },
  );

  const allTimeStatsRaw: Array<StatEntry | false> = [
    settings.showTotalGold && {
      date:  false,
      icon:  "🪙",
      label: "Total Gold Earned",
      value: fmt(profile.totalGoldEarned),
    },
    settings.showTotalClicks && {
      date:  false,
      icon:  "👆",
      label: "Total Clicks",
      value: fmt(profile.totalClicks),
    },
    settings.showLifetimeBossesDefeated && {
      date:  false,
      icon:  "💀",
      label: "Bosses Defeated",
      value: String(profile.lifetimeBossesDefeated),
    },
    settings.showLifetimeQuestsCompleted && {
      date:  false,
      icon:  "📜",
      label: "Quests Completed",
      value: String(profile.lifetimeQuestsCompleted),
    },
    settings.showLifetimeAdventurersRecruited && {
      date:  false,
      icon:  "⚔️",
      label: "Adventurers Recruited",
      value: fmt(profile.lifetimeAdventurersRecruited),
    },
    settings.showLifetimeAchievementsUnlocked && {
      date:  false,
      icon:  "🏆",
      label: "Achievements Unlocked",
      value: String(profile.lifetimeAchievementsUnlocked),
    },
    settings.showGuildFounded && {
      date:  true,
      icon:  "📅",
      label: "Guild Founded",
      value: memberSince,
    },
  ];
  const allTimeStats = allTimeStatsRaw.filter((entry): entry is StatEntry => {
    return entry !== false;
  });

  function renderStats(stats: Array<StatEntry>): JSX.Element {
    return (
      <div className="profile-stats">
        {stats.map((stat) => {
          return (
            <div className="profile-stat" key={stat.label}>
              <span className="profile-stat-icon">{stat.icon}</span>
              <span
                className={`profile-stat-value ${
                  stat.date
                    ? "profile-stat-date"
                    : ""
                }`}
              >
                {stat.value}
              </span>
              <span className="profile-stat-label">{stat.label}</span>
            </div>
          );
        })}
      </div>
    );
  }

  return (
    <div className="profile-page">
      <div className="profile-card">
        <div className="profile-header">
          <img
            alt={`${profile.username}'s avatar`}
            className="profile-avatar"
            src={avatarUrl}
          />
          <div className="profile-identity">
            <h1 className="profile-character-name">{profile.characterName}</h1>
            <p className="profile-username">
              {"@"}
              {profile.username}
            </p>
            {settings.showApotheosis && profile.apotheosisCount > 0
              ? <span className="profile-apotheosis-badge">
                {"✨ Apotheosis "}
                {profile.apotheosisCount}
              </span>
              : null}
            {settings.showTranscendence && profile.transcendenceCount > 0
              ? <span className="profile-transcendence-badge">
                {"🌌 Transcendence "}
                {profile.transcendenceCount}
              </span>
              : null}
            {settings.showPrestige && profile.prestigeCount > 0
              ? <span className="profile-prestige-badge">
                {"⭐ Prestige "}
                {profile.prestigeCount}
              </span>
              : null}
          </div>
        </div>

        {profile.bio === ""
          ? null
          : <p className="profile-bio">{profile.bio}</p>
        }

        {currentRunStats.length > 0
          && <div className="profile-stats-section">
            <h3 className="profile-stats-heading">{"Current Run"}</h3>
            {renderStats(currentRunStats)}
          </div>
        }

        {allTimeStats.length > 0
          && <div className="profile-stats-section">
            <h3 className="profile-stats-heading">{"All Time"}</h3>
            {renderStats(allTimeStats)}
          </div>
        }

        <div className="profile-actions">
          <button
            className="profile-share-button"
            onClick={handleCopy}
            type="button"
          >
            {copied
              ? "✓ Copied!"
              : "🔗 Copy Profile Link"}
          </button>
          <a className="profile-play-link" href="/">
            {"⚔️ Play Elysium"}
          </a>
        </div>
      </div>
    </div>
  );
};

export { ProfilePage };
