'use client';
import { useGameStore, fmt, fmtDec, calcDamage, computePactMultiplier, computePactInsightMultiplier } from '@/lib/game/store';
import { ELEMENTS, GUARDIANS, SPELLS_DEF } from '@/lib/game/constants';
import { SKILL_EVOLUTION_PATHS, getTierMultiplier } from '@/lib/game/skill-evolution';
import { useManaStats, useCombatStats, useStudyStats } from '@/lib/game/hooks/useGameDerived';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import { Droplet, Swords, BookOpen, FlaskConical, RotateCcw, Trophy, Star } from 'lucide-react';
import type { SkillUpgradeChoice } from '@/lib/game/types';
export function StatsTab() {
const store = useGameStore();
const {
upgradeEffects, maxMana, baseRegen, clickMana,
meditationMultiplier, incursionStrength, manaCascadeBonus, effectiveRegen,
hasSteadyStream, hasManaTorrent, hasDesperateWells
} = useManaStats();
const { activeSpellDef, pactMultiplier, pactInsightMultiplier } = useCombatStats();
const { studySpeedMult, studyCostMult } = useStudyStats();
// Compute element max
const elemMax = (() => {
const ea = store.skillTiers?.elemAttune || 1;
const tieredSkillId = ea > 1 ? `elemAttune_t${ea}` : 'elemAttune';
const level = store.skills[tieredSkillId] || store.skills.elemAttune || 0;
const tierMult = getTierMultiplier(tieredSkillId);
return 10 + level * 50 * tierMult + (store.prestigeUpgrades.elementalAttune || 0) * 25;
})();
// Get all selected skill upgrades
const getAllSelectedUpgrades = () => {
const upgrades: { skillId: string; upgrade: SkillUpgradeChoice }[] = [];
for (const [skillId, selectedIds] of Object.entries(store.skillUpgrades)) {
const baseSkillId = skillId.includes('_t') ? skillId.split('_t')[0] : skillId;
const path = SKILL_EVOLUTION_PATHS[baseSkillId];
if (!path) continue;
for (const tier of path.tiers) {
if (tier.skillId === skillId) {
for (const upgradeId of selectedIds) {
const upgrade = tier.upgrades.find(u => u.id === upgradeId);
if (upgrade) {
upgrades.push({ skillId, upgrade });
}
}
}
}
}
return upgrades;
};
const selectedUpgrades = getAllSelectedUpgrades();
return (
{/* Mana Stats */}
Mana Stats
Base Max Mana:
100
Mana Well Bonus:
{(() => {
const mw = store.skillTiers?.manaWell || 1;
const tieredSkillId = mw > 1 ? `manaWell_t${mw}` : 'manaWell';
const level = store.skills[tieredSkillId] || store.skills.manaWell || 0;
const tierMult = getTierMultiplier(tieredSkillId);
return `+${fmt(level * 100 * tierMult)} (${level} lvl × 100 × ${tierMult}x tier)`;
})()}
Prestige Mana Well:
+{fmt((store.prestigeUpgrades.manaWell || 0) * 500)}
{upgradeEffects.maxManaBonus > 0 && (
Upgrade Mana Bonus:
+{fmt(upgradeEffects.maxManaBonus)}
)}
{upgradeEffects.maxManaMultiplier > 1 && (
Upgrade Mana Multiplier:
×{fmtDec(upgradeEffects.maxManaMultiplier, 2)}
)}
Total Max Mana:
{fmt(maxMana)}
Base Regen:
2/hr
Mana Flow Bonus:
{(() => {
const mf = store.skillTiers?.manaFlow || 1;
const tieredSkillId = mf > 1 ? `manaFlow_t${mf}` : 'manaFlow';
const level = store.skills[tieredSkillId] || store.skills.manaFlow || 0;
const tierMult = getTierMultiplier(tieredSkillId);
return `+${fmtDec(level * 1 * tierMult)}/hr (${level} lvl × 1 × ${tierMult}x tier)`;
})()}
Mana Spring Bonus:
+{(store.skills.manaSpring || 0) * 2}/hr
Prestige Mana Flow:
+{fmtDec((store.prestigeUpgrades.manaFlow || 0) * 0.5)}/hr
Temporal Echo:
×{fmtDec(1 + (store.prestigeUpgrades.temporalEcho || 0) * 0.1, 2)}
Base Regen:
{fmtDec(baseRegen, 2)}/hr
{upgradeEffects.regenBonus > 0 && (
Upgrade Regen Bonus:
+{fmtDec(upgradeEffects.regenBonus, 2)}/hr
)}
{upgradeEffects.permanentRegenBonus > 0 && (
Permanent Regen Bonus:
+{fmtDec(upgradeEffects.permanentRegenBonus, 2)}/hr
)}
{upgradeEffects.regenMultiplier > 1 && (
Upgrade Regen Multiplier:
×{fmtDec(upgradeEffects.regenMultiplier, 2)}
)}
{/* Skill Upgrade Effects Summary */}
{upgradeEffects.activeUpgrades.length > 0 && (
<>
Active Skill Upgrades
{upgradeEffects.activeUpgrades.map((upgrade, idx) => (
{upgrade.name}
{upgrade.desc}
))}
>
)}
Click Mana Value:
+{clickMana}
Mana Tap Bonus:
+{store.skills.manaTap || 0}
Mana Surge Bonus:
+{(store.skills.manaSurge || 0) * 3}
Mana Overflow:
×{fmtDec(1 + (store.skills.manaOverflow || 0) * 0.25, 2)}
Meditation Multiplier:
1.5 ? 'text-purple-400' : 'text-gray-300'}`}>
{fmtDec(meditationMultiplier, 2)}x
Effective Regen:
{fmtDec(effectiveRegen, 2)}/hr
{incursionStrength > 0 && !hasSteadyStream && (
Incursion Penalty:
-{Math.round(incursionStrength * 100)}%
)}
{hasSteadyStream && incursionStrength > 0 && (
Steady Stream:
Immune to incursion
)}
{manaCascadeBonus > 0 && (
Mana Cascade Bonus:
+{fmtDec(manaCascadeBonus, 2)}/hr
)}
{hasManaTorrent && store.rawMana > maxMana * 0.75 && (
Mana Torrent:
+50% regen (high mana)
)}
{hasDesperateWells && store.rawMana < maxMana * 0.25 && (
Desperate Wells:
+50% regen (low mana)
)}
{/* Combat Stats */}
Combat Stats
Active Spell Base Damage:
{activeSpellDef?.dmg || 5}
Combat Training Bonus:
+{(store.skills.combatTrain || 0) * 5}
Arcane Fury Multiplier:
×{fmtDec(1 + (store.skills.arcaneFury || 0) * 0.1, 2)}
Elemental Mastery:
×{fmtDec(1 + (store.skills.elementalMastery || 0) * 0.15, 2)}
Guardian Bane:
×{fmtDec(1 + (store.skills.guardianBane || 0) * 0.2, 2)} (vs guardians)
Critical Hit Chance:
{((store.skills.precision || 0) * 5)}%
Critical Multiplier:
1.5x
Spell Echo Chance:
{((store.skills.spellEcho || 0) * 10)}%
Pact Multiplier:
×{fmtDec(pactMultiplier, 2)}
Total Damage:
{fmt(calcDamage(store, store.activeSpell))}
{/* Pact Status */}
Pact Status
Pact Slots:
{store.signedPacts.length} / {1 + (store.prestigeUpgrades.pactCapacity || 0)}
Damage Multiplier:
×{fmtDec(pactMultiplier, 2)}
Insight Multiplier:
×{fmtDec(pactInsightMultiplier, 2)}
{store.signedPacts.length > 1 && (
<>
Interference Mitigation:
{Math.min(store.pactInterferenceMitigation || 0, 5) * 10}%
{(store.pactInterferenceMitigation || 0) >= 5 && (
Synergy Bonus:
+{((store.pactInterferenceMitigation || 0) - 5) * 10}%
)}
>
)}
Unlocked Mana Types:
{Object.entries(store.elements)
.filter(([, state]) => state.unlocked)
.map(([id]) => {
const elem = ELEMENTS[id];
return (
{elem?.sym} {elem?.name}
);
})}
{/* Study Stats */}
Study Stats
Study Speed:
×{fmtDec(studySpeedMult, 2)}
Quick Learner Bonus:
+{((store.skills.quickLearner || 0) * 10)}%
Study Cost:
{Math.round(studyCostMult * 100)}%
Focused Mind Bonus:
-{((store.skills.focusedMind || 0) * 5)}%
Progress Retention:
{Math.round((1 + (store.skills.knowledgeRetention || 0) * 0.2) * 100)}%
{/* Element Stats */}
Element Stats
Element Capacity:
{elemMax}
Elem. Attunement Bonus:
{(() => {
const ea = store.skillTiers?.elemAttune || 1;
const tieredSkillId = ea > 1 ? `elemAttune_t${ea}` : 'elemAttune';
const level = store.skills[tieredSkillId] || store.skills.elemAttune || 0;
const tierMult = getTierMultiplier(tieredSkillId);
return `+${level * 50 * tierMult}`;
})()}
Prestige Attunement:
+{(store.prestigeUpgrades.elementalAttune || 0) * 25}
Unlocked Elements:
{Object.values(store.elements).filter(e => e.unlocked).length} / {Object.keys(ELEMENTS).length}
Elem. Crafting Bonus:
×{fmtDec(1 + (store.skills.elemCrafting || 0) * 0.25, 2)}
Elemental Mana Pools:
{Object.entries(store.elements)
.filter(([, state]) => state.unlocked)
.map(([id, state]) => {
const def = ELEMENTS[id];
return (
{def?.sym}
{state.current}/{state.max}
);
})}
{/* Active Upgrades */}
Active Skill Upgrades ({selectedUpgrades.length})
{selectedUpgrades.length === 0 ? (
No skill upgrades selected yet. Level skills to 5 or 10 to choose upgrades.
) : (
{selectedUpgrades.map(({ skillId, upgrade }) => (
{upgrade.name}
{SKILLS_DEF[skillId]?.name || skillId}
{upgrade.desc}
{upgrade.effect.type === 'multiplier' && (
+{Math.round((upgrade.effect.value! - 1) * 100)}% {upgrade.effect.stat}
)}
{upgrade.effect.type === 'bonus' && (
+{upgrade.effect.value} {upgrade.effect.stat}
)}
{upgrade.effect.type === 'special' && (
⚡ {upgrade.effect.specialDesc || 'Special effect active'}
)}
))}
)}
{/* Loop Stats */}
Loop Stats
{store.loopCount}
Loops Completed
{fmt(store.insight)}
Current Insight
{fmt(store.totalInsight)}
Total Insight
{store.maxFloorReached}
Max Floor
{Object.values(store.spells).filter(s => s.learned).length}
Spells Learned
{Object.values(store.skills).reduce((a, b) => a + b, 0)}
Total Skill Levels
{fmt(store.totalManaGathered)}
Total Mana Gathered
{store.memorySlots}
Memory Slots
);
}