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

// PairLive uses these client-only modules. Stub them so the component
// can be rendered server-side for assertion. The default state on first
// render is `phase: "waiting"` — exactly the case we want to verify here.
vi.mock("next/navigation", () => ({
  useRouter: () => ({ push: vi.fn() }),
}));
vi.mock("next/link", () => ({
  default: ({ href, children, ...rest }: { href: string; children: ReactNode } & Record<string, unknown>) => (
    <a href={href} {...rest}>
      {children}
    </a>
  ),
}));
// useEvents subscribes to the SSE stream; on the server-render side we
// just want it to no-op so the component stays in its initial state.
vi.mock("@/hooks/use-events", () => ({
  useEvents: () => {},
}));

import { PairLive } from "./pair-live";

describe("PairLive — initial 'waiting' state shows a spinner placeholder", () => {
  it("renders an aria-live spinner block before any QR arrives", () => {
    const html = renderToStaticMarkup(
      <PairLive accountId="acc-1" label="Personal" />,
    );

    // The placeholder is a labelled, aria-live region so screen readers
    // announce it as soon as it appears.
    expect(html).toMatch(/data-testid="pair-loading"/);
    expect(html).toMatch(/role="status"/);
    expect(html).toMatch(/aria-live="polite"/);
    expect(html).toMatch(/aria-label="Generating QR code"/);
  });

  it("uses an animated spinner icon (lucide Loader2)", () => {
    const html = renderToStaticMarkup(
      <PairLive accountId="acc-1" label="Personal" />,
    );
    // Lucide tags every icon with a stable `lucide-<name>` class.
    expect(html).toMatch(/lucide-loader-?2|lucide-loader/);
    // The animation hook (Tailwind's animate-spin) must be applied so
    // the spinner actually rotates.
    expect(html).toContain("animate-spin");
  });

  it("shows the 'Generating QR…' helper text", () => {
    const html = renderToStaticMarkup(
      <PairLive accountId="acc-1" label="Personal" />,
    );
    expect(html).toContain("Generating QR…");
  });

  it("does NOT yet render the QR image, countdown bar, or Save QR button", () => {
    const html = renderToStaticMarkup(
      <PairLive accountId="acc-1" label="Personal" />,
    );
    // No <img> for the QR.
    expect(html).not.toMatch(/<img[^>]+alt="WhatsApp QR code"/);
    // No "QR expires" / "Pairing expires" countdown copy.
    expect(html).not.toContain("Pairing expires");
    // No download CTA.
    expect(html).not.toContain("Save QR");
  });

  it("placeholder occupies the same 64x64 footprint as the eventual QR", () => {
    // Avoids a layout jump when the QR finally lands. Both the spinner
    // tile and the rendered QR use Tailwind's `size-64` (16rem).
    const html = renderToStaticMarkup(
      <PairLive accountId="acc-1" label="Personal" />,
    );
    expect(html).toMatch(/class="[^"]*\bsize-64\b/);
  });
});
