/**
 * useContentData Hook 单元测试
 */

import { describe, it, expect, vi, beforeEach } from "vitest";
import { renderHook, waitFor } from "@testing-library/react";
import { SWRConfig } from "swr";
import type { ReactNode } from "react";

vi.mock("@/lib/api/client", () => ({
  fetchWithAuth: vi.fn(),
}));

import { fetchWithAuth } from "@/lib/api/client";
const mockFetchWithAuth = vi.mocked(fetchWithAuth);

import { useContentData } from "@/lib/hooks/use-content-data";
import type { Content } from "@/lib/api/contents";
import type { KnowledgeBase } from "@/lib/api/knowledge";

const noRetryOptions = { shouldRetryOnError: false };

function createWrapper() {
  return ({ children }: { children: ReactNode }) =>
    SWRConfig({ value: { provider: () => new Map() }, children });
}

describe("useContentData", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  const mockContents: Content[] = [
    {
      id: "content-1",
      title: "测试内容",
      body: "内容正文",
      content_type: "article",
      status: "draft",
      author_id: "user-1",
      tags: ["test"],
      created_at: "2024-01-01",
      updated_at: "2024-01-01",
    },
  ];

  const mockKnowledgeBases: KnowledgeBase[] = [
    {
      id: "kb-1",
      name: "测试知识库",
      type: "enterprise",
      document_count: 5,
      status: "ready",
      created_at: "2024-01-01",
    },
  ];

  it("应同时获取内容列表和知识库列表", async () => {
    mockFetchWithAuth.mockImplementation((url: string) => {
      if (url.includes("/api/v1/contents/")) return Promise.resolve(mockContents);
      if (url.includes("/api/v1/knowledge/bases")) return Promise.resolve(mockKnowledgeBases);
      return Promise.resolve([]);
    });

    const { result } = renderHook(
      () => useContentData({ swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    expect(result.current.contents).toEqual(mockContents);
    expect(result.current.knowledgeBases).toEqual(mockKnowledgeBases);
  });

  it("应正确暴露 isLoading 状态", async () => {
    mockFetchWithAuth.mockImplementation((url: string) => {
      if (url.includes("/api/v1/contents/")) return Promise.resolve(mockContents);
      if (url.includes("/api/v1/knowledge/bases")) return Promise.resolve(mockKnowledgeBases);
      return Promise.resolve([]);
    });

    const { result } = renderHook(
      () => useContentData({ swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });
  });

  it("应正确暴露 error 状态", async () => {
    mockFetchWithAuth.mockRejectedValue(new Error("数据加载失败"));

    const { result } = renderHook(
      () => useContentData({ swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

    await waitFor(() => {
      expect(result.current.error).toBeDefined();
      expect(result.current.error?.message).toBe("数据加载失败");
    });
  });

  it("应提供 refresh 方法", async () => {
    mockFetchWithAuth.mockImplementation((url: string) => {
      if (url.includes("/api/v1/contents/")) return Promise.resolve(mockContents);
      if (url.includes("/api/v1/knowledge/bases")) return Promise.resolve(mockKnowledgeBases);
      return Promise.resolve([]);
    });

    const { result } = renderHook(
      () => useContentData({ swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    expect(typeof result.current.refreshContents).toBe("function");
    expect(typeof result.current.refreshKnowledgeBases).toBe("function");
  });

  it("数据加载失败时 error 应包含错误信息", async () => {
    mockFetchWithAuth.mockRejectedValue(new Error("网络异常"));

    const { result } = renderHook(
      () => useContentData({ swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

    await waitFor(() => {
      expect(result.current.error?.message).toBe("网络异常");
    });
  });
});
