// The Lucia project.
// Copyright 2026-2026 DSP, inc.  All rights reserved.
// Authors:
//   imacat.yang@dsp.im (imacat), 2026/03/05

import { describe, it, expect, beforeEach, vi } from "vitest";
import { setActivePinia, createPinia } from "pinia";
import { useCytoscapeStore } from "@/stores/cytoscapeStore";
import { SAVE_KEY_NAME } from "@/constants/constants.js";

// Mock localStorage since jsdom's localStorage is limited
const localStorageMock = (() => {
  let store = {};
  return {
    getItem: vi.fn((key) => store[key] || null),
    setItem: vi.fn((key, value) => {
      store[key] = value;
    }),
    removeItem: vi.fn((key) => {
      delete store[key];
    }),
    clear: vi.fn(() => {
      store = {};
    }),
  };
})();
Object.defineProperty(globalThis, "localStorage", {
  value: localStorageMock,
});

describe("cytoscapeStore", () => {
  let store;

  beforeEach(() => {
    setActivePinia(createPinia());
    store = useCytoscapeStore();
    localStorageMock.clear();
    vi.clearAllMocks();
  });

  it("has correct default state", () => {
    expect(store.nodePositions).toEqual({});
    expect(store.currentGraphId).toBe("");
  });

  it("setCurrentGraphId initializes graph structure", () => {
    store.setCurrentGraphId("graph1");
    expect(store.currentGraphId).toBe("graph1");
    expect(store.nodePositions["graph1"]).toEqual({
      TB: [],
      LR: [],
    });
  });

  it("saveNodePosition adds node and saves to localStorage", () => {
    store.setCurrentGraphId("graph1");
    store.saveNodePosition("node1", { x: 10, y: 20 }, "TB");
    expect(store.nodePositions["graph1"]["TB"]).toEqual([
      { id: "node1", position: { x: 10, y: 20 } },
    ]);
    expect(localStorageMock.setItem).toHaveBeenCalledWith(
      SAVE_KEY_NAME,
      expect.any(String),
    );
  });

  it("saveNodePosition updates existing node position", () => {
    store.setCurrentGraphId("graph1");
    store.saveNodePosition("node1", { x: 10, y: 20 }, "TB");
    store.saveNodePosition("node1", { x: 30, y: 40 }, "TB");
    expect(store.nodePositions["graph1"]["TB"]).toHaveLength(1);
    expect(store.nodePositions["graph1"]["TB"][0].position).toEqual({
      x: 30,
      y: 40,
    });
  });

  it("loadPositionsFromStorage restores from localStorage", () => {
    const data = {
      graph1: {
        TB: [{ id: "n1", position: { x: 5, y: 10 } }],
      },
    };
    localStorageMock.getItem.mockReturnValue(JSON.stringify(data));
    store.setCurrentGraphId("graph1");
    store.loadPositionsFromStorage("TB");
    expect(store.nodePositions["graph1"]["TB"]).toEqual([
      { id: "n1", position: { x: 5, y: 10 } },
    ]);
  });
});
