import { useEffect, useRef, useState } from "react";
import { useShellStore } from "../app/shellStore";
import { BOSS_TESTING_STATUSES, BOSS_TESTING_STATUS_LABELS, useBossTestingReviews, type BossTestingStatus } from "../app/bossTestingReviews";
import { bossTestIsDefeated } from "../game/BossTestingBridge";
import { enterBossTesting, prepareBossTesting } from "../app/bossTestingRuntime";
import { anotherRandomTestingBoss, BOSS_TESTING_CATALOG } from "../game/bossTesting";
import { useGameStore } from "../game/store";
import { useMenuController, type MenuAction } from "../input/useMenuController";
import { ControllerButton } from "./ControllerButton";
import "./bossTesting.css";
export function BossTestingReviewPanel() {
const boss = useGameStore((state) => state.bossTest);
const session = useShellStore((state) => state.session);
const review = useBossTestingReviews((state) => boss ? state.reviews[boss.key] : undefined);
const save = useBossTestingReviews((state) => state.save);
const refresh = useBossTestingReviews((state) => state.refresh);
const [saving, setSaving] = useState(false);
const [startingRandom, setStartingRandom] = useState(false);
const [message, setMessage] = useState("");
const busy = useRef(false);
const mark = async (status: BossTestingStatus) => {
if (!boss || busy.current) return;
busy.current = true; setSaving(true); setMessage("");
const synced = await save(boss, status, session);
setMessage(synced ? `Marked ${BOSS_TESTING_STATUS_LABELS[status].toLowerCase()}.` : "Saved on this device. This label will sync when you reconnect or reopen Boss Testing.");
busy.current = false; setSaving(false);
};
useEffect(() => {
void refresh(session);
const reconnect = () => void refresh(session);
window.addEventListener("online", reconnect);
return () => window.removeEventListener("online", reconnect);
}, [refresh, session]);
const defeated = bossTestIsDefeated();
const disabled = saving || startingRandom;
const back = () => { if (!busy.current) useGameStore.getState().openOverlay("pause"); };
const retry = () => useGameStore.getState().resetAtEntrance();
const leave = () => useShellStore.getState().returnToMainMenu();
const fightRandom = async () => {
if (busy.current || !boss) return;
const next = anotherRandomTestingBoss(BOSS_TESTING_CATALOG, boss.key);
if (!next) { setMessage("No other bosses are available."); return; }
busy.current = true; setStartingRandom(true); setMessage(`Preparing ${next.name}…`);
try {
await prepareBossTesting(next);
enterBossTesting(next, useShellStore.getState().activeDungeonRole ?? undefined);
} catch (failure) {
setMessage(failure instanceof Error ? failure.message : "The next boss could not be started. Please retry.");
} finally {
busy.current = false; setStartingRandom(false);
}
};
const actions: MenuAction[] = [
...BOSS_TESTING_STATUSES.map((status) => ({ id: `boss-review-${status}`, run: () => void mark(status), enabled: !disabled })),
{ id: "boss-review-report", run: () => useGameStore.getState().openOverlay("report-issue"), enabled: !disabled },
{ id: "boss-review-retry", run: retry, enabled: !disabled },
{ id: "boss-review-random", run: () => void fightRandom(), enabled: !disabled },
{ id: "boss-review-leave", run: leave, enabled: !disabled },
{ id: "boss-review-back", run: back, enabled: !disabled },
];
const controller = useMenuController(actions, { initialId: "boss-review-needs-testing", onBack: back });
if (!boss) return null;
const button = (controlId: string, label: string, run: () => void, pressed?: boolean) =>
{defeated ? "Boss defeated" : "Boss Testing paused"}
Current readiness: {BOSS_TESTING_STATUS_LABELS[review?.status ?? "needs-testing"]}
{message}
}