import { afterEach, describe, expect, it } from "vitest";
import { createDefaultHealerAppearance } from "../game/healerVisuals";
import { hasPendingSaveSync } from "./saveSync";
import { getFrontendSnapshot, useFrontendStore } from "./store";

const originalState = useFrontendStore.getState();

afterEach(() => {
  useFrontendStore.getState().deleteSlot(3);
  useFrontendStore.setState({
    activeSlotId: originalState.activeSlotId,
    selectedSlotId: originalState.selectedSlotId,
    screen: originalState.screen,
    appearanceClassId: originalState.appearanceClassId,
    appearanceDrafts: structuredClone(originalState.appearanceDrafts),
    previewMode: originalState.previewMode,
    previewAnimation: originalState.previewAnimation,
    notice: originalState.notice,
  });
});

describe("Appearance Lab frontend state", () => {
  it("opens from saved looks, previews drafts, saves explicitly, and cancels unsaved edits", () => {
    const frontend = useFrontendStore.getState();
    frontend.deleteSlot(3);
    expect(frontend.createSlot(3, "Wardrobe Tester")).toBe(true);
    frontend.playSlot(3);

    useFrontendStore.getState().openAppearanceLab();
    let state = useFrontendStore.getState();
    const savedPriest = state.slots[2].local!.healers.priest.appearance;
    expect(state.screen).toBe("appearance");
    expect(state.appearanceClassId).toBe("priest");
    expect(state.appearanceDrafts.priest).toEqual(savedPriest);
    expect(state.appearanceDrafts.priest).not.toBe(savedPriest);
    expect(state.previewMode).toBe("modular");
    expect(state.previewAnimation).toBe("idle");

    const mixedPriest = {
      ...state.appearanceDrafts.priest,
      headPartId: "rogue-head" as const,
    };
    state.updateAppearanceDraft(mixedPriest);
    state.setAppearancePreviewMode("legacy");
    state.setAppearancePreviewAnimation("cast");
    state = useFrontendStore.getState();
    expect(state.appearanceDrafts.priest.headPartId).toBe("rogue-head");
    expect(state.slots[2].local!.healers.priest.appearance.headPartId).toBe(
      createDefaultHealerAppearance("priest").headPartId,
    );
    expect(state.previewMode).toBe("legacy");
    expect(state.previewAnimation).toBe("cast");

    expect(state.saveAppearanceDraft()).toBe(true);
    state = useFrontendStore.getState();
    expect(state.slots[2].local!.healers.priest.appearance.headPartId).toBe("rogue-head");
    expect(hasPendingSaveSync(3)).toBe(true);

    state.updateAppearanceDraft({
      ...state.appearanceDrafts.priest,
      headPartId: "ranger-head",
    });
    useFrontendStore.getState().closeAppearanceLab();
    state = useFrontendStore.getState();
    expect(state.screen).toBe("home");
    expect(state.appearanceDrafts.priest.headPartId).toBe("rogue-head");
    expect(state.slots[2].local!.healers.priest.appearance.headPartId).toBe("rogue-head");
  });

  it("resets only the selected class and includes state but no actions in snapshots", () => {
    useFrontendStore.setState((state) => ({
      appearanceClassId: "paladin",
      appearanceDrafts: {
        ...state.appearanceDrafts,
        paladin: { ...state.appearanceDrafts.paladin, headPartId: "rogue-head" },
      },
      previewMode: "legacy",
      previewAnimation: "walk",
    }));

    useFrontendStore.getState().resetAppearanceDraft();
    const snapshot = getFrontendSnapshot();
    expect(snapshot.appearanceClassId).toBe("paladin");
    expect(snapshot.appearanceDrafts.paladin).toEqual(createDefaultHealerAppearance("paladin"));
    expect(snapshot.previewMode).toBe("legacy");
    expect(snapshot.previewAnimation).toBe("walk");
    expect("openAppearanceLab" in snapshot).toBe(false);
    expect("updateAppearanceDraft" in snapshot).toBe(false);
    expect("saveAppearanceDraft" in snapshot).toBe(false);
    expect("setAppearancePreviewAnimation" in snapshot).toBe(false);
  });
});
