import { beforeEach, describe, expect, it, vi } from "vitest";
import { FrontendActionExecutor } from "./executor";
import { parseFrontendActionRegistry, parseFrontendActionRequest, type FrontendActionResult } from ".";

const storage = new Map<string, string>();

beforeEach(() => {
  storage.clear();
  vi.stubGlobal("sessionStorage", {
    getItem: (key: string) => storage.get(key) ?? null,
    setItem: (key: string, value: string) => storage.set(key, value)
  });
});

describe("SCADA frontend actions", () => {
  it("accepts only the two registered SCADA action names", () => {
    expect(parseFrontendActionRegistry({
      schema_version: "frontend-action-registry@1",
      actions: [
        { id: "render_scada_analysis", version: "frontend-action@1" },
        { id: "clear_scada_analysis", version: "frontend-action@1" },
        { id: "zoom_to_map", version: "frontend-action@1" }
      ]
    })?.actions.map((action) => action.id)).toEqual([
      "render_scada_analysis",
      "clear_scada_analysis"
    ]);
    expect(parseFrontendActionRequest(createRequest("zoom_to_map"))).toBeNull();
    expect(parseFrontendActionRequest(createRequest("render_scada_analysis"))).not.toBeNull();
  });

  it("submits the real browser output and replays the terminal receipt idempotently", async () => {
    const execute = vi.fn(async () => ({
      rendered_ids: ["MP01"],
      missing_ids: [],
      level_counts: { high: 1, medium: 0, low: 0, unrated: 0 },
      fitted: true
    }));
    const submit = vi.fn(async (
      _sessionId: string,
      _actionId: string,
      _result: FrontendActionResult
    ) => undefined);
    const executor = new FrontendActionExecutor(execute, submit);
    const request = createRequest("render_scada_analysis");
    await executor.handle(request, "session-1");
    await executor.handle(request, "session-1");
    expect(execute).toHaveBeenCalledTimes(1);
    expect(submit).toHaveBeenCalledTimes(2);
    expect(submit.mock.calls[0][2]).toMatchObject({
      status: "succeeded",
      output: { rendered_ids: ["MP01"], fitted: true }
    });
    expect(submit.mock.calls[1][2]).toEqual(submit.mock.calls[0][2]);
  });
});

function createRequest(name: string) {
  return {
    version: "frontend-action@1",
    actionId: "action-1",
    toolCallId: "call-1",
    sessionId: "session-1",
    name,
    params: { items: [{ sensor_id: "MP01", level: "high" }] },
    issuedAt: Date.now(),
    expiresAt: Date.now() + 15_000
  };
}
