import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { describe, it, expect, vi } from "vitest";
import { QuantityInput } from "@/components/ui/quantity-input";

// Mock Radix Tooltip to render content immediately for easier testing in JSDOM
vi.mock("@/components/ui/tooltip", () => ({
  Tooltip: ({ children }: { children: React.ReactNode }) => <>{children}</>,
  TooltipTrigger: ({ children }: { children: React.ReactNode }) => <>{children}</>,
  TooltipContent: ({ children }: { children: React.ReactNode }) => (
    <div role="tooltip">{children}</div>
  ),
  TooltipProvider: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

describe("QuantityInput", () => {
  it("renders with default value", () => {
    render(<QuantityInput />);
    expect(screen.getByTestId("quantity-select")).toHaveTextContent("1");
  });

  it("calls onValueChange when increase button is clicked", () => {
    const onValueChange = vi.fn();
    render(<QuantityInput value={1} onValueChange={onValueChange} />);
    const increaseButton = screen.getByLabelText("Anzahl erhöhen");
    fireEvent.click(increaseButton);
    expect(onValueChange).toHaveBeenCalledWith(2);
  });

  it("calls onValueChange when decrease button is clicked", () => {
    const onValueChange = vi.fn();
    render(<QuantityInput value={2} onValueChange={onValueChange} />);
    const decreaseButton = screen.getByLabelText("Anzahl verringern");
    fireEvent.click(decreaseButton);
    expect(onValueChange).toHaveBeenCalledWith(1);
  });

  it("disables decrease button when at min value", () => {
    const onValueChange = vi.fn();
    render(<QuantityInput value={1} onValueChange={onValueChange} min={1} />);
    const decreaseButton = screen.getByLabelText("Anzahl verringern");
    expect(decreaseButton).toBeDisabled();
  });

  it("disables increase button when at max value", () => {
    const onValueChange = vi.fn();
    render(<QuantityInput value={5} onValueChange={onValueChange} max={5} />);
    const increaseButton = screen.getByLabelText("Anzahl erhöhen");
    expect(increaseButton).toBeDisabled();
  });

  it("respects min boundary", () => {
    const onValueChange = vi.fn();
    render(<QuantityInput value={3} onValueChange={onValueChange} min={2} max={5} />);
    const decreaseButton = screen.getByLabelText("Anzahl verringern");
    fireEvent.click(decreaseButton);
    expect(onValueChange).toHaveBeenCalledWith(2);
    fireEvent.click(decreaseButton);
    expect(onValueChange).toHaveBeenCalledWith(2); // Should not go below min
  });

  it("respects max boundary", () => {
    const onValueChange = vi.fn();
    render(<QuantityInput value={3} onValueChange={onValueChange} min={1} max={5} />);
    const increaseButton = screen.getByLabelText("Anzahl erhöhen");
    fireEvent.click(increaseButton);
    expect(onValueChange).toHaveBeenCalledWith(4);
    fireEvent.click(increaseButton);
    expect(onValueChange).toHaveBeenCalledWith(5);
    fireEvent.click(increaseButton);
    expect(onValueChange).toHaveBeenCalledWith(5); // Should not go above max
  });

  it("shows dynamic options based on max value", () => {
    render(<QuantityInput value={7} onValueChange={vi.fn()} min={1} max={8} />);
    const select = screen.getByTestId("quantity-select");
    expect(select).toHaveTextContent("7");
    
    // Open the select to reveal options
    fireEvent.click(select);
    
    const options = screen.getAllByRole("option");
    expect(options).toHaveLength(8); // Should show 1-8
    expect(options[0]).toHaveTextContent("1");
    expect(options[7]).toHaveTextContent("8");
  });

  it("includes current value beyond 10 in options when within max", () => {
    render(<QuantityInput value={15} onValueChange={vi.fn()} min={1} max={20} />);
    const select = screen.getByTestId("quantity-select");
    
    // Open the select to reveal options
    fireEvent.click(select);
    
    const options = screen.getAllByRole("option");
    expect(options).toHaveLength(11); // Should show 1-10 + 15
  });

  it("announces quantity changes via aria-live", () => {
    const { rerender } = render(<QuantityInput value={1} />);
    expect(screen.getByRole("status")).toHaveTextContent("Anzahl auf 1 aktualisiert");

    rerender(<QuantityInput value={2} />);
    expect(screen.getByRole("status")).toHaveTextContent("Anzahl auf 2 aktualisiert");
  });

  it("has aria-hidden icons", () => {
    render(<QuantityInput />);
    // The icons are inside buttons, they should be hidden from screen readers
    // as the buttons have aria-labels
    const increaseButton = screen.getByLabelText("Anzahl erhöhen");
    const decreaseButton = screen.getByLabelText("Anzahl verringern");

    expect(increaseButton.querySelector("svg")).toHaveAttribute("aria-hidden", "true");
    expect(decreaseButton.querySelector("svg")).toHaveAttribute("aria-hidden", "true");
  });

  it("includes correct localized Tooltip labels for accessibility", () => {
    render(<QuantityInput />);

    // Check that tooltips are present in the document
    // Since we mocked TooltipContent to render directly
    const tooltips = screen.getAllByRole("tooltip");
    expect(tooltips).toHaveLength(2);
    expect(screen.getByText("Anzahl verringern")).toBeInTheDocument();
    expect(screen.getByText("Anzahl erhöhen")).toBeInTheDocument();
  });
});