import { act, renderHook } from "@testing-library/react";
import { expect, it } from "bun:test";
import { MemoryRouter } from "react-router";
import { parseState, useServerState } from "./useServerState";

function createWrapper(initialState: Record<string, unknown> = {}) {
  // eslint-disable-next-line react/display-name
  return ({ children }) => <MemoryRouter>{children}</MemoryRouter>;
}

it("encodes/decodes an object into a query string", () => {
  const input = { a: 1, b: 2 };
  const { result } = renderHook(() => useServerState("alpha", input), {
    wrapper: createWrapper({}),
  });
  expect(result.current[0]).toEqual(input);
  act(() => {
    result.current[1]({ a: 3, b: 2 });
  });
  expect(result.current[0]).toEqual({ a: 3, b: 2 });
});

it("encodes/decodes an array into a query string", () => {
  const input = [{ a: 1 }, { b: 2 }];
  const { result } = renderHook(() => useServerState("alpha", input), {
    wrapper: createWrapper({}),
  });
  expect(result.current[0]).toEqual(input);
  act(() => {
    result.current[1]([{ a: 3 }]);
  });
  expect(result.current[0]).toEqual([{ a: 3 }]);
});

it("parses state", () => {
  const search = `?fake=true&test=142&myfilter=eyJpZCI6IjEiLCJmaWVsZCI6eyJfX3R5cGUiOiJjb2x1bW4iLCJpZCI6IjEiLCJuYW1lIjoiTmFtZSJ9LCJvcGVyYXRvciI6ImVxIiwidmFsdWUiOiJKb2huIiwiY2hpbGRyZW4iOlt7ImlkIjoiMSIsImZpZWxkIjp7Il9fdHlwZSI6ImNvbHVtbiIsImlkIjoiMSIsIm5hbWUiOiJOYW1lIn0sIm9wZXJhdG9yIjoiZXEiLCJ2YWx1ZSI6IkpvaG4iLCJjaGlsZHJlbiI6W119XX0`;
  const parsed = parseState(search, (_key, value) => {
    if (value?.__type === "columnRef" && value.key) {
      return { __type: "column", key: value.key };
    }
    return value;
  });
  expect(parsed).toMatchInlineSnapshot(`
{
  "fake": "true",
  "myfilter": {
    "children": [
      {
        "children": [],
        "field": {
          "__type": "column",
          "id": "1",
          "name": "Name",
        },
        "id": "1",
        "operator": "eq",
        "value": "John",
      },
    ],
    "field": {
      "__type": "column",
      "id": "1",
      "name": "Name",
    },
    "id": "1",
    "operator": "eq",
    "value": "John",
  },
  "test": "142",
}
`);
});
