jest.mock("ol/layer/WebGLVectorTile", () => ({
  __esModule: true,
  default: class WebGLVectorTileLayer {},
}));

import { LayerStyleController } from "./layerStyleController";

describe("LayerStyleController", () => {
  it("rebuilds only when the structural signature changes", () => {
    const layer = {
      getSource: () => null,
      updateStyleVariables: jest.fn(),
      setStyle: jest.fn(),
    } as any;
    const controller = new LayerStyleController({
      layer,
      defaultStyle: { "stroke-color": "gray" },
    });
    const base = {
      property: "pressure",
      classCount: 5,
      template: { "stroke-color": ["var", "tj_color_0"] } as any,
      variables: { tj_color_0: "red" },
    };

    controller.applyNative(base);
    controller.applyNative({ ...base, variables: { tj_color_0: "blue" } });
    expect(layer.setStyle).toHaveBeenCalledTimes(1);
    expect(layer.updateStyleVariables).toHaveBeenCalledTimes(2);

    controller.applyNative({ ...base, classCount: 6 });
    expect(layer.setStyle).toHaveBeenCalledTimes(2);
  });

  it("isolates primary and comparison values on a shared vector source", () => {
    const properties: Record<string, unknown> = { id: "J-1" };
    const feature = {
      properties,
      properties_: properties,
      get: (key: string) => properties[key],
    };
    const listeners = new Set<(event: any) => void>();
    const source = {
      sourceTiles_: { loaded: { getFeatures: () => [feature] } },
      on: (_type: string, listener: (event: any) => void) => listeners.add(listener),
      un: (_type: string, listener: (event: any) => void) => listeners.delete(listener),
    };
    const createLayer = () => ({
      getSource: () => source,
      on: jest.fn(),
      un: jest.fn(),
      getOpacity: () => 1,
      setOpacity: jest.fn(),
      setStyle: jest.fn(),
      updateStyleVariables: jest.fn(),
    });
    const primary = new LayerStyleController({
      layer: createLayer() as any,
      defaultStyle: { "circle-fill-color": "gray" },
      stateNamespace: "primary",
    });
    const compare = new LayerStyleController({
      layer: createLayer() as any,
      defaultStyle: { "circle-fill-color": "gray" },
      stateNamespace: "compare",
    });
    const options = {
      property: "pressure",
      classCount: 5,
      template: { "circle-fill-color": ["get", "pressure"] } as any,
      variables: {},
    };

    primary.applyRuntime(options, new Map([["J-1", 0.25]]));
    compare.applyRuntime(options, new Map([["J-1", 0.75]]));

    expect(properties.primary_pressure).toBe(0.25);
    expect(properties.compare_pressure).toBe(0.75);
    expect(listeners.size).toBe(2);

    primary.dispose();
    expect(listeners.size).toBe(1);
    expect(properties.compare_pressure).toBe(0.75);
    compare.dispose();
    expect(listeners.size).toBe(0);
  });
});
