/* @vitest-environment jsdom */

import { act } from "react";
import { createRoot, type Root } from "react-dom/client";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

import { PrivateAlbumSchema } from "@/data/schemas/private-zoom";

import { PrivateAlbumCard } from "../private-album-card";

describe("PrivateAlbumCard interactions", () => {
  let container: HTMLDivElement;
  let root: Root;

  beforeEach(() => {
    (globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean })
      .IS_REACT_ACT_ENVIRONMENT = true;
    container = document.createElement("div");
    document.body.append(container);
    root = createRoot(container);
  });

  afterEach(() => {
    act(() => root.unmount());
    container.remove();
  });

  it("opens the selected thumbnail with its original source index", () => {
    const onOpenGallery = vi.fn();
    const album = PrivateAlbumSchema.parse({
      albumId: "album-1",
      title: "Private afternoon",
      imageCount: 4,
      images: [
        { url: "", locked: false, index: 0 },
        { url: "/images/private-zoom/locked.png", locked: true, index: 1 },
        { url: "/images/private-zoom/photo-2.png", locked: false, index: 2 },
        { url: "/images/private-zoom/photo-3.png", locked: false, index: 3 },
      ],
      locked: false,
      unlocked: true,
      lockDetail: { locked: false },
    });

    act(() => {
      root.render(
        <PrivateAlbumCard
          album={album}
          displayName="Elio Silvestri"
          avatarUrl="/images/avatar/elio.png"
          index={0}
          isUnlocking={false}
          onOpenGallery={onOpenGallery}
          onUnlock={() => undefined}
        />,
      );
    });

    const thumbnail = container.querySelector<HTMLButtonElement>(
      'button[data-image-index="3"]',
    );
    act(() => thumbnail?.click());

    expect(onOpenGallery).toHaveBeenCalledOnce();
    expect(onOpenGallery).toHaveBeenCalledWith(3);
  });

  it("unlocks only from the collection CTA and disables repeat actions", () => {
    const onUnlock = vi.fn();
    const album = PrivateAlbumSchema.parse({
      albumId: "album-locked",
      title: "Locked afternoon",
      imageCount: 3,
      images: [
        { url: "/images/private-zoom/locked.png", locked: true, index: 0 },
      ],
      locked: true,
      unlocked: false,
      unlockCost: 40,
      lockDetail: { locked: true },
    });

    renderLockedCard(album, false, onUnlock);
    const avatar = container.querySelector<HTMLElement>(
      '[aria-label="Elio Silvestri locked collection"]',
    );
    act(() => avatar?.parentElement?.click());
    expect(onUnlock).not.toHaveBeenCalled();

    const button = findCollectionButton();
    act(() => button.click());
    expect(onUnlock).toHaveBeenCalledOnce();

    renderLockedCard(album, true, onUnlock);
    const disabledButton = findCollectionButton();
    expect(disabledButton.disabled).toBe(true);
    expect(disabledButton.textContent).toBe("Opening...");
    act(() => disabledButton.click());
    expect(onUnlock).toHaveBeenCalledOnce();
  });

  function renderLockedCard(
    album: ReturnType<typeof PrivateAlbumSchema.parse>,
    isUnlocking: boolean,
    onUnlock: () => void,
  ): void {
    act(() => {
      root.render(
        <PrivateAlbumCard
          album={album}
          displayName="Elio Silvestri"
          avatarUrl="/images/avatar/elio.png"
          index={0}
          isUnlocking={isUnlocking}
          onOpenGallery={() => undefined}
          onUnlock={onUnlock}
        />,
      );
    });
  }

  function findCollectionButton(): HTMLButtonElement {
    const button = Array.from(container.querySelectorAll("button")).find(
      (item) =>
        item.textContent === "View collection" ||
        item.textContent === "Opening...",
    );
    if (!button) throw new Error("Missing View collection button");
    return button;
  }
});
