import type { PrestigeUpgradeCategory } from "@elysium/types";
import { useState } from "react";
import { prestige } from "../../api/client.js";
import { useGame } from "../../context/GameContext.js";
import {
  PRESTIGE_UPGRADES,
  PRESTIGE_UPGRADE_CATEGORY_LABELS,
} from "../../data/prestigeUpgrades.js";

const BASE_THRESHOLD = 1_000_000;
const THRESHOLD_SCALE = 5;
const RUNESTONES_PER_LEVEL = 10;

const calculateThreshold = (prestigeCount: number): number =>
  BASE_THRESHOLD * Math.pow(THRESHOLD_SCALE, prestigeCount);

const calculateProductionMultiplier = (prestigeCount: number): number =>
  Math.pow(1.15, prestigeCount);

const calculateRunestonePreview = (
  totalGoldEarned: number,
  prestigeCount: number,
  purchasedUpgradeIds: string[],
): number => {
  const threshold = calculateThreshold(prestigeCount);
  const base = Math.floor(Math.sqrt(totalGoldEarned / threshold)) * RUNESTONES_PER_LEVEL;
  const runestoneMult = PRESTIGE_UPGRADES
    .filter((u) => u.category === "runestones" && purchasedUpgradeIds.includes(u.id))
    .reduce((mult, u) => mult * u.multiplier, 1);
  return Math.floor(base * runestoneMult);
};

const CATEGORY_ORDER: PrestigeUpgradeCategory[] = [
  "income",
  "click",
  "essence",
  "crystals",
  "runestones",
  "utility",
];

