import { fireEvent, render, screen } from "@testing-library/react";
import { BlockActionOverride } from "../../../BlockAction";
import { Expander } from "../../../Expander";
import { SelectionTile } from "..";

describe("SelectionTile", () => {
  it("renders a radio with an associated label", () => {
    render(
      <SelectionTile type="radio" id="choice-a" name="choices" label="Choice A">
        <p>Additional content</p>
      </SelectionTile>,
    );

    expect(screen.getByRole("radio", { name: "Choice A" })).toBeInTheDocument();
    expect(screen.getByText("Additional content")).toBeInTheDocument();
    expect(screen.getByRole("radio")).toHaveClass("radiocheck--fill");
    expect(
      screen.getByText("Additional content").closest(".block-action"),
    ).toHaveClass("block-action");
  });

  it("renders a checkbox and preserves native interaction", () => {
    render(<SelectionTile type="checkbox" id="choice-b" label="Choice B" />);
    const checkbox = screen.getByRole("checkbox", { name: "Choice B" });

    expect(checkbox).not.toBeChecked();
    fireEvent.click(checkbox);
    expect(checkbox).toBeChecked();
  });

  it("renders a disabled native checkbox", () => {
    render(
      <SelectionTile
        type="checkbox"
        id="choice-disabled"
        label="Unavailable choice"
        isDisabled
      />,
    );

    expect(screen.getByRole("checkbox")).toBeDisabled();
  });

  it("selects the option through its tile label", () => {
    render(
      <SelectionTile type="checkbox" id="choice-label" label="Choice label">
        <p>Tile content</p>
      </SelectionTile>,
    );
    const checkbox = screen.getByRole("checkbox", { name: "Choice label" });

    fireEvent.click(screen.getByText("Choice label"));

    expect(checkbox).toBeChecked();
  });

  it("renders optional predefined slots and arbitrary children", () => {
    render(
      <SelectionTile
        type="checkbox"
        id="choice-slots"
        inputProps={{ "aria-label": "Slot choice" }}
        price="€9.99"
        message="Feedback"
      >
        <span>Custom content</span>
        <span>More details</span>
      </SelectionTile>,
    );

    expect(
      screen.getByRole("checkbox", { name: "Slot choice" }),
    ).toBeInTheDocument();
    expect(screen.getByRole("checkbox")).toHaveAttribute(
      "aria-describedby",
      "choice-slots-message",
    );
    expect(screen.getByText("€9.99")).toHaveClass(
      "caption",
      "text-accent",
      "bold",
    );
    expect(screen.getByText("Feedback")).toHaveClass("selection-tile__message");
    expect(screen.getByText("Custom content")).toBeInTheDocument();
    expect(screen.getByText("More details")).toBeInTheDocument();
  });

  it("marks error status invalid and warning status advisory", () => {
    const { rerender } = render(
      <SelectionTile
        type="radio"
        id="choice-c"
        name="choices"
        label="Choice C"
        status="error"
      />,
    );
    expect(screen.getByRole("radio")).toHaveAttribute("aria-invalid", "true");

    rerender(
      <SelectionTile
        type="radio"
        id="choice-c"
        name="choices"
        label="Choice C"
        status="warning"
      />,
    );
    expect(screen.getByRole("radio")).not.toHaveAttribute("aria-invalid");
  });

  it("forwards explicit description relationships to the native input", () => {
    render(
      <SelectionTile
        type="checkbox"
        id="choice-message"
        label="Choice with feedback"
        inputProps={{ "aria-describedby": "choice-message-feedback" }}
        message={<p id="choice-message-feedback">Additional feedback</p>}
      />,
    );

    expect(screen.getByRole("checkbox")).toHaveAttribute(
      "aria-describedby",
      "choice-message-feedback",
    );
  });

  it("keeps an Expander in the override layer", () => {
    render(
      <SelectionTile type="checkbox" id="choice-d" label="Choice D">
        <BlockActionOverride>
          <Expander summary="Detail">Details</Expander>
        </BlockActionOverride>
      </SelectionTile>,
    );

    const checkbox = screen.getByRole("checkbox");
    const summary = screen.getByText("Detail");

    expect(summary.closest(".block-action__override")).toBeInTheDocument();
    fireEvent.click(summary);

    expect(checkbox).not.toBeChecked();
  });
});
