import { describe, it, expect } from "vitest";
import { Hono } from "hono";
import { ErrorDisplay } from "../error-display.js";
import { EmptyState } from "../empty-state.js";
import { LoadingState } from "../loading-state.js";

describe("ErrorDisplay", () => {
  it("renders message with error-display class", async () => {
    const app = new Hono().get("/", (c) =>
      c.html(<ErrorDisplay message="Something went wrong" />)
    );
    const res = await app.request("/");
    const html = await res.text();
    expect(html).toContain('class="error-display"');
    expect(html).toContain("Something went wrong");
  });

  it("renders detail when provided", async () => {
    const app = new Hono().get("/", (c) =>
      c.html(<ErrorDisplay message="Error" detail="Extra context" />)
    );
    const res = await app.request("/");
    const html = await res.text();
    expect(html).toContain("Extra context");
  });

  it("omits detail element when not provided", async () => {
    const app = new Hono().get("/", (c) =>
      c.html(<ErrorDisplay message="Error" />)
    );
    const res = await app.request("/");
    const html = await res.text();
    expect(html).not.toMatch(/<p[^>]*class="error-display__detail"[^>]*>/);
  });
});

describe("EmptyState", () => {
  it("renders message with empty-state class", async () => {
    const app = new Hono().get("/", (c) =>
      c.html(<EmptyState message="No topics yet" />)
    );
    const res = await app.request("/");
    const html = await res.text();
    expect(html).toContain('class="empty-state"');
    expect(html).toContain("No topics yet");
  });

  it("renders action when provided", async () => {
    const app = new Hono().get("/", (c) =>
      c.html(
        <EmptyState message="Empty" action={<a href="/new">Create one</a>} />
      )
    );
    const res = await app.request("/");
    const html = await res.text();
    expect(html).toContain('class="empty-state__action"');
    expect(html).toContain("Create one");
  });

  it("omits action element when not provided", async () => {
    const app = new Hono().get("/", (c) =>
      c.html(<EmptyState message="Empty" />)
    );
    const res = await app.request("/");
    const html = await res.text();
    expect(html).not.toContain('class="empty-state__action"');
  });
});

describe("LoadingState", () => {
  it("renders with htmx-indicator class", async () => {
    const app = new Hono().get("/", (c) => c.html(<LoadingState />));
    const res = await app.request("/");
    const html = await res.text();
    expect(html).toContain("htmx-indicator");
  });

  it("renders default loading message", async () => {
    const app = new Hono().get("/", (c) => c.html(<LoadingState />));
    const res = await app.request("/");
    const html = await res.text();
    expect(html).toContain("Loading");
  });

  it("renders custom message when provided", async () => {
    const app = new Hono().get("/", (c) =>
      c.html(<LoadingState message="Fetching posts…" />)
    );
    const res = await app.request("/");
    const html = await res.text();
    expect(html).toContain("Fetching posts");
  });
});
