/**
 * @file Public character page for viewing a player's character sheet.
 * @copyright nhcarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */
/* eslint-disable max-lines-per-function -- Complex component with many render paths */
/* eslint-disable max-lines -- Story section adds lines beyond the file limit */
/* eslint-disable complexity -- Many conditional render paths for optional fields */
import {
  STORY_CHAPTERS,
  type EquipmentBonus,
  type EquipmentType,
  type PublicProfileResponse,
} from "@elysium/types";
import { type JSX, useEffect, useState } from "react";
import { logError } from "../../utils/logError.js";

interface CharacterPageProperties {
  readonly discordId: string;
}

const slotIcons: Record<EquipmentType, string> = {
  armour:  "🛡️",
  trinket: "💍",
  weapon:  "⚔️",
};

/**
 * Formats an equipment bonus as a human-readable string.
 * @param bonus - The equipment bonus to format.
 * @returns The formatted bonus string.
 */
const formatBonus = (bonus: EquipmentBonus): string => {
  const parts: Array<string> = [];
  if (bonus.goldMultiplier !== undefined) {
    const pct = Math.round((bonus.goldMultiplier - 1) * 100);
    parts.push(`+${String(pct)}% Gold Income`);
  }
  if (bonus.combatMultiplier !== undefined) {
    const pct = Math.round((bonus.combatMultiplier - 1) * 100);
    parts.push(`+${String(pct)}% Combat Power`);
  }
  if (bonus.clickMultiplier !== undefined) {
    const pct = Math.round((bonus.clickMultiplier - 1) * 100);
    parts.push(`+${String(pct)}% Click Power`);
  }
  return parts.join(" · ");
};

/**
 * Renders the public character page for a given Discord user.
 * @param props - The character page properties.
 * @param props.discordId - The Discord ID of the player to display.
 * @returns The JSX element.
 */
