import { describe, it, expect, vi, beforeEach } from "vitest";
import { createRegionManagerProxy } from "./region-manager";
import { BROKER_EVENTS } from "../broker/broker-events";

const pluginId = "test-plugin";
const mockView = { id: "view1" };

const createMockRegion = () => ({
  activate: vi.fn(),
  deactivate: vi.fn(),
  removeView: vi.fn(),
  containsView: vi.fn().mockReturnValue(true),
  isViewActive: vi.fn().mockReturnValue(false),
  currentActiveViews: [{ id: "view1" }],
});

describe("RegionManagerProxy", () => {
  let proxy: ReturnType<typeof createRegionManagerProxy>;
  let regionManager: any;
  let broker: any;
  let regionMock: any;

  beforeEach(() => {
    regionMock = createMockRegion();
    regionManager = {
      registerViewWithRegion: vi.fn(),
      unregisterViewFromRegion: vi.fn(),
      getRegion: vi.fn().mockReturnValue(regionMock),
      destroy: vi.fn(),
    };

    broker = {
      publish: vi.fn(),
    };

    proxy = createRegionManagerProxy({ pluginId }, regionManager, broker);
  });

  it("registerView should delegate to regionManager", async () => {
    await proxy.registerView("test-region", mockView);
    expect(regionManager.registerViewWithRegion).toHaveBeenCalledWith("test-region", `${pluginId}::${mockView.id}`, mockView);
  });

  it("removeView should unregister view from region manager", async () => {
    await proxy.removeView("main", "view1");
    expect(regionManager.unregisterViewFromRegion).toHaveBeenCalledWith("main", `${pluginId}::view1`);
  });

  it("activateView should activate the view and notify if region is main", async () => {
    await proxy.activateView(proxy.regions.shell.main, "view1");
    expect(regionMock.activate).toHaveBeenCalledWith(`${pluginId}::view1`);
    expect(broker.publish).toHaveBeenCalledWith(BROKER_EVENTS.shell.mainViewChanged, { viewId: "view1" });
  });

  it("deactivateView should deactivate the view", async () => {
    await proxy.deactivateView("main", "view1");
    expect(regionMock.deactivate).toHaveBeenCalledWith(`${pluginId}::view1`);
  });

  it("getRegion should return the region", async () => {
    const region = await proxy.getRegion("main");
    expect(region).toEqual(regionMock);
  });

  it("containsView should check for view existence", async () => {
    const result = await proxy.containsView("main", "view1");
    expect(regionMock.containsView).toHaveBeenCalledWith(`${pluginId}::view1`);
    expect(result).toBe(true);
  });

  it("isViewActive should check if view is active", async () => {
    const result = await proxy.isViewActive("main", "view1");
    expect(result).toBe(true);
  });

  it("registerQuickAction should register in quickActions region", async () => {
    await proxy.registerQuickAction(mockView);
    expect(regionManager.registerViewWithRegion).toHaveBeenCalledWith(
      proxy.regions.shell.quickActions,
      `${pluginId}::${mockView.id}`,
      mockView,
    );
  });

  it("registerNavigationMenu should register in navigationMenu region", async () => {
    await proxy.registerNavigationMenu(mockView);
    expect(regionManager.registerViewWithRegion).toHaveBeenCalledWith(
      proxy.regions.shell.navigationMenu,
      `${pluginId}::${mockView.id}`,
      mockView,
    );
  });

  it("registerMainView should register in main region", async () => {
    await proxy.registerMainView(mockView);
    expect(regionManager.registerViewWithRegion).toHaveBeenCalledWith(
      proxy.regions.shell.main,
      `${pluginId}::${mockView.id}`,
      mockView,
    );
  });

  it("activateMainView should activate main view and notify broker", async () => {
    await proxy.activateMainView("view1");
    expect(regionMock.activate).toHaveBeenCalledWith(`${pluginId}::view1`);
    expect(broker.publish).toHaveBeenCalledWith(BROKER_EVENTS.shell.mainViewChanged, { viewId: "view1" });
  });

  it("getCurrentMainViewActive should return id of the active main view", () => {
    const result = proxy.getCurrentMainViewActive();
    expect(result).toBe("view1");
  });

  it("_destroy should call regionManager.destroy", () => {
    proxy._destroy();
    expect(regionManager.destroy).toHaveBeenCalled();
  });
});
