import { createSignal } from "solid-js";
import { render } from "@solidjs/testing-library";
import { describe, expect, it } from "vitest";
import { createFloating } from "../../src/primitives/create-floating";
import type { CreateFloatingOptions } from "../../src/primitives/create-floating";

type PartialOpts = Partial<Pick<CreateFloatingOptions, "placement" | "strategy" | "open">>;

function renderFloating(extra: PartialOpts = {}) {
  let state: ReturnType<typeof createFloating> | undefined;

  render(() => {
    const [anchor, setAnchor] = createSignal<HTMLElement | null>(null);
    const [floating, setFloating] = createSignal<HTMLElement | null>(null);

    state = createFloating({ anchor, floating, ...extra });

    return (
      <div>
        <button ref={setAnchor}>Anchor</button>
        <div ref={setFloating}>Float</div>
      </div>
    );
  });

  return state!;
}

describe("createFloating", () => {
  it("returns reactive x, y, placement, and style", () => {
    const state = renderFloating({ placement: () => "bottom" });

    expect(typeof state.x()).toBe("number");
    expect(typeof state.y()).toBe("number");
    expect(state.placement()).toBe("bottom");
    expect(state.style()).toHaveProperty("position");
  });

  it("does not compute when open is false", () => {
    const state = renderFloating({ placement: () => "bottom", open: () => false });

    expect(state.x()).toBe(0);
    expect(state.y()).toBe(0);
  });

  it("style includes position strategy", () => {
    const state = renderFloating({ strategy: () => "fixed" });

    expect(state.style().position).toBe("fixed");
  });
});
