import { describe, expect, it, vi } from "vitest";
import { createDocumentApi } from "../documentApi";
import { detail, result, summary } from "./fixtures";

const page = { items: [summary], page: 1, pageSize: 20, total: 1, totalPages: 1 };

describe("documentApi", () => {
  it("GET /documents 透传筛选、排序、分页和 AbortSignal", async () => {
    const client = { get: vi.fn().mockResolvedValue(result(page)) };
    const api = createDocumentApi(client);
    const signal = new AbortController().signal;
    const query = { documentType: "MAIN", categoryId: "2", includeDescendants: true, keyword: "应急", updatedFrom: "2026-08-04T01:00:00.000Z", updatedTo: "2026-08-04T10:00:00.000Z", sortBy: "updatedAt" as const, sortDirection: "desc" as const, page: 2, pageSize: 20 };
    await api.list(query, signal);
    expect(client.get).toHaveBeenCalledWith("documents", { query, signal });
  });

  it("GET /documents/{id} 严格解析详情", async () => {
    const client = { get: vi.fn().mockResolvedValue(result(detail)) };
    const api = createDocumentApi(client);
    await expect(api.detail("1")).resolves.toEqual(detail);
    expect(client.get).toHaveBeenCalledWith("documents/1", { signal: undefined });
  });

  it("GET /main-plans/{id}/sub-plans 使用直属子方案路径", async () => {
    const client = { get: vi.fn().mockResolvedValue(result(page)) };
    const api = createDocumentApi(client);
    await api.subPlans("1", { page: 1, pageSize: 20 });
    expect(client.get).toHaveBeenCalledWith("main-plans/1/sub-plans", {
      query: { page: 1, pageSize: 20 },
      signal: undefined,
    });
  });

  it("直属子方案透传状态、时间、排序和分页组合", async () => {
    const client = { get: vi.fn().mockResolvedValue(result(page)) };
    const query = {
      keyword: "通信",
      status: "PUBLISHED" as const,
      updatedFrom: "2026-08-01T00:00:00.000Z",
      updatedTo: "2026-08-04T00:00:00.000Z",
      page: 2,
      pageSize: 20,
      sortBy: "updatedAt" as const,
      sortDirection: "desc" as const,
    };
    await createDocumentApi(client).subPlans("1", query);
    expect(client.get).toHaveBeenCalledWith("main-plans/1/sub-plans", {
      query,
      signal: undefined,
    });
  });

  it("拒绝 number ID 和非 UTC 时间", async () => {
    const client = { get: vi.fn().mockResolvedValue(result({ ...page, items: [{ ...summary, id: 1, updatedAt: "2026-07-23 10:00:00" }] })) };
    await expect(createDocumentApi(client).list({})).rejects.toMatchObject({
      code: "INTERNAL_ERROR",
      requestId: "request-id",
    });
  });

  it("GET /documents/tags 透传 signal 并返回字符串数组", async () => {
    const client = { get: vi.fn().mockResolvedValue(result({ items: ["保密", "涉外"], total: 2 })) };
    const api = createDocumentApi(client);
    const signal = new AbortController().signal;
    await expect(api.listTags(signal)).resolves.toEqual(["保密", "涉外"]);
    expect(client.get).toHaveBeenCalledWith("documents/tags", { signal });
  });

  it("GET /documents/tags 拒绝非字符串数组", async () => {
    const client = { get: vi.fn().mockResolvedValue(result({ items: ["保密", 12], total: 2 })) };
    await expect(createDocumentApi(client).listTags()).rejects.toMatchObject({
      code: "INTERNAL_ERROR",
      requestId: "request-id",
    });
  });
});
