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

import type { Conversation } from "../../../src/shared/api";

import { ConversationList } from "../../../src/web/features/chat/components/ConversationList";
import { renderWithProviders } from "../test-utils";

const CONVERSATIONS: Conversation[] = [
  {
    createdAt: "2026-06-03T00:00:00.000Z",
    id: "conv-1",
    modelId: "model-1",
    projectId: "proj-1",
    title: "今天对话",
    updatedAt: "2026-06-03T00:00:00.000Z",
  },
  {
    createdAt: "2026-06-02T00:00:00.000Z",
    id: "conv-2",
    modelId: "model-1",
    projectId: "proj-1",
    title: "昨天对话",
    updatedAt: "2026-06-02T00:00:00.000Z",
  },
  {
    createdAt: "2026-05-01T00:00:00.000Z",
    id: "conv-3",
    modelId: "model-1",
    projectId: "proj-1",
    title: "更早对话",
    updatedAt: "2026-05-01T00:00:00.000Z",
  },
];

describe("ConversationList", () => {
  test("列表为空时显示暂无对话", () => {
    renderWithProviders(
      createElement(ConversationList, {
        conversations: [],
        loading: false,
        onAddClick: vi.fn(),
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        selectedId: null,
      }),
    );
    expect(screen.getByText("暂无对话")).not.toBeNull();
  });

  test("渲染对话列表并按日期分组", () => {
    renderWithProviders(
      createElement(ConversationList, {
        conversations: CONVERSATIONS,
        loading: false,
        onAddClick: vi.fn(),
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        selectedId: null,
      }),
    );
    expect(screen.getByText("今天对话")).not.toBeNull();
    expect(screen.getByText("昨天对话")).not.toBeNull();
    expect(screen.getByText("更早对话")).not.toBeNull();
  });

  test("加载中显示 Skeleton", () => {
    renderWithProviders(
      createElement(ConversationList, {
        conversations: [],
        loading: true,
        onAddClick: vi.fn(),
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        selectedId: null,
      }),
    );
    expect(document.querySelector(".ant-skeleton")).not.toBeNull();
  });

  test("点击新对话按钮触发 onAddClick", () => {
    const onAddClick = vi.fn();
    renderWithProviders(
      createElement(ConversationList, {
        conversations: [],
        loading: false,
        onAddClick,
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        selectedId: null,
      }),
    );
    screen.getByText("新对话").click();
    expect(onAddClick).toHaveBeenCalledTimes(1);
  });

  test("点击搜索按钮过滤对话标题", async () => {
    renderWithProviders(
      createElement(ConversationList, {
        conversations: CONVERSATIONS,
        loading: false,
        onAddClick: vi.fn(),
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        selectedId: null,
      }),
    );
    const searchInput = screen.getByPlaceholderText("搜索对话");
    fireEvent.change(searchInput, { target: { value: "今天" } });
    expect(screen.getByText("昨天对话")).not.toBeNull();

    fireEvent.keyDown(searchInput, { key: "Enter" });

    await waitFor(() => {
      expect(screen.getByText("今天对话")).not.toBeNull();
      expect(screen.queryByText("昨天对话")).toBeNull();
      expect(screen.queryByText("更早对话")).toBeNull();
    });
  });

  test("输入文字未点击搜索时不触发过滤", () => {
    renderWithProviders(
      createElement(ConversationList, {
        conversations: CONVERSATIONS,
        loading: false,
        onAddClick: vi.fn(),
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        selectedId: null,
      }),
    );
    const searchInput = screen.getByPlaceholderText("搜索对话");
    fireEvent.change(searchInput, { target: { value: "今天" } });

    expect(screen.getByText("今天对话")).not.toBeNull();
    expect(screen.getByText("昨天对话")).not.toBeNull();
    expect(screen.getByText("更早对话")).not.toBeNull();
  });

  test("搜索无匹配结果时显示无匹配对话", async () => {
    renderWithProviders(
      createElement(ConversationList, {
        conversations: CONVERSATIONS,
        loading: false,
        onAddClick: vi.fn(),
        onDelete: vi.fn(),
        onSelect: vi.fn(),
        selectedId: null,
      }),
    );
    const searchInput = screen.getByPlaceholderText("搜索对话");
    fireEvent.change(searchInput, { target: { value: "不存在的对话" } });
    fireEvent.keyDown(searchInput, { key: "Enter" });

    await waitFor(() => {
      expect(screen.getByText("无匹配对话")).not.toBeNull();
    });
  });
});
