/**
 * @file Read-only panel displaying vampire quests grouped by zone.
 * @copyright nhcarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */
/* eslint-disable max-lines-per-function -- Complex component with many render paths */
/* eslint-disable react/no-multi-comp -- QuestCard sub-component is tightly coupled */
import { useState, type JSX } from "react";
import { useGame } from "../../context/gameContext.js";
import type {
  VampireQuest,
  VampireQuestReward,
  VampireZone,
} from "@elysium/types";

/**
 * Formats a duration in seconds to a human-readable string.
 * @param seconds - The total number of seconds to format.
 * @returns The formatted duration string.
 */
const formatDuration = (seconds: number): string => {
  const secondsPerHour = 3600;
  const secondsPerMinute = 60;
  if (seconds >= secondsPerHour) {
    const hours = Math.floor(seconds / secondsPerHour);
    const remainderSeconds = seconds % secondsPerHour;
    const minutes = Math.floor(remainderSeconds / secondsPerMinute);
    return `${String(hours)}h ${String(minutes)}m`;
  }
  if (seconds >= secondsPerMinute) {
    const minutes = Math.floor(seconds / secondsPerMinute);
    const secs = seconds % secondsPerMinute;
    return `${String(minutes)}m ${String(secs)}s`;
  }
  return `${String(seconds)}s`;
};

/**
 * Returns a human-readable label string for a vampire quest reward.
 * @param reward - The reward to describe.
 * @param formatNumber - The number formatter function.
 * @returns The label string for the given reward type.
 */
const getRewardLabel = (
  reward: VampireQuestReward,
  formatNumber: (value: number)=> string,
): string => {
  if (reward.type === "blood") {
    return `🩸 ${formatNumber(reward.amount ?? 0)} Blood`;
  }
  if (reward.type === "ichor") {
    return `💧 ${formatNumber(reward.amount ?? 0)} Ichor`;
  }
  if (reward.type === "soulShards") {
    return `💠 ${formatNumber(reward.amount ?? 0)} Soul Shards`;
  }
  if (reward.type === "upgrade") {
    return "🔓 Upgrade Unlocked";
  }
  if (reward.type === "thrall") {
    return "🧟 New Thrall Tier";
  }
  return "🦇 Equipment Unlocked";
};

interface VampireQuestCardProperties {
  readonly quest:      VampireQuest;
  readonly unlockHint: string | undefined;
  readonly zoneIsOpen: boolean;
}

/**
 * Renders a single vampire quest card (read-only).
 * @param props - The component properties.
 * @param props.quest - The vampire quest to display.
 * @param props.unlockHint - The name of the prerequisite quest, if locked.
 * @param props.zoneIsOpen - Whether the quest's zone is currently unlocked.
 * @returns The JSX element.
 */
const VampireQuestCard = ({
  quest,
  unlockHint,
  zoneIsOpen,
}: VampireQuestCardProperties): JSX.Element => {
  const { formatNumber } = useGame();

  return (
    <div className={`quest-card quest-${quest.status}`}>
      <div className="quest-info">
        <h3>{quest.name}</h3>
        <p>{quest.description}</p>
        <p className="quest-duration">
          {"⏱ "}
          {formatDuration(quest.durationSeconds)}
        </p>
        <div className="quest-rewards">
          {quest.rewards.map((reward, rewardIndex) => {
            return <span
              className="reward-tag"
              key={`${reward.type}-${reward.targetId ?? String(reward.amount ?? rewardIndex)}`}
            >
              {getRewardLabel(reward, formatNumber)}
            </span>;
          })}
        </div>
      </div>
      <div className="quest-action">
        {quest.status === "locked" && !zoneIsOpen
          && <span className="quest-badge locked">{"🔒 Zone Locked"}</span>
        }
        {quest.status === "locked" && zoneIsOpen
          ? <>
            <span className="quest-badge locked">{"🔒 Locked"}</span>
            {unlockHint !== undefined
              && <p className="unlock-hint">
                {"📜 Complete: "}
                {unlockHint}
              </p>
            }
          </>
          : null
        }
        {quest.status === "available"
          && <span className="quest-badge available">{"📋 Available"}</span>
        }
        {quest.status === "active"
          && <span className="quest-badge active">{"⏳ In Progress"}</span>
        }
        {quest.status === "completed"
          && <span className="quest-badge completed">{"✅ Completed"}</span>
        }
      </div>
    </div>
  );
};

