import { fireEvent, render, screen } from "@solidjs/testing-library";
import { describe, expect, it, vi } from "vitest";
import { NumberField } from "../../../src/components/number-field/index";

describe("NumberField basics", () => {
  it("input has role=spinbutton", () => {
    render(() => (
      <NumberField>
        <NumberField.Input />
      </NumberField>
    ));
    expect(screen.getByRole("spinbutton")).toBeTruthy();
  });
  it("sets aria-valuenow", () => {
    render(() => (
      <NumberField defaultValue={5}>
        <NumberField.Input />
      </NumberField>
    ));
    expect(screen.getByRole("spinbutton").getAttribute("aria-valuenow")).toBe("5");
  });
  it("label linked to input", () => {
    render(() => (
      <NumberField>
        <NumberField.Label>Quantity</NumberField.Label>
        <NumberField.Input />
      </NumberField>
    ));
    const label = screen.getByText("Quantity");
    const input = screen.getByRole("spinbutton");
    expect(label.getAttribute("for")).toBe(input.id);
  });
});

describe("NumberField interactions", () => {
  it("increment button increases value", () => {
    const onChange = vi.fn();
    render(() => (
      <NumberField defaultValue={5} onValueChange={onChange}>
        <NumberField.Input />
        <NumberField.IncrementTrigger>+</NumberField.IncrementTrigger>
      </NumberField>
    ));
    fireEvent.click(screen.getByText("+"));
    expect(onChange).toHaveBeenCalledWith(6);
  });
  it("decrement button decreases value", () => {
    const onChange = vi.fn();
    render(() => (
      <NumberField defaultValue={5} onValueChange={onChange}>
        <NumberField.Input />
        <NumberField.DecrementTrigger>-</NumberField.DecrementTrigger>
      </NumberField>
    ));
    fireEvent.click(screen.getByText("-"));
    expect(onChange).toHaveBeenCalledWith(4);
  });
  it("respects min/max", () => {
    const onChange = vi.fn();
    render(() => (
      <NumberField defaultValue={10} max={10} onValueChange={onChange}>
        <NumberField.Input />
        <NumberField.IncrementTrigger>+</NumberField.IncrementTrigger>
      </NumberField>
    ));
    fireEvent.click(screen.getByText("+"));
    expect(onChange).not.toHaveBeenCalled();
  });
  it("ArrowUp increments", () => {
    const onChange = vi.fn();
    render(() => (
      <NumberField defaultValue={5} onValueChange={onChange}>
        <NumberField.Input />
      </NumberField>
    ));
    fireEvent.keyDown(screen.getByRole("spinbutton"), { key: "ArrowUp" });
    expect(onChange).toHaveBeenCalledWith(6);
  });
});
