import { render, screen } from "@testing-library/react";
import { describe, it, expect } from "vitest";
import { StatusBadge, MappedStatusBadge } from "./StatusBadge";
import React from "react";

describe("StatusBadge", () => {
  it("renders the children", () => {
    render(<StatusBadge>Paid</StatusBadge>);
    expect(screen.getByText("Paid")).toBeDefined();
  });

  it("renders a dot when dotClassName is provided", () => {
    const { container } = render(
      <StatusBadge dotClassName="bg-green-500">Paid</StatusBadge>
    );
    const dot = container.querySelector(".bg-green-500");
    expect(dot).toBeInTheDocument();
    expect(dot?.classList.contains("h-2")).toBe(true);
    expect(dot?.classList.contains("w-2")).toBe(true);
    expect(dot?.classList.contains("rounded-full")).toBe(true);
  });

  it("applies custom className to the badge", () => {
    render(<StatusBadge className="custom-class">Paid</StatusBadge>);
    const badge = screen.getByText("Paid");
    expect(badge.classList.contains("custom-class")).toBe(true);
  });

  describe("Status Variants", () => {
    const statusVariants = [
      { status: "success", expectedClass: "bg-green-500" },
      { status: "warning", expectedClass: "bg-yellow-500" },
      { status: "error", expectedClass: "bg-red-500" },
      { status: "info", expectedClass: "bg-blue-500" },
      { status: "default", expectedClass: "bg-gray-500" },
    ] as const;

    statusVariants.forEach(({ status, expectedClass }) => {
      it(`renders correctly for status: ${status}`, () => {
        const { container } = render(
          <StatusBadge status={status}>{status}</StatusBadge>
        );

        // Check for the dot with correct color
        const dot = container.querySelector(`.${expectedClass}`);
        expect(dot).toBeInTheDocument();
        expect(dot?.getAttribute("aria-hidden")).toBe("true");

        // Check if the badge has some status-specific class (e.g., background opacity)
        const badge = screen.getByText(status);
        expect(badge.className).toContain("bg-opacity-50");
      });
    });
  });

  it("renders with both status and custom dotClassName", () => {
    const { container } = render(
      <StatusBadge status="success" dotClassName="custom-dot">Success</StatusBadge>
    );
    const dot = container.querySelector(".custom-dot");
    expect(dot).toBeInTheDocument();
    expect(dot?.classList.contains("bg-green-500")).toBe(true);
  });

  it("does not render a dot when no status or dotClassName is provided", () => {
    const { container } = render(<StatusBadge>No Dot</StatusBadge>);
    // The dot is rendered as a span inside the Badge (which is a div/span depending on implementation)
    // We check for the absence of the aria-hidden span which represents the dot
    const dot = container.querySelector("span[aria-hidden='true']");
    expect(dot).toBeNull();
  });
});

describe("MappedStatusBadge", () => {
  const testMapping = {
    active: { label: "Aktiv", status: "success" as const },
    inactive: { label: "Inaktiv", status: "error" as const },
  };

  it("renders correctly for a mapped value", () => {
    render(<MappedStatusBadge status="active" mapping={testMapping} />);
    expect(screen.getByText("Aktiv")).toBeDefined();
  });

  it("renders correctly for another mapped value", () => {
    render(<MappedStatusBadge status="inactive" mapping={testMapping} />);
    expect(screen.getByText("Inaktiv")).toBeDefined();
  });

  it("uses status as label for unmapped values", () => {
    render(<MappedStatusBadge status="pending" mapping={testMapping} />);
    expect(screen.getByText("pending")).toBeDefined();
  });

  it("uses fallbackLabel for empty status", () => {
    render(
      <MappedStatusBadge
        status=""
        mapping={testMapping}
        fallbackLabel="Kein Status"
      />
    );
    expect(screen.getByText("Kein Status")).toBeDefined();
  });

  it("uses default fallbackLabel if none provided", () => {
    render(<MappedStatusBadge status="" mapping={testMapping} />);
    expect(screen.getByText("Unbekannt")).toBeDefined();
  });
});
