/**
 * useSuggestionsData 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);

vi.mock("next-auth/react", () => ({
  useSession: vi.fn(() => ({
    data: { accessToken: "test-token" },
    status: "authenticated",
  })),
}));

import { useSuggestionsData } from "@/lib/hooks/use-suggestions-data";
import type { SuggestionListResponse } from "@/types/suggestion";

const noRetryOptions = { shouldRetryOnError: false };

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

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

  const mockSuggestionsResponse: SuggestionListResponse = {
    suggestions: [
      {
        id: "sug-1",
        brand_id: "brand-1",
        type: "content_optimization",
        priority: "high",
        title: "优化内容",
        description: "建议优化内容",
        action: null,
        expected_impact: null,
        difficulty: "easy",
        status: "pending",
        generated_at: "2024-01-01",
        updated_at: "2024-01-01",
        batch_id: "batch-1",
        source: "rule",
      },
    ],
    total: 1,
  };

  it("brandId 为空时应暂停建议请求", () => {
    mockFetchWithAuth.mockResolvedValue({});

    const { result } = renderHook(() => useSuggestionsData(), { wrapper: createWrapper() });

    expect(result.current.suggestions).toBeUndefined();
  });

  it("brandId 存在时应获取建议列表", async () => {
    mockFetchWithAuth.mockResolvedValue(mockSuggestionsResponse);

    const { result } = renderHook(
      () => useSuggestionsData({ brandId: "brand-1", swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

    await waitFor(() => {
      expect(result.current.suggestions).toEqual(mockSuggestionsResponse.suggestions);
    });
  });

  it("应支持筛选参数", async () => {
    mockFetchWithAuth.mockResolvedValue(mockSuggestionsResponse);

    const { result } = renderHook(
      () => useSuggestionsData({
        brandId: "brand-1",
        filters: { type: "content_optimization", priority: "high", status: "pending" },
        swrOptions: noRetryOptions,
      }),
      { wrapper: createWrapper() }
    );

    await waitFor(() => {
      expect(result.current.suggestions).toEqual(mockSuggestionsResponse.suggestions);
    });

    const suggestionCall = mockFetchWithAuth.mock.calls.find(
      (call) => typeof call[0] === "string" && call[0].includes("/suggestions")
    );
    expect(suggestionCall).toBeDefined();
    const calledUrl = suggestionCall![0] as string;
    expect(calledUrl).toContain("type=content_optimization");
    expect(calledUrl).toContain("priority=high");
    expect(calledUrl).toContain("status=pending");
  });

  it("应正确暴露 isLoading 状态", async () => {
    mockFetchWithAuth.mockResolvedValue(mockSuggestionsResponse);

    const { result } = renderHook(
      () => useSuggestionsData({ brandId: "brand-1", swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

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

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

    const { result } = renderHook(
      () => useSuggestionsData({ brandId: "brand-1", swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

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

  it("应提供 regenerate 方法", () => {
    mockFetchWithAuth.mockResolvedValue(mockSuggestionsResponse);

    const { result } = renderHook(
      () => useSuggestionsData({ brandId: "brand-1", swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

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

  it("应提供 updateStatus 方法", () => {
    mockFetchWithAuth.mockResolvedValue(mockSuggestionsResponse);

    const { result } = renderHook(
      () => useSuggestionsData({ brandId: "brand-1", swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

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

  it("应提供 refresh 方法", () => {
    mockFetchWithAuth.mockResolvedValue(mockSuggestionsResponse);

    const { result } = renderHook(
      () => useSuggestionsData({ brandId: "brand-1", swrOptions: noRetryOptions }),
      { wrapper: createWrapper() }
    );

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