import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { RoleCode } from "../../../shared/api/enums";
import { fileApi } from "../fileApi";
import { clearPreviewRequestsForTests, loadPreviewOnce } from "../fileState";

const read = (path: string) => readFileSync(resolve(process.cwd(), "src", path), "utf8");
const app = read("app/App.tsx");
const preview = read("features/files/FilePreviewModal.tsx");
const mutations = read("features/mutations/MutationModals.tsx");
const mutationTypes = read("features/mutations/mutationTypes.ts");
const mainPage = app.slice(app.indexOf("function RealMainPage"), app.indexOf("function RealAdminPage"));

describe("Q3-F 1.4 business alignment", () => {
  it("正式角色仅ADMIN和USER", () => {
    expect(Object.values(RoleCode).sort()).toEqual(["ADMIN", "USER"]);
  });

  it("ADMIN审计与导航由allowedModules驱动", () => {
    expect(app).toContain('page === "audit" && currentUser.roleCode === RoleCode.ADMIN');
    expect(app).toContain("getNavigationItems(");
    expect(app).toContain("currentUser.allowedModules,");
  });

  it("所有登录页框显示单位和真实姓名并处理空单位", () => {
    expect(app).toContain('currentUser.organizationName || "未设置单位"');
    expect(app).toContain("currentUser.realName");
    expect(app).not.toContain("currentUser.username}</div>");
  });

  it("用户主列表无三标签且只查询MAIN", () => {
    expect(mainPage).not.toContain('label: "全部方案"');
    expect(mainPage).not.toContain('label: "最近更新"');
    expect(mainPage).toContain("documentType: DocumentType.MAIN");
    expect(mainPage).not.toContain("MAIN},${DocumentType.SUB_PLAN");
  });

  it("全部分类不伪造ID，真实分类启用后代查询", () => {
    expect(app).toContain("全部分类");
    expect(app).toContain("includeDescendants: categoryId ? true : undefined");
    expect(app).toContain("categoryId: categoryId ?? undefined");
  });

  it("分类数字直接使用后端documentCount", () => {
    expect(app).toContain("node.documentCount");
    expect(app).not.toContain("getCategoryBranchMainPlanCount(node)");
  });

  it("主案分类只允许叶子，分类管理父级选择不复用该限制", () => {
    expect(mutations).toContain("category.isLeaf");
    expect(mutations).toContain("disabled={!category.isLeaf}");
    expect(app).toContain("getCategoryParentOptions");
  });

  it("单文件上传统一选择主案或子案且子案继承主案分类", () => {
    expect(app).toContain("上传主案/子案</button>");
    expect(mutations).toContain('label="方案类型 *"');
    expect(mutations).toContain("方案分类继承自主案");
    expect(mutations).toContain("DOCUMENT_NAME_CONFLICT");
    expect(mutations).toContain("确认覆盖");
  });

  it("1.4 DTO不含status、visibilityType或子方案categoryId", () => {
    expect(mutationTypes).not.toContain("visibilityType:");
    expect(mutationTypes).not.toContain("status:");
    const sub = mutationTypes.slice(mutationTypes.indexOf("export interface SubPlanCreateMetadata"), mutationTypes.indexOf("export type DocumentCreateMetadata"));
    expect(sub).not.toContain("categoryId");
  });

  it("USER页面不挂独立共享附件库且仍挂载已关联附件", () => {
    expect(mainPage).not.toContain("<F4AttachmentLibrary");
    expect(mainPage).toContain("useMountedAttachments");
    expect(mainPage).toContain("配套资料");
  });

  it("USER页面无继承权限按钮，管理员显示只读继承说明", () => {
    expect(mainPage).not.toContain("onPermission={setPermission}");
    expect(app).toContain("权限继承自主案：{selected.documentName}");
  });

  it("方案关键词提示覆盖主案和子方案", () => {
    expect(app.match(/搜索方案名称、概述、标签或文档内容/g)?.length).toBeGreaterThanOrEqual(4);
  });
});

describe("Q3-F right preview", () => {
  beforeEach(() => {
    clearPreviewRequestsForTests();
    vi.restoreAllMocks();
  });

  it("预览只调用正式preview路径而不调用download", () => {
    expect(read("features/files/fileApi.ts")).toContain("`documents/${id}/preview`");
    expect(preview).not.toContain("fileApi.download");
  });

  it("点击行保留右侧预览，查看按钮打开完整文档窗口", () => {
    expect(app).toContain("onSelect={(item) => { setSelected(item); setPreview(item); }}");
    expect(app).toContain("onView={setFullView}");
    expect(app).toContain('mode="modal"');
    expect(preview).toContain('mode?: "side" | "modal"');
    expect(preview).toContain('aria-label={mode === "modal" ? "完整文档查看" : "文档右侧预览"}');
  });

  it("业务弹窗所在主体层级高于顶部导航，关闭按钮不会被遮挡", () => {
    expect(app).toContain('className="relative z-30 flex-shrink-0 flex items-center');
    expect(app).toContain('className="relative z-40 flex flex-1 min-h-0"');
    expect(preview).toContain('className="fixed inset-0 z-[80] flex items-center justify-center"');
  });

  it("PDF通过自托管PdfViewer渲染并卸载时释放资源", () => {
    expect(preview).toContain("mime === PDF_MIME");
    expect(preview).toContain("<PdfViewer");
    expect(preview).toContain('from "./PdfViewer"');
  });

  it("DOCX严格校验MIME、arrayBuffer并调用renderAsync", () => {
    expect(preview).toContain("mime !== DOCX_MIME");
    expect(preview).toContain("result.blob.arrayBuffer()");
    expect(preview).toContain("await renderAsync");
  });

  it("DOC不会进入renderAsync并显示415友好提示和requestId", () => {
    expect(preview).toContain("当前DOC格式暂不支持在线预览，请下载原始文件。");
    expect(preview).toContain("error.httpStatus === 415");
    expect(preview).toContain("错误编号：{error.requestId}");
  });

  it("下载入口由DOWNLOAD动作控制", () => {
    expect(preview).toContain("item.allowedActions.includes(AllowedAction.DOWNLOAD)");
    expect(preview).toContain("{canDownload &&");
  });

  it("版本键相同合并请求，文档版本变化产生新请求", async () => {
    const result = { blob: new Blob(["pdf"]), contentType: "application/pdf", contentDisposition: null, requestId: "r", httpStatus: 200, headers: new Headers() };
    const call = vi.spyOn(fileApi, "preview").mockResolvedValue(result);
    await Promise.all([loadPreviewOnce("1", "v1"), loadPreviewOnce("1", "v1")]);
    await loadPreviewOnce("1", "v2");
    expect(call).toHaveBeenCalledTimes(2);
  });

  it("快速切换、DOCX容器和危险链接均有清理保护", () => {
    expect(preview).toContain("requestVersion.current");
    expect(preview).toContain("replaceChildren()");
    expect(preview).toContain("noopener noreferrer");
    expect(preview).toContain("javascript:");
  });

  it("401之外可重试且错误不会保留上一文档内容", () => {
    expect(preview).toContain("setPdfBlob(null)");
    expect(preview).toContain("error.httpStatus !== 401");
    expect(preview).toContain("重试预览");
  });
});
