import { describe, it, expect, vi } from "vitest";
import { devicesApi } from "../modules/devices.js";
import { areasApi } from "../modules/areas.js";
import { scriptsApi } from "../modules/scripts.js";

vi.mock("../client.js", () => ({
  apiGet: vi.fn((path, options) => Promise.resolve({ ok: true, path, options })),
  apiPost: vi.fn((path, payload) => Promise.resolve({ ok: true, path, payload })),
}));

describe("devicesApi", () => {
  it("list calls apiGet", async () => {
    const { apiGet } = await import("../client.js");
    await devicesApi.list();
    expect(apiGet).toHaveBeenCalledWith("/api/v1/devices/list");
  });

  it("status encodes id", async () => {
    const { apiGet } = await import("../client.js");
    await devicesApi.status(42);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/devices/id/42/status", undefined);
  });

  it("reboot encodes id", async () => {
    const { apiGet } = await import("../client.js");
    await devicesApi.reboot(7);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/devices/id/7/reboot");
  });

  it("action posts payload", async () => {
    const { apiPost } = await import("../client.js");
    await devicesApi.action({ device_id: 1, action: "toggle" });
    expect(apiPost).toHaveBeenCalledWith("/api/v1/devices/action", { device_id: 1, action: "toggle" });
  });

  it("scanningSetup passes options", async () => {
    const { apiGet } = await import("../client.js");
    await devicesApi.scanningSetup({ signal: new AbortController().signal });
    expect(apiGet).toHaveBeenCalledWith("/api/v1/devices/scanning/setup", expect.anything());
  });

  it("scanningAll passes options", async () => {
    const { apiGet } = await import("../client.js");
    await devicesApi.scanningAll({ signal: new AbortController().signal });
    expect(apiGet).toHaveBeenCalledWith("/api/v1/devices/scanning/all", expect.anything());
  });

  it("setupNewDevice posts payload", async () => {
    const { apiPost } = await import("../client.js");
    await devicesApi.setupNewDevice({ alias: "test" });
    expect(apiPost).toHaveBeenCalledWith("/api/v1/devices/setup/new-device", { alias: "test" });
  });

  it("resetup posts device_id", async () => {
    const { apiPost } = await import("../client.js");
    await devicesApi.resetup(99);
    expect(apiPost).toHaveBeenCalledWith("/api/v1/devices/resetup", { device_id: 99 });
  });

  it("reset posts device_id", async () => {
    const { apiPost } = await import("../client.js");
    await devicesApi.reset(42);
    expect(apiPost).toHaveBeenCalledWith("/api/v1/devices/reset", { device_id: 42 });
  });
});

describe("areasApi", () => {
  it("list passes options", async () => {
    const { apiGet } = await import("../client.js");
    await areasApi.list({ signal: new AbortController().signal });
    expect(apiGet).toHaveBeenCalledWith("/api/v1/areas/list", expect.anything());
  });

  it("innerList encodes areaId", async () => {
    const { apiGet } = await import("../client.js");
    await areasApi.innerList(5);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/areas/id/5/list", undefined);
  });

  it("devices encodes areaId and passes options", async () => {
    const { apiGet } = await import("../client.js");
    await areasApi.devices(3);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/areas/id/3/devices", undefined);
  });

  it("scripts encodes areaId and passes options", async () => {
    const { apiGet } = await import("../client.js");
    await areasApi.scripts(3);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/areas/id/3/scripts", undefined);
  });

  it("newArea posts payload", async () => {
    const { apiPost } = await import("../client.js");
    await areasApi.newArea({ type: "room", alias: "test" });
    expect(apiPost).toHaveBeenCalledWith("/api/v1/areas/new-area", { type: "room", alias: "test" });
  });

  it("updateDisplayName posts payload", async () => {
    const { apiPost } = await import("../client.js");
    await areasApi.updateDisplayName({ area_id: 1, display_name: "New" });
    expect(apiPost).toHaveBeenCalledWith("/api/v1/areas/update-display-name", { area_id: 1, display_name: "New" });
  });

  it("updateAlias posts payload", async () => {
    const { apiPost } = await import("../client.js");
    await areasApi.updateAlias({ area_id: 1, new_alias: "new_alias" });
    expect(apiPost).toHaveBeenCalledWith("/api/v1/areas/update-alias", { area_id: 1, new_alias: "new_alias" });
  });

  it("placeInArea posts payload", async () => {
    const { apiPost } = await import("../client.js");
    await areasApi.placeInArea({ target_id: 1, place_in_area_id: 2 });
    expect(apiPost).toHaveBeenCalledWith("/api/v1/areas/place-in-area", { target_id: 1, place_in_area_id: 2 });
  });

  it("remove encodes areaId", async () => {
    const { apiGet } = await import("../client.js");
    await areasApi.remove(10);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/areas/id/10/remove");
  });

  it("unassign encodes areaId", async () => {
    const { apiGet } = await import("../client.js");
    await areasApi.unassign(10);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/areas/id/10/unassign-from-area");
  });
});

describe("scriptsApi", () => {
  it("actionsList passes options", async () => {
    const { apiGet } = await import("../client.js");
    await scriptsApi.actionsList({ signal: new AbortController().signal });
    expect(apiGet).toHaveBeenCalledWith("/api/v1/scripts/actions/list", expect.anything());
  });

  it("regularList passes options", async () => {
    const { apiGet } = await import("../client.js");
    await scriptsApi.regularList({ signal: new AbortController().signal });
    expect(apiGet).toHaveBeenCalledWith("/api/v1/scripts/regular/list", expect.anything());
  });

  it("scopesList passes options", async () => {
    const { apiGet } = await import("../client.js");
    await scriptsApi.scopesList({ signal: new AbortController().signal });
    expect(apiGet).toHaveBeenCalledWith("/api/v1/scripts/scopes/list", expect.anything());
  });

  it("runAction posts alias and params", async () => {
    const { apiPost } = await import("../client.js");
    await scriptsApi.runAction("test", { a: 1 });
    expect(apiPost).toHaveBeenCalledWith("/api/v1/scripts/actions/run", { alias: "test", params: { a: 1 } });
  });

  it("setRegularState encodes alias", async () => {
    const { apiGet } = await import("../client.js");
    await scriptsApi.setRegularState("my_script", true);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/scripts/regular/alias/my_script/enable");
  });

  it("setRegularState encodes alias for disable", async () => {
    const { apiGet } = await import("../client.js");
    await scriptsApi.setRegularState("my_script", false);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/scripts/regular/alias/my_script/disable");
  });

  it("setScopeState encodes name", async () => {
    const { apiGet } = await import("../client.js");
    await scriptsApi.setScopeState("MyScope", true);
    expect(apiGet).toHaveBeenCalledWith("/api/v1/scripts/scopes/name/MyScope/enable");
  });
});
