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

import { renderWithProviders } from "../../test-utils";

void mock.module("../../../../src/web/shared/hooks/use-is-dark", () => ({
  useIsDark: () => false,
}));

void mock.module("shiki", () => ({
  codeToHtml: (code: string, options: { lang: string; theme: string }) =>
    Promise.resolve(`<pre class="shiki ${options.theme}"><code>${code}</code></pre>`),
}));

import { CodeBlock } from "../../../../src/web/features/chat/parts/CodeBlock";

function createCodeChild(text: string, lang = "javascript"): React.ReactElement {
  return createElement("code", { className: `language-${lang}` }, text);
}

describe("CodeBlock 流式期间纯文本渲染", () => {
  test("流式时渲染为纯文本 pre", () => {
    const child = createCodeChild("const x = 1;");

    renderWithProviders(createElement(CodeBlock, { children: child, isStreaming: true }));

    const pre = document.querySelector(".code-block");
    expect(pre).toBeTruthy();
    expect(pre!.tagName).toBe("PRE");
    expect(screen.getByText("const x = 1;")).toBeTruthy();
    expect(document.querySelector(".code-block-header")).toBeNull();
  });
});

describe("CodeBlock 非流式高亮渲染", () => {
  test("非流式时显示语言标签和复制按钮", () => {
    const child = createCodeChild("const x = 1;");

    renderWithProviders(createElement(CodeBlock, { children: child, isStreaming: false }));

    expect(document.querySelector(".code-block-header")).toBeTruthy();
    expect(document.querySelector(".code-block-lang")).toBeTruthy();
    expect(screen.getByText("javascript")).toBeTruthy();
  });

  test("非流式时异步高亮代码", async () => {
    const child = createCodeChild("const x = 1;");

    renderWithProviders(createElement(CodeBlock, { children: child, isStreaming: false }));

    await waitFor(() => {
      const body = document.querySelector(".code-block-body");
      expect(body).toBeTruthy();
      expect(body!.innerHTML).toContain("const x = 1;");
    });
  });
});

describe("CodeBlock 复制按钮", () => {
  test("复制按钮存在且可点击", () => {
    const child = createCodeChild("test code");

    renderWithProviders(createElement(CodeBlock, { children: child, isStreaming: false }));

    const button = document.querySelector(".code-block-header button");
    expect(button).toBeTruthy();
  });
});

describe("CodeBlock 语言标签显示", () => {
  test("常见语言显示正确", () => {
    const child = createCodeChild("print('hello')", "python");

    renderWithProviders(createElement(CodeBlock, { children: child, isStreaming: false }));

    expect(screen.getByText("python")).toBeTruthy();
  });

  test("无语言时显示 text", () => {
    const child = createElement("code", { className: "" }, "plain text");

    renderWithProviders(createElement(CodeBlock, { children: child, isStreaming: false }));

    expect(screen.getByText("text")).toBeTruthy();
  });
});
