import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it } from "vitest";

import {
  PrivateAlbumSchema,
  type PrivateAlbum,
  type PrivateAlbumInput,
} from "@/data/schemas/private-zone";

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

const COVER_URL = "/images/private-zone/banner/elio.png";

function makeAlbum(overrides: Partial<PrivateAlbumInput> = {}): PrivateAlbum {
  return PrivateAlbumSchema.parse({
    albumId: "album-1",
    title: "Private morning",
    content: "A quiet morning by the water.",
    previewText: "Only for you.",
    imageCount: 8,
    images: [],
    locked: false,
    unlocked: true,
    unlockCost: 320,
    publishedAt: "2026-07-01T08:11:35+00:00",
    lockDetail: { locked: false },
    ...overrides,
  });
}

function renderCard(album: PrivateAlbum): string {
  return renderToStaticMarkup(
    <PrivateAlbumCard
      album={album}
      displayName="Elio Silvestri"
      avatarUrl="/images/avatar/elio.png"
      index={0}
      isUnlocking={false}
      onOpenGallery={() => undefined}
      onUnlock={() => undefined}
    />,
  );
}

describe("PrivateAlbumCard", () => {
  it("renders every available unlocked image in the adaptive grid", () => {
    const html = renderCard(
      makeAlbum({
        imageCount: 2,
        images: [
          { url: COVER_URL, locked: false, index: 0 },
          {
            url: "/images/cover/elio.png",
            locked: false,
            index: 1,
          },
        ],
      }),
    );

    expect(html).toContain("elio.png");
    expect(html).toContain("%2Fimages%2Fcover%2Felio.png");
    expect(html).toContain('data-grid-layout="double"');
    expect(html).toContain('data-image-index="0"');
    expect(html).toContain('data-image-index="1"');
    expect(html).toContain("A quiet morning by the water.");
    expect(html).toContain(
      'aria-label="Open photo 2 of 2 from Elio Silvestri"',
    );
    expect(html).toContain('data-analytics-key="private_album.open_gallery"');
  });

  it.each([
    { count: 1, layout: "single" },
    { count: 2, layout: "double" },
    { count: 3, layout: "triple" },
    { count: 4, layout: "double" },
    { count: 5, layout: "triple" },
    { count: 9, layout: "triple" },
  ])("uses the $layout layout for $count images", ({ count, layout }) => {
    const html = renderCard(
      makeAlbum({
        imageCount: count,
        images: makeImages(count),
      }),
    );

    expect(html).toContain(`data-grid-layout="${layout}"`);
  });

  it("limits the preview to nine images and shows the remaining count", () => {
    const html = renderCard(
      makeAlbum({
        imageCount: 12,
        images: makeImages(12),
      }),
    );

    expect(html.match(/data-image-index=/g)).toHaveLength(9);
    expect(html).toContain("+3");
    expect(html).not.toContain('data-image-index="9"');
  });

  it("renders the reference-style locked collection over the first image", () => {
    const html = renderCard(
      makeAlbum({
        content: null,
        locked: true,
        unlocked: false,
        lockDetail: { locked: true },
        images: [{ url: COVER_URL, locked: true, index: 0 }],
      }),
    );

    expect(html).toContain("elio.png");
    expect(html).toContain(
      'aria-label="Elio Silvestri locked collection"',
    );
    expect(html).toContain("lucide-copy");
    expect(html).toContain("lucide-lock-keyhole");
    expect(html).toContain("Unlock to view");
    expect(html).toContain("8 Images");
    expect(html).toContain("View collection");
    expect(html).toContain(
      'aria-label="View locked collection with 8 images from Elio Silvestri"',
    );
    expect(html).not.toContain("Only for you.");
    expect(html).not.toContain("320 credits");
    expect(html).not.toContain("Videos");
    expect(html).toContain('data-analytics-key="private_album.unlock"');
  });

  it("uses singular image copy and works without a cover", () => {
    const html = renderCard(
      makeAlbum({
        imageCount: 0,
        locked: true,
        unlocked: false,
        lockDetail: { locked: true },
        images: [{ url: "", locked: true, index: 0 }],
      }),
    );

    expect(html).toContain("1 Image");
    expect(html).not.toContain("1 Images");
    expect(html.match(/<img/g)).toHaveLength(2);
    expect(html).toContain("View collection");
  });

  it("renders an empty cover when an unlocked album has no image", () => {
    const html = renderCard(makeAlbum());

    expect(html).toContain('aria-label="No private album photo available"');
    expect(html).toContain("No photo available");
  });
});

function makeImages(count: number) {
  return Array.from({ length: count }, (_, index) => ({
    url: `/images/private-zone/photo-${index}.png`,
    locked: false,
    index,
  }));
}