export const PrestigePanel = (): React.JSX.Element => {
  const { state, reload, formatNumber, buyPrestigeUpgrade, toggleAutoPrestige } = useGame();
  const [isPending, setIsPending] = useState(false);
  const [result, setResult] = useState<{ runestones: number; count: number; milestoneRunestones: number } | null>(null);
  const [prestigeError, setPrestigeError] = useState<string | null>(null);
  const [buyingId, setBuyingId] = useState<string | null>(null);
  const [activeTab, setActiveTab] = useState<"prestige" | "shop">("prestige");

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

  const { prestige: prestigeData, player } = state;
  const threshold = calculateThreshold(prestigeData.count);
  const isEligible = player.totalGoldEarned >= threshold;
  const runestonePreview = calculateRunestonePreview(
    player.totalGoldEarned,
    prestigeData.count,
    prestigeData.purchasedUpgradeIds,
  );
  const nextMultiplier = calculateProductionMultiplier(prestigeData.count + 1);

  const handlePrestige = async (): Promise<void> => {
    setIsPending(true);
    setPrestigeError(null);
    try {
      const data = await prestige({});
      setResult({ runestones: data.runestones, count: data.newPrestigeCount, milestoneRunestones: data.milestoneRunestones });
      await reload();
    } catch (err) {
      setPrestigeError(err instanceof Error ? err.message : "Prestige failed");
    } finally {
      setIsPending(false);
    }
  };

  const handleBuyUpgrade = async (upgradeId: string): Promise<void> => {
    setBuyingId(upgradeId);
    try {
      await buyPrestigeUpgrade(upgradeId);
    } finally {
      setBuyingId(null);
    }
  };

  const upgradesByCategory = CATEGORY_ORDER.map((category) => ({
    category,
    label: PRESTIGE_UPGRADE_CATEGORY_LABELS[category] ?? category,
    upgrades: PRESTIGE_UPGRADES.filter((u) => u.category === category),
  }));

  return (
    <section className="panel prestige-panel">
      <h2>⭐ Prestige</h2>

      <div className="prestige-tabs">
        <button
          className={`prestige-tab ${activeTab === "prestige" ? "active" : ""}`}
          onClick={() => { setActiveTab("prestige"); }}
          type="button"
        >
          Ascend
        </button>
        <button
          className={`prestige-tab ${activeTab === "shop" ? "active" : ""}`}
          onClick={() => { setActiveTab("shop"); }}
          type="button"
        >
          🔮 Runestone Shop ({formatNumber(prestigeData.runestones)} stones)
        </button>
      </div>

      {activeTab === "prestige" && (
        <>
          <p>
            Prestige resets your progress but grants <strong>Runestones</strong> — permanent
            currency used for powerful upgrades. Each prestige multiplies your global production
            by ×1.15 (compounding each run).
          </p>

          <div className="prestige-status">
            <p>
              Total gold this run:{" "}
              <strong>{formatNumber(player.totalGoldEarned)}</strong>
            </p>
            <p>
              Required to prestige: <strong>{formatNumber(threshold)}</strong>
            </p>
            <p>
              Prestige count: <strong>{prestigeData.count}</strong>
            </p>
            <p>
              Current production multiplier:{" "}
              <strong>×{prestigeData.productionMultiplier.toFixed(2)}</strong>
            </p>
            <p>
              After next prestige:{" "}
              <strong>×{nextMultiplier.toFixed(2)}</strong>
            </p>
            <p>
              Runestones: <strong>{formatNumber(prestigeData.runestones)}</strong>
            </p>
            {isEligible && (
              <p className="runestone-preview">
                Runestones on prestige: <strong>+{formatNumber(runestonePreview)}</strong>
              </p>
            )}
            {!isEligible && (
              <p className="prestige-progress">
                Progress: {formatNumber(player.totalGoldEarned)} / {formatNumber(threshold)}{" "}
                ({((player.totalGoldEarned / threshold) * 100).toFixed(1)}%)
              </p>
            )}
          </div>

          {isEligible ? (
            <div className="prestige-form">
              <p>You are ready to prestige!</p>
              <button
                className="prestige-button"
                disabled={isPending}
                onClick={() => { void handlePrestige(); }}
                type="button"
              >
                {isPending ? "Ascending..." : `✨ Ascend (+${formatNumber(runestonePreview)} Runestones)`}
              </button>
              {prestigeError && <p className="error">{prestigeError}</p>}
              {result && (
                <p className="success">
                  Ascended to Prestige {result.count}! Earned {formatNumber(result.runestones)} Runestones.
                  {result.milestoneRunestones > 0 && (
                    <> 🎉 Milestone bonus: +{formatNumber(result.milestoneRunestones)} Runestones!</>
                  )}
                </p>
              )}
            </div>
          ) : (
            <p className="prestige-locked">
              Earn {formatNumber(threshold - player.totalGoldEarned)} more gold to unlock prestige.
            </p>
          )}
        </>
      )}

      {activeTab === "shop" && (
        <div className="runestone-shop">
          <p className="shop-balance">
            Balance: <strong>{formatNumber(prestigeData.runestones)} Runestones</strong>
          </p>

          {upgradesByCategory.map(({ category, label, upgrades }) => (
            <div key={category} className="shop-category">
              <h3>{label}</h3>
              <div className="shop-upgrades">
                {upgrades.map((upgrade) => {
                  const purchased = prestigeData.purchasedUpgradeIds.includes(upgrade.id);
                  const canAfford = prestigeData.runestones >= upgrade.runestonesCost;
                  const isLoading = buyingId === upgrade.id;

                  const isAutoPrestigeToggle = upgrade.id === "auto_prestige" && purchased;
                  const autoPrestigeEnabled = prestigeData.autoPrestigeEnabled ?? false;

                  return (
                    <div
                      key={upgrade.id}
                      className={`shop-upgrade-card ${purchased ? "purchased" : ""} ${!canAfford && !purchased ? "unaffordable" : ""}`}
                    >
                      <div className="shop-upgrade-info">
                        <h4>{upgrade.name}</h4>
                        <p>{upgrade.description}</p>
                        <p className="upgrade-cost">
                          {purchased ? "✅ Purchased" : `🔮 ${formatNumber(upgrade.runestonesCost)} Runestones`}
                        </p>
                      </div>
                      {isAutoPrestigeToggle && (
                        <button
                          className={`auto-prestige-toggle ${autoPrestigeEnabled ? "enabled" : "disabled"}`}
                          onClick={() => { toggleAutoPrestige(); }}
                          type="button"
                        >
                          {autoPrestigeEnabled ? "⚡ Auto ON" : "⏸ Auto OFF"}
                        </button>
                      )}
                      {!purchased && (
                        <button
                          className="buy-upgrade-button"
                          disabled={!canAfford || isLoading || buyingId !== null}
                          onClick={() => { void handleBuyUpgrade(upgrade.id); }}
                          type="button"
                        >
                          {isLoading ? "Buying..." : "Buy"}
                        </button>
                      )}
                    </div>
                  );
                })}
              </div>
            </div>
          ))}
        </div>
      )}
    </section>
  );
};
