// 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 { http, HttpResponse } from "msw";
import { server } from "@/mocks/node.js";
import { findRequest, captureRequest } from "@/mocks/request-log.js";

vi.mock("@/module/apiError.js", () => ({
  default: vi.fn(),
}));

import { useConformanceStore } from "@/stores/conformance";

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

  beforeEach(() => {
    setActivePinia(createPinia());
    store = useConformanceStore();
    document.cookie = "luciaToken=fake-test-token";
  });

  it("has correct default state", () => {
    expect(store.conformanceLogId).toBeNull();
    expect(store.conformanceFilterId).toBeNull();
    expect(store.allConformanceTask).toEqual([]);
    expect(store.selectedRuleType).toBe("Have activity");
  });

  describe("getConformanceParams", () => {
    it("fetches log check params when no filter", async () => {
      store.conformanceLogId = 1;
      store.conformanceFilterId = null;
      const mockData = {
        tasks: [{ label: "A" }],
        sources: ["A"],
        sinks: ["B"],
        processing_time: {},
        waiting_time: {},
        cycle_time: {},
      };
      server.use(
        http.get("/api/log-checks/params", ({ request }) => {
          const url = new URL(request.url);
          captureRequest("GET", url.pathname + url.search);
          return HttpResponse.json(mockData);
        }),
      );

      await store.getConformanceParams();

      const reqs = findRequest("GET", "/api/log-checks/params?log_id=1");
      expect(reqs).toHaveLength(1);
      expect(store.allConformanceTask).toEqual([{ label: "A" }]);
      expect(store.allCfmSeqStart).toEqual(["A"]);
    });

    it("fetches filter check params when filter set", async () => {
      store.conformanceFilterId = 5;
      const mockData = {
        tasks: [],
        sources: [],
        sinks: [],
        processing_time: {},
        waiting_time: {},
        cycle_time: {},
      };
      server.use(
        http.get("/api/filter-checks/params", ({ request }) => {
          const url = new URL(request.url);
          captureRequest("GET", url.pathname + url.search);
          return HttpResponse.json(mockData);
        }),
      );

      await store.getConformanceParams();

      const reqs = findRequest("GET",
        "/api/filter-checks/params?filter_id=5");
      expect(reqs).toHaveLength(1);
    });
  });

  describe("addConformanceCheckId", () => {
    it("posts to log temp-check and stores id", async () => {
      store.conformanceLogId = 1;
      store.conformanceFilterId = null;
      server.use(
        http.post("/api/temp-log-checks", async ({ request }) => {
          const url = new URL(request.url);
          const body = await request.json();
          captureRequest("POST", url.pathname + url.search, body);
          return HttpResponse.json({ id: 42 });
        }),
      );

      await store.addConformanceCheckId({ rule: "test" });

      const reqs = findRequest("POST",
        "/api/temp-log-checks?log_id=1");
      expect(reqs).toHaveLength(1);
      expect(reqs[0].body).toEqual({ rule: "test" });
      expect(store.conformanceLogTempCheckId).toBe(42);
    });

    it("posts to filter temp-check when filter set", async () => {
      store.conformanceFilterId = 3;
      server.use(
        http.post("/api/temp-filter-checks", async ({ request }) => {
          const url = new URL(request.url);
          const body = await request.json();
          captureRequest("POST", url.pathname + url.search, body);
          return HttpResponse.json({ id: 99 });
        }),
      );

      await store.addConformanceCheckId({ rule: "test" });

      const reqs = findRequest("POST",
        "/api/temp-filter-checks?filter_id=3");
      expect(reqs).toHaveLength(1);
      expect(reqs[0].body).toEqual({ rule: "test" });
      expect(store.conformanceFilterTempCheckId).toBe(99);
    });
  });

  describe("getConformanceReport", () => {
    it("fetches temp log check report", async () => {
      store.conformanceLogTempCheckId = 10;
      const mockData = { file: {}, charts: {} };
      server.use(
        http.get("/api/temp-log-checks/:id", ({ request }) => {
          captureRequest("GET", new URL(request.url).pathname);
          return HttpResponse.json(mockData);
        }),
      );

      await store.getConformanceReport();

      const reqs = findRequest("GET", "/api/temp-log-checks/10");
      expect(reqs).toHaveLength(1);
      expect(store.allConformanceTempReportData).toEqual(mockData);
    });

    it("stores routeFile when getRouteFile=true", async () => {
      store.conformanceLogTempCheckId = 10;
      const mockData = { file: { name: "test.csv" } };
      server.use(
        http.get("/api/temp-log-checks/:id", () =>
          HttpResponse.json(mockData),
        ),
      );

      await store.getConformanceReport(true);

      expect(store.allRouteFile).toEqual({ name: "test.csv" });
      expect(store.allConformanceTempReportData).toBeNull();
    });
  });

  describe("addConformanceCreateCheckId", () => {
    it("creates log check and clears temp id", async () => {
      store.conformanceLogId = 1;
      store.conformanceFilterId = null;
      store.conformanceLogTempCheckId = 10;
      store.conformanceRuleData = { type: "test" };
      server.use(
        http.post("/api/log-checks", async ({ request }) => {
          const url = new URL(request.url);
          const body = await request.json();
          captureRequest("POST", url.pathname + url.search, body);
          return HttpResponse.json({ id: 100 });
        }),
      );

      await store.addConformanceCreateCheckId("myRule");

      const reqs = findRequest("POST", "/api/log-checks?log_id=1");
      expect(reqs).toHaveLength(1);
      expect(reqs[0].body).toEqual({
        name: "myRule",
        rule: { type: "test" },
      });
      expect(store.conformanceLogCreateCheckId).toBe(100);
      expect(store.conformanceLogTempCheckId).toBeNull();
    });
  });

  describe("updateConformance", () => {
    it("updates existing log check", async () => {
      store.conformanceLogCreateCheckId = 50;
      store.conformanceRuleData = { type: "updated" };
      server.use(
        http.put("/api/log-checks/:id", async ({ request, params }) => {
          const body = await request.json();
          captureRequest("PUT", `/api/log-checks/${params.id}`, body);
          return new HttpResponse(null, { status: 200 });
        }),
      );

      await store.updateConformance();

      const reqs = findRequest("PUT", "/api/log-checks/50");
      expect(reqs).toHaveLength(1);
      expect(reqs[0].body).toEqual({ type: "updated" });
      expect(store.isUpdateConformance).toBe(true);
    });
  });

  it("setConformanceLogCreateCheckId sets value", () => {
    store.setConformanceLogCreateCheckId("abc");
    expect(store.conformanceLogCreateCheckId).toBe("abc");
  });

  describe("getters", () => {
    it("conformanceTask returns labels", () => {
      store.allConformanceTask = [{ label: "A" }, { label: "B" }];
      expect(store.conformanceTask).toEqual(["A", "B"]);
    });

    it("cases getter formats date attributes with correct minute token", () => {
      store.allCases = [
        {
          started_at: "2023-06-15T10:30:00Z",
          completed_at: "2023-06-15T11:45:00Z",
          facets: [],
          attributes: [
            {
              type: "date",
              value: "2023-06-15T14:30:00Z",
            },
          ],
        },
      ];
      const result = store.cases;
      // The date attribute should show minutes (30), not month (06)
      expect(result[0].attributes[0].value).toMatch(/:30:/);
    });

    it("cases getter does not corrupt original state on repeated access", () => {
      const originalDate = "2023-06-15T10:30:00Z";
      store.allCases = [
        {
          started_at: originalDate,
          completed_at: "2023-06-15T11:45:00Z",
          facets: [],
          attributes: [],
        },
      ];
      expect(store.cases).toBeDefined();
      // Original state should still contain the ISO date
      expect(store.allCases[0].started_at).toBe(originalDate);
    });
  });
});
