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

import { App } from "../../../src/web/app";
import { renderWithProviders } from "../test-utils";

const MOCK_PROJECT = {
  createdAt: "2024-01-01T00:00:00.000Z",
  description: "测试项目",
  id: "test-project-id",
  name: "测试项目",
  status: "active" as const,
  updatedAt: "2024-01-01T00:00:00.000Z",
};

function createMockHandler(overrides?: { status?: "active" | "archived" }) {
  const project = { ...MOCK_PROJECT, ...overrides };
  const handler = (input: RequestInfo | URL) => {
    const url = input instanceof Request ? input.url : typeof input === "string" ? input : input.toString();
    if (url.includes("/api/settings")) {
      return new Response(JSON.stringify({ theme: "system" }), {
        headers: { "Content-Type": "application/json" },
        status: 200,
      });
    }
    if (url.includes("/api/meta")) {
      return new Response(
        JSON.stringify({ ok: true, service: "test-app", timestamp: new Date().toISOString(), version: "0.1.0" }),
        { headers: { "Content-Type": "application/json" }, status: 200 },
      );
    }
    if (url.includes(`/api/projects/${project.id}`)) {
      return new Response(JSON.stringify({ project }), {
        headers: { "Content-Type": "application/json" },
        status: 200,
      });
    }
    if (url.includes("/api/projects/") && url.includes("/conversations")) {
      return new Response(JSON.stringify({ items: [], page: 1, pageSize: 100, total: 0 }), {
        headers: { "Content-Type": "application/json" },
        status: 200,
      });
    }
    return new Response(JSON.stringify({ error: "Not Found" }), { status: 404 });
  };
  const mocked = ((input: RequestInfo | URL, _init?: RequestInit) =>
    Promise.resolve(handler(input))) as unknown as typeof fetch;
  globalThis.fetch = mocked;
  window.fetch = mocked;
}

describe("Workbench 路由", () => {
  test("active 项目可进入 Workbench", async () => {
    createMockHandler();

    renderWithProviders(createElement(App), {
      initialRoute: `/workbench/${MOCK_PROJECT.id}`,
    });

    await waitFor(
      () => {
        const body = document.body.textContent ?? "";
        expect(body).toContain("工作台");
      },
      { timeout: 10000 },
    );
  });

  test("Workbench 显示返回管理台按钮", async () => {
    createMockHandler();

    renderWithProviders(createElement(App), {
      initialRoute: `/workbench/${MOCK_PROJECT.id}`,
    });

    await waitFor(
      () => {
        expect(screen.getByText("返回管理台")).not.toBeNull();
      },
      { timeout: 10000 },
    );
  });

  test("不存在项目显示不可访问", async () => {
    createMockHandler();

    renderWithProviders(createElement(App), {
      initialRoute: "/workbench/nonexistent-id",
    });

    await waitFor(
      () => {
        expect(screen.getByText("项目不存在或不可访问")).not.toBeNull();
      },
      { timeout: 10000 },
    );
  });

  test("archived 项目显示不可访问", async () => {
    createMockHandler({ status: "archived" });

    renderWithProviders(createElement(App), {
      initialRoute: `/workbench/${MOCK_PROJECT.id}`,
    });

    await waitFor(
      () => {
        expect(screen.getByText("项目不存在或不可访问")).not.toBeNull();
      },
      { timeout: 10000 },
    );
  });

  test("Workbench 显示聊天室菜单", async () => {
    createMockHandler();

    renderWithProviders(createElement(App), {
      initialRoute: `/workbench/${MOCK_PROJECT.id}`,
    });

    await waitFor(
      () => {
        expect(screen.getByText("聊天室")).not.toBeNull();
      },
      { timeout: 10000 },
    );
  });

  test("Workbench 收集箱路由可达", async () => {
    createMockHandler();

    renderWithProviders(createElement(App), {
      initialRoute: `/workbench/${MOCK_PROJECT.id}/inbox`,
    });

    await waitFor(
      () => {
        expect(screen.getByText("新增素材")).not.toBeNull();
      },
      { timeout: 10000 },
    );
  });

  test("Workbench 显示收集箱菜单", async () => {
    createMockHandler();

    renderWithProviders(createElement(App), {
      initialRoute: `/workbench/${MOCK_PROJECT.id}`,
    });

    await waitFor(
      () => {
        expect(screen.getByText("收集箱")).not.toBeNull();
      },
      { timeout: 10000 },
    );
  });
});
