/**
 * @file Resource bar component displaying player resources and profile actions.
 * @copyright nhcarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */
/* eslint-disable max-lines -- Resource bar has many resource and action elements */
/* eslint-disable max-lines-per-function -- Large header with many resource and action elements */
/* eslint-disable max-statements -- Resource bar requires many local computations and handlers */
/* eslint-disable complexity -- Many conditional resource and badge render paths */
import { useState, type FocusEvent, type JSX } from "react";
import { useGame } from "../../context/gameContext.js";
import {
  RESOURCE_CAP,
  computeEssencePerSecond,
  computeGoldPerSecond,
  computePartyCombatPower,
  computeProjectedRunestones,
} from "../../engine/tick.js";
import type { Resource } from "@elysium/types";

interface ResourceBarProperties {
  readonly resources:          Resource;
  readonly runestones:         number;
  readonly prestigeCount:      number;
  readonly transcendenceCount: number;
  readonly apotheosisCount:    number;
  readonly onEditProfile:      ()=> void;
  readonly lastSavedAt:        number | null;
  readonly isSyncing:          boolean;
  readonly onForceSync:        ()=> Promise<void>;
}

/**
 * Formats a timestamp as a human-readable relative time string.
 * @param timestamp - The Unix timestamp in milliseconds.
 * @returns The relative time string.
 */
const formatRelativeTime = (timestamp: number): string => {
  const seconds = Math.floor((Date.now() - timestamp) / 1000);
  if (seconds < 10) {
    return "just now";
  }
  if (seconds < 60) {
    return `${String(seconds)}s ago`;
  }
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) {
    return `${String(minutes)}m ago`;
  }
  const hours = Math.floor(minutes / 60);
  return `${String(hours)}h ago`;
};

const resourceFullTooltip = [
  "This resource is full!",
  " Consider spending some or prestiging to keep earning.",
].join("");

/**
 * Renders the resource bar with player resources and profile actions.
 * @param props - The resource bar properties.
 * @param props.resources - The current player resources.
 * @param props.runestones - The current runestone count.
 * @param props.prestigeCount - The number of prestiges completed.
 * @param props.transcendenceCount - The number of transcendences completed.
 * @param props.apotheosisCount - The number of apotheoses completed.
 * @param props.onEditProfile - Callback to open the edit profile modal.
 * @param props.lastSavedAt - Timestamp of the last cloud save.
 * @param props.isSyncing - Whether a sync is currently in progress.
 * @param props.onForceSync - Callback to trigger a forced cloud sync.
 * @returns The JSX element.
 */