const CharacterPage = ({ discordId }: CharacterPageProperties): 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 requires cast
        return await (response.json() as Promise<PublicProfileResponse>);
      }).
      then(setProfile).
      catch((error_: unknown) => {
        setError(
          error_ instanceof Error
            ? error_.message
            : "Failed to load character sheet",
        );
      });
  }, [ 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="character-page">
        <div className="character-page-error">
          <p>
            {"⚠️ "}
            {error}
          </p>
          <a className="character-page-link" href="/">
            {"← Play Elysium"}
          </a>
        </div>
      </div>
    );
  }

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

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

  const subtitleParts = [
    profile.characterRace,
    profile.characterClass,
  ].filter((part) => {
    return part !== "";
  });
  const subtitle = subtitleParts.join(" · ");

  const activeTitleEntry
    = profile.activeTitle === ""
      ? undefined
      : profile.unlockedTitles.find((title) => {
        return title.id === profile.activeTitle;
      });
  const activeTitleName
    = activeTitleEntry === undefined
      ? null
      : activeTitleEntry.name;

  const hasBadge
    = profile.apotheosisCount > 0
    || profile.transcendenceCount > 0
    || profile.prestigeCount > 0;

  const displayName
    = profile.characterName === ""
      ? profile.username
      : profile.characterName;

  return (
    <div className="character-page">
      <div className="character-page-card">
        <div className="character-page-header">
          <img
            alt={`${displayName}'s avatar`}
            className="character-page-avatar"
            src={avatarUrl}
          />
          <div className="character-page-identity">
            <h1 className="character-page-name">{displayName}</h1>
            {activeTitleName === null
              ? null
              : <p className="character-page-title">{activeTitleName}</p>
            }
            {profile.pronouns === ""
              ? null
              : <p className="character-page-pronouns">{profile.pronouns}</p>
            }
            {subtitle === ""
              ? null
              : <p className="character-page-subtitle">{subtitle}</p>
            }
            {hasBadge
              ? <div className="character-page-badges">
                {profile.apotheosisCount > 0
                  && <span
                    className={
                      "character-page-badge character-page-badge--apotheosis"
                    }
                  >
                    {"✨ Apotheosis "}
                    {profile.apotheosisCount}
                  </span>
                }
                {profile.transcendenceCount > 0
                  && <span
                    className={
                      "character-page-badge"
                      + " character-page-badge--transcendence"
                    }
                  >
                    {"🌌 Transcendence "}
                    {profile.transcendenceCount}
                  </span>
                }
                {profile.prestigeCount > 0
                  && <span
                    className={
                      "character-page-badge character-page-badge--prestige"
                    }
                  >
                    {"⭐ Prestige "}
                    {profile.prestigeCount}
                  </span>
                }
              </div>
              : null}
          </div>
        </div>

        {profile.bio === ""
          ? null
          : <div className="character-page-section">
            <h2 className="character-page-section-title">{"⚔️ About"}</h2>
            <p className="character-page-bio">{profile.bio}</p>
          </div>
        }

        {profile.guildName === ""
          ? null
          : <div className="character-page-section">
            <h2 className="character-page-section-title">{"🏰 Guild"}</h2>
            <p className="character-page-guild-name">{profile.guildName}</p>
            {profile.guildDescription === ""
              ? null
              : <p className="character-page-guild-desc">
                {profile.guildDescription}
              </p>
            }
          </div>
        }

        {profile.equippedItems.length > 0
          && <div className="character-page-section">
            <h2 className="character-page-section-title">{"🗡️ Equipment"}</h2>
            <div className="character-page-equipment-list">
              {profile.equippedItems.map((item) => {
                return (
                  <div
                    className="character-page-equipment-item"
                    key={item.name}
                  >
                    <div className="character-page-equipment-header">
                      <span className="character-page-equipment-slot">
                        {slotIcons[item.type]}
                      </span>
                      <span
                        className={
                          "character-page-equipment-name"
                          + ` character-sheet-rarity--${item.rarity}`
                        }
                      >
                        {item.name}
                      </span>
                      <span
                        className={
                          "character-page-equipment-rarity"
                          + ` character-sheet-rarity--${item.rarity}`
                        }
                      >
                        {item.rarity}
                      </span>
                    </div>
                    <p className="character-page-equipment-bonus">
                      {formatBonus(item.bonus)}
                    </p>
                  </div>
                );
              })}
            </div>
          </div>
        }

        {profile.completedChapters.length === 0
          ? null
          : <div className="character-page-section">
            <h2 className="character-page-section-title">{"📖 Story"}</h2>
            {profile.completedChapters.map((completion) => {
              const chapter = STORY_CHAPTERS.find((candidate) => {
                return candidate.id === completion.chapterId;
              });
              if (chapter === undefined) {
                return null;
              }
              const choice = chapter.choices.find((candidate) => {
                return candidate.id === completion.choiceId;
              });
              if (choice === undefined) {
                return null;
              }
              return (
                <div
                  className="character-sheet-story-entry"
                  key={completion.chapterId}
                >
                  <span className="character-sheet-story-chapter">
                    {chapter.title}
                  </span>
                  <span className="character-sheet-story-choice">
                    {choice.label}
                  </span>
                  <p className="character-sheet-story-outcome">
                    {choice.description}
                  </p>
                </div>
              );
            })}
          </div>
        }

        <div className="character-page-divider" />

        <p className="character-page-player-line">
          {"Played by "}
          <span className="character-page-username">
            {"@"}
            {profile.username}
          </span>
        </p>

        <div className="character-page-actions">
          <button
            className="character-page-share-btn"
            onClick={handleCopy}
            type="button"
          >
            {copied
              ? "✓ Copied!"
              : "🔗 Share Character"}
          </button>
          <a
            className="character-page-profile-link"
            href={`/profile/${discordId}`}
          >
            {"📊 View Stats"}
          </a>
          <a className="character-page-play-link" href="/">
            {"⚔️ Play Elysium"}
          </a>
        </div>
      </div>
    </div>
  );
};

export { CharacterPage };
