import { describe, expect, test, vi } from "bun:test";
import { fireEvent, screen, waitFor } from "@testing-library/react";
import { createElement } from "react";

import { ConversationSidebar } from "../../../src/web/features/chat/components/ConversationSidebar";
import { installFetchMock, jsonResponse, renderWithProviders } from "../test-utils";

const PROJECT_ID = "proj-1";

const CONVERSATION = {
  createdAt: "2026-06-03T00:00:00.000Z",
  id: "conv-1",
  modelId: "model-1",
  projectId: PROJECT_ID,
  title: "测试对话",
  updatedAt: "2026-06-03T00:00:00.000Z",
};

function setupSuccessMock() {
  return installFetchMock((call) => {
    if (call.url.includes("/conversations") && call.method === "GET") {
      return jsonResponse({ items: [CONVERSATION], page: 1, pageSize: 200, total: 1 });
    }
    return jsonResponse({ error: "not found" }, { status: 404 });
  });
}

describe("ConversationSidebar", () => {
  test("加载成功后渲染对话列表", async () => {
    setupSuccessMock();
    renderWithProviders(
      createElement(ConversationSidebar, {
        onAddClick: vi.fn(),
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        projectId: PROJECT_ID,
        selectedId: null,
      }),
    );

    await waitFor(() => {
      expect(screen.getByText("测试对话")).not.toBeNull();
    });
  });

  test("加载失败时显示错误和重试按钮", async () => {
    installFetchMock((call) => {
      if (call.url.includes("/conversations") && call.method === "GET") {
        return jsonResponse({ error: "服务器错误" }, { status: 500 });
      }
      return jsonResponse({ error: "not found" }, { status: 404 });
    });

    renderWithProviders(
      createElement(ConversationSidebar, {
        onAddClick: vi.fn(),
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        projectId: PROJECT_ID,
        selectedId: null,
      }),
    );

    await waitFor(() => {
      expect(screen.getByText("加载对话列表失败")).not.toBeNull();
    });

    expect(screen.getByText("重试")).not.toBeNull();
  });

  test("点击重试重新请求", async () => {
    let callCount = 0;
    installFetchMock((call) => {
      if (call.url.includes("/conversations") && call.method === "GET") {
        callCount++;
        if (callCount === 1) {
          return jsonResponse({ error: "服务器错误" }, { status: 500 });
        }
        return jsonResponse({ items: [CONVERSATION], page: 1, pageSize: 200, total: 1 });
      }
      return jsonResponse({ error: "not found" }, { status: 404 });
    });

    renderWithProviders(
      createElement(ConversationSidebar, {
        onAddClick: vi.fn(),
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        projectId: PROJECT_ID,
        selectedId: null,
      }),
    );

    await waitFor(() => {
      expect(screen.getByText("加载对话列表失败")).not.toBeNull();
    });

    fireEvent.click(screen.getByText("重试"));

    await waitFor(() => {
      expect(screen.getByText("测试对话")).not.toBeNull();
    });
  });
});