const ResourceBar = ({
  resources,
  runestones,
  prestigeCount,
  transcendenceCount,
  apotheosisCount,
  onEditProfile,
  lastSavedAt,
  isSyncing,
  onForceSync,
}: ResourceBarProperties): JSX.Element => {
  const { formatNumber, syncError, state } = useGame();
  const [ isProfileOpen, setIsProfileOpen ] = useState(false);
  const [ isResourcesOpen, setIsResourcesOpen ] = useState(false);

  const { gold, essence, crystals } = resources;
  let partyCombatPower = 0;
  let goldPerSecond = 0;
  let essencePerSecond = 0;
  let projectedRunestones = 0;
  if (state !== null) {
    partyCombatPower = computePartyCombatPower(state);
    goldPerSecond = computeGoldPerSecond(state);
    essencePerSecond = computeEssencePerSecond(state);
    projectedRunestones = computeProjectedRunestones(state);
  }

  let avatarUrl: string | null = null;
  if (state !== null) {
    avatarUrl = state.player.avatar === null
      ? `https://cdn.discordapp.com/embed/avatars/${String(Number.parseInt(state.player.discordId, 10) % 5)}.png`
      : `https://cdn.discordapp.com/avatars/${state.player.discordId}/${state.player.avatar}.png?size=64`;
  }
  const profileUrl = state === null
    ? "#"
    : `/profile/${state.player.discordId}`;

  const goldFull = gold >= RESOURCE_CAP;
  const essenceFull = essence >= RESOURCE_CAP;
  const crystalsFull = crystals >= RESOURCE_CAP;
  const anyFull = goldFull || essenceFull || crystalsFull;
  const hiddenResourcesFull = essenceFull || crystalsFull;

  function handleForceSync(): void {
    void onForceSync();
  }

  function handleToggleResources(): void {
    setIsResourcesOpen((previous) => {
      return !previous;
    });
  }

  function handleResourceBlur(event: FocusEvent<HTMLDivElement>): void {
    if (!event.currentTarget.contains(event.relatedTarget)) {
      setIsResourcesOpen(false);
    }
  }

  function handleToggleProfile(): void {
    setIsProfileOpen((previous) => {
      return !previous;
    });
  }

  function handleProfileBlur(event: FocusEvent<HTMLDivElement>): void {
    if (!event.currentTarget.contains(event.relatedTarget)) {
      setIsProfileOpen(false);
    }
  }

  function handleEditProfile(): void {
    setIsProfileOpen(false);
    onEditProfile();
  }

  return (
    <>
      <header className="resource-bar">
        <div
          className="resource-menu"
          onBlur={handleResourceBlur}
        >
          <button
            className={`resource resource-toggle${goldFull
              ? " resource-full"
              : ""}`}
            onClick={handleToggleResources}
            title="Click to see all resources"
            type="button"
          >
            <span className="resource-icon">{"🪙"}</span>
            <span className="resource-value">{formatNumber(gold)}</span>
            <span className="resource-label">{"Gold"}</span>
            {goldFull
              ? <span
                className="resource-cap-badge"
                title={resourceFullTooltip}
              >
                {"FULL"}
              </span>
              : null}
            {hiddenResourcesFull
              ? <span
                className="resource-alert-dot"
                title={"One or more resources are full!"}
              />
              : null}
          </button>
          {isResourcesOpen
            ? <div className="resources-dropdown">
              <div className="resource">
                <span className="resource-icon">{"📈"}</span>
                <span className="resource-value">
                  {formatNumber(goldPerSecond)}
                </span>
                <span className="resource-label">{"Gold/s"}</span>
              </div>
              <div className="resource">
                <span className="resource-icon">{"⚡"}</span>
                <span className="resource-value">
                  {formatNumber(essencePerSecond)}
                </span>
                <span className="resource-label">{"Essence/s"}</span>
              </div>
              <div className={`resource${essenceFull
                ? " resource-full"
                : ""}`}>
                <span className="resource-icon">{"✨"}</span>
                <span className="resource-value">
                  {formatNumber(essence)}
                </span>
                <span className="resource-label">{"Essence"}</span>
                {essenceFull
                  ? <span
                    className="resource-cap-badge"
                    title={resourceFullTooltip}
                  >
                    {"FULL"}
                  </span>
                  : null}
              </div>
              <div className={`resource${crystalsFull
                ? " resource-full"
                : ""}`}>
                <span className="resource-icon">{"💎"}</span>
                <span className="resource-value">
                  {formatNumber(crystals)}
                </span>
                <span className="resource-label">{"Crystals"}</span>
                {crystalsFull
                  ? <span
                    className="resource-cap-badge"
                    title={resourceFullTooltip}
                  >
                    {"FULL"}
                  </span>
                  : null}
              </div>
              <div className="resource">
                <span className="resource-icon">{"🔮"}</span>
                <span className="resource-value">
                  {formatNumber(runestones)}
                </span>
                <span className="resource-label">{"Runestones"}</span>
              </div>
              <div className="resource">
                <span className="resource-icon">{"⭐"}</span>
                <span className="resource-value">
                  {`+${formatNumber(projectedRunestones)}`}
                </span>
                <span className="resource-label">{"On Prestige"}</span>
              </div>
              <div className="resource">
                <span className="resource-icon">{"⚔️"}</span>
                <span className="resource-value">
                  {formatNumber(partyCombatPower)}
                </span>
                <span className="resource-label">{"Combat Power"}</span>
              </div>
            </div>
            : null}
        </div>
        {apotheosisCount > 0
          && <div className="apotheosis-badge">
            {"✨ Apotheosis "}
            {apotheosisCount}
          </div>
        }
        {transcendenceCount > 0
          && <div className="transcendence-badge">
            {"🌌 Transcendence "}
            {transcendenceCount}
          </div>
        }
        {prestigeCount > 0
          && <div className="prestige-badge">
            {"⭐ Prestige "}
            {prestigeCount}
          </div>
        }
        <div className="resource-bar-actions">
          {syncError === null
            ? null
            : <span className="save-status save-error" title={syncError}>
              {"❌ Save failed"}
            </span>
          }
          {syncError === null && lastSavedAt !== null
            ? <span
              className="save-status"
              title={new Date(lastSavedAt).toLocaleString()}
            >
              {"☁️ "}
              {formatRelativeTime(lastSavedAt)}
            </span>
            : null}
          <button
            className="force-save-button"
            disabled={isSyncing}
            onClick={handleForceSync}
            title="Force cloud save"
            type="button"
          >
            {isSyncing
              ? "⏳"
              : "💾"}
          </button>
          {avatarUrl === null
            ? null
            : <div
              className="profile-menu"
              onBlur={handleProfileBlur}
            >
              <button
                className="profile-avatar-button"
                onClick={handleToggleProfile}
                title="Account"
                type="button"
              >
                <img
                  alt="Profile"
                  className="profile-avatar-img"
                  src={avatarUrl}
                />
              </button>
              {isProfileOpen
                ? <div className="profile-dropdown">
                  <a
                    className="profile-dropdown-item"
                    href={profileUrl}
                    rel="noreferrer"
                    target="_blank"
                  >
                    {"👤 View Profile"}
                  </a>
                  <button
                    className="profile-dropdown-item"
                    onClick={handleEditProfile}
                    type="button"
                  >
                    {"✏️ Edit Profile"}
                  </button>
                  <hr className="profile-dropdown-divider" />
                  <a
                    className="profile-dropdown-item"
                    href="https://donate.nhcarrigan.com"
                    rel="noreferrer"
                    target="_blank"
                  >
                    {"💜 Donate"}
                  </a>
                  <a
                    className="profile-dropdown-item"
                    href="https://chat.nhcarrigan.com"
                    rel="noreferrer"
                    target="_blank"
                  >
                    {"💬 Discord"}
                  </a>
                  <a
                    className="profile-dropdown-item"
                    href="https://support.nhcarrigan.com"
                    rel="noreferrer"
                    target="_blank"
                  >
                    {"🆘 Support"}
                  </a>
                </div>
                : null}
            </div>}
        </div>
      </header>
      {anyFull
        ? <div className="resource-cap-notice">
          {"⚠️ One or more resources are full! Consider spending some or"
            + " prestiging to keep earning."}
        </div>
        : null}
    </>
  );
};

export { ResourceBar };