/**
 * Renders the vampire quests panel with zone selection and quest list.
 * @returns The JSX element.
 */
const VampireQuestsPanel = (): JSX.Element => {
  const { state } = useGame();
  const [ activeZoneId, setActiveZoneId ] = useState(() => {
    return sessionStorage.getItem("elysium_vampire_quest_zone")
      ?? "vampire_haunted_catacombs";
  });

  if (state === null) {
    return (
      <section className="panel">
        <p>{"Loading..."}</p>
      </section>
    );
  }

  const vampireState = state.vampire;
  if (vampireState === undefined) {
    return (
      <section className="panel">
        <p>{"Vampire expansion not yet unlocked."}</p>
      </section>
    );
  }

  const { zones, quests } = vampireState;

  const activeZone = zones.find((zone: VampireZone) => {
    return zone.id === activeZoneId;
  });
  const zoneIsOpen = activeZone?.status === "unlocked";

  const zoneQuests = quests.filter((quest: VampireQuest) => {
    return quest.zoneId === activeZoneId;
  });

  const questNameById = new Map(
    quests.map((quest: VampireQuest) => {
      return [ quest.id, quest.name ];
    }),
  );

  const getUnlockHint = (quest: VampireQuest): string | undefined => {
    if (quest.status !== "locked" || quest.prerequisiteIds.length === 0) {
      return undefined;
    }
    const [ prereqId ] = quest.prerequisiteIds;
    if (prereqId === undefined) {
      return undefined;
    }
    return questNameById.get(prereqId);
  };

  function handleZoneSelect(zoneId: string): void {
    setActiveZoneId(zoneId);
    sessionStorage.setItem("elysium_vampire_quest_zone", zoneId);
  }

  const completedCount = zoneQuests.filter((quest: VampireQuest) => {
    return quest.status === "completed";
  }).length;

  return (
    <section className="panel vampire-quests-panel">
      <h2>{"Vampire Quests"}</h2>
      <div className="zone-filter-buttons">
        {zones.map((zone: VampireZone) => {
          function handleClick(): void {
            handleZoneSelect(zone.id);
          }
          return <button
            className={`zone-filter-button ${zone.id === activeZoneId
              ? "active"
              : ""} ${zone.status === "locked"
              ? "zone-locked"
              : ""}`}
            key={zone.id}
            onClick={handleClick}
            title={zone.status === "locked"
              ? "Zone locked"
              : zone.name}
            type="button"
          >
            {zone.emoji}
            {" "}
            {zone.name}
          </button>;
        })}
      </div>
      {activeZone !== undefined
        && <div className="zone-info">
          <p className="zone-description">{activeZone.description}</p>
          <p className="zone-progress">
            {String(completedCount)}
            {" / "}
            {String(zoneQuests.length)}
            {" quests completed"}
          </p>
          {activeZone.status === "locked"
            && <p className="zone-locked-notice">
              {"🔒 This zone is locked. Defeat the required vampire boss"}
              {" to unlock it."}
            </p>
          }
        </div>
      }
      <div className="quest-list">
        {zoneQuests.length === 0
          ? <p className="empty-state">{"No quests in this zone."}</p>
          : zoneQuests.map((quest: VampireQuest) => {
            return <VampireQuestCard
              key={quest.id}
              quest={quest}
              unlockHint={getUnlockHint(quest)}
              zoneIsOpen={zoneIsOpen}
            />;
          })
        }
      </div>
    </section>
  );
};

export { VampireQuestsPanel };
