/**
 * @file Thralls panel component for purchasing vampire thralls.
 * @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 -- ThrallCard sub-component is tightly coupled */
/* eslint-disable complexity -- ThrallCard has inherent branching for batch/afford logic */
import { type JSX, useState } from "react";
import { useGame } from "../../context/gameContext.js";
import type { VampireThrall } from "@elysium/types";

type BatchSize = 1 | 10 | "max";
const batchOptions: Array<BatchSize> = [ 1, 10, "max" ];

const growthRate = 1.15;

/**
 * Computes the total blood cost to buy a batch of thralls.
 * @param thrall - The thrall tier to purchase.
 * @param quantity - The number to buy.
 * @returns The total blood cost.
 */
const computeBatchCost = (
  thrall: VampireThrall,
  quantity: number,
): number => {
  let total = 0;
  for (let index = 0; index < quantity; index = index + 1) {
    const exponent = thrall.count + index;
    const cost = thrall.baseCost * Math.pow(growthRate, exponent);
    total = total + cost;
  }
  return total;
};

/**
 * Computes the maximum number of thralls affordable with the available blood.
 * @param thrall - The thrall tier.
 * @param blood - The available blood balance.
 * @returns The maximum affordable quantity.
 */
const computeMaxAffordable = (
  thrall: VampireThrall,
  blood: number,
): number => {
  let total = 0;
  let quantity = 0;
  for (let index = 0; index < 100_000; index = index + 1) {
    const exponent = thrall.count + index;
    const cost = thrall.baseCost * Math.pow(growthRate, exponent);
    if (total + cost > blood) {
      break;
    }
    total = total + cost;
    quantity = quantity + 1;
  }
  return quantity;
};

/**
 * Parses a localStorage string back into a valid BatchSize, defaulting to 1.
 * @param stored - The raw string from localStorage (or null if absent).
 * @returns A valid BatchSize value.
 */
const parseBatchSize = (stored: string | null): BatchSize => {
  if (stored === "max") {
    return "max";
  }
  if (stored === "10") {
    return 10;
  }
  return 1;
};

interface ThrallCardProperties {
  readonly thrall:        VampireThrall;
  readonly blood:         number;
  readonly selectedBatch: BatchSize;
}

/**
 * Renders a single thrall purchase card.
 * @param props - The component properties.
 * @param props.thrall - The thrall tier to display.
 * @param props.blood - The player's current blood balance.
 * @param props.selectedBatch - The active batch size selection.
 * @returns The JSX element.
 */
const ThrallCard = ({
  thrall,
  blood,
  selectedBatch,
}: ThrallCardProperties): JSX.Element => {
  const { buyVampireThrall, formatNumber } = useGame();

  const maxAffordable = computeMaxAffordable(thrall, blood);
  const effectiveBatch = selectedBatch === "max"
    ? maxAffordable
    : selectedBatch;
  const batchCost = computeBatchCost(thrall, effectiveBatch);
  const canAffordBatch = blood >= batchCost && effectiveBatch > 0;

  const singleCost = computeBatchCost(thrall, 1);

  function handleBuy(): void {
    if (effectiveBatch > 0) {
      buyVampireThrall(thrall.id, effectiveBatch);
    }
  }

  function getBuyButtonLabel(): string {
    if (selectedBatch === "max") {
      if (maxAffordable === 0) {
        return "Can't Afford";
      }
      return `Buy Max (×${String(maxAffordable)})`;
    }
    return `Buy ×${String(effectiveBatch)}`;
  }

  return (
    <div className={`disciple-card ${thrall.unlocked
      ? ""
      : "disciple-locked"}`}>
      <div className="disciple-header">
        <div className="disciple-title">
          <h3>{thrall.name}</h3>
          <span className="disciple-class">{thrall.class}</span>
        </div>
        <span className="disciple-count">
          {"×"}
          {formatNumber(thrall.count)}
        </span>
      </div>
      <div className="disciple-income">
        {thrall.bloodPerSecond > 0
          && <span className="income-tag">
            {"🩸 "}
            {formatNumber(thrall.bloodPerSecond)}
            {"/s blood"}
          </span>
        }
        {thrall.ichorPerSecond > 0
          && <span className="income-tag">
            {"💧 "}
            {formatNumber(thrall.ichorPerSecond)}
            {"/s ichor"}
          </span>
        }
        <span className="combat-power-tag">
          {"⚔️ "}
          {formatNumber(thrall.combatPower)}
          {" combat power each"}
        </span>
      </div>
      <div className="disciple-cost">
        <span className="cost-label">
          {"Next: 🩸 "}
          {formatNumber(singleCost)}
        </span>
        {selectedBatch !== 1
          && effectiveBatch > 0
          && <span className="cost-label">
            {selectedBatch === "max"
              ? "Max"
              : String(selectedBatch)}
            {" (×"}
            {String(effectiveBatch)}
            {"): 🩸 "}
            {formatNumber(batchCost)}
          </span>
        }
      </div>
      {thrall.unlocked
        ? <button
          className="buy-disciple-button"
          disabled={!canAffordBatch}
          onClick={handleBuy}
          title={
            canAffordBatch
              ? undefined
              : `Need 🩸 ${formatNumber(batchCost)} blood`
          }
          type="button"
        >
          {getBuyButtonLabel()}
        </button>
        : <span className="disciple-badge locked">{"🔒 Locked"}</span>
      }
    </div>
  );
};

/**
 * Renders the thralls panel for purchasing vampire thralls.
 * @returns The JSX element.
 */
const VampireThrallsPanel = (): JSX.Element => {
  const { state, formatNumber, toggleVampireAutoThrall } = useGame();
  const [ selectedBatch, setSelectedBatch ] = useState<BatchSize>(() => {
    return parseBatchSize(localStorage.getItem("elysium_thrall_batch"));
  });

  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 blood = state.resources.blood ?? 0;
  const { thralls, autoThrall } = vampireState;
  const autoThrallOn = autoThrall === true;

  function handleBatchSelect(batch: BatchSize): void {
    setSelectedBatch(batch);
    localStorage.setItem("elysium_thrall_batch", String(batch));
  }

  return (
    <section className="panel disciples-panel">
      <div className="panel-header">
        <h2>{"Thralls"}</h2>
        <button
          className={`auto-toggle ${autoThrallOn
            ? "auto-on"
            : "auto-off"}`}
          onClick={toggleVampireAutoThrall}
          title={autoThrallOn
            ? "Auto-Thrall is ON — click to disable"
            : "Auto-Thrall is OFF — click to enable"}
          type="button"
        >
          {autoThrallOn
            ? "🤖 Auto-Thrall: ON"
            : "🤖 Auto-Thrall: OFF"}
        </button>
      </div>
      <div className="disciples-balance">
        <span>
          {"🩸 Blood: "}
          <strong>{formatNumber(blood)}</strong>
        </span>
      </div>
      <div className="batch-selector">
        {batchOptions.map((batch) => {
          function handleClick(): void {
            handleBatchSelect(batch);
          }
          return <button
            className={`batch-button ${selectedBatch === batch
              ? "active"
              : ""}`}
            key={String(batch)}
            onClick={handleClick}
            type="button"
          >
            {batch === "max"
              ? "Max"
              : `×${String(batch)}`}
          </button>;
        })}
      </div>
      <div className="disciples-list">
        {thralls.map((thrall: VampireThrall) => {
          return <ThrallCard
            blood={blood}
            key={thrall.id}
            selectedBatch={selectedBatch}
            thrall={thrall}
          />;
        })}
      </div>
    </section>
  );
};

export { VampireThrallsPanel };
