import { describe, expect, it } from "vitest";
import {
  buildOnlyOfficeAssetOpenUrl,
  buildOnlyOfficeCallbackUrl,
  buildOnlyOfficeForcesaveUrl,
  buildOnlyOfficeOpenFileId,
  docTypeFromExt,
  inferOnlyOfficeFileType,
  resolveOnlyOfficeDocumentUrl,
} from "@/lib/onlyoffice/client-session";

describe("onlyoffice client session helpers", () => {
  it("docTypeFromExt maps office extensions", () => {
    expect(docTypeFromExt("docx")).toBe("word");
    expect(docTypeFromExt("xlsx")).toBe("cell");
    expect(docTypeFromExt("pptx")).toBe("slide");
    expect(docTypeFromExt("pdf")).toBe("word");
  });

  it("inferOnlyOfficeFileType detects only true Office assets from file name and MIME", () => {
    expect(inferOnlyOfficeFileType("demo.pptx", null)).toBe("pptx");
    expect(inferOnlyOfficeFileType("demo", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")).toBe("docx");
    expect(inferOnlyOfficeFileType("demo", "application/pdf")).toBeNull();
    expect(inferOnlyOfficeFileType("demo.png", "image/png")).toBeNull();
    expect(inferOnlyOfficeFileType("demo.pdf", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.toml", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.json", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.yaml", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.yml", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.md", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.txt", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.ts", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.js", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.py", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.rs", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.go", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.html", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.css", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.vue", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.svelte", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.proto", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.graphql", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.gradle", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.tf", null)).toBeNull();
    expect(inferOnlyOfficeFileType("demo.pdf", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")).toBeNull();
    expect(inferOnlyOfficeFileType("Dockerfile", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")).toBeNull();
    expect(inferOnlyOfficeFileType(".gitignore", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")).toBeNull();
  });

  it("buildOnlyOfficeAssetOpenUrl keeps attachment identity for callback writeback", () => {
    const result = buildOnlyOfficeAssetOpenUrl({
      origin: "https://mnote.example.com",
      fileUrl: "https://storage.example.com/demo.pptx?token=abc",
      fileName: "2023自我介绍PPT_李爱波0831.pptx",
      fileType: "pptx",
      assetId: "asset_ppt_1",
      documentId: "doc_1",
      mode: "edit",
    });

    expect(result).toBe(
      "https://mnote.example.com/onlyoffice?fileUrl=https%3A%2F%2Fstorage.example.com%2Fdemo.pptx%3Ftoken%3Dabc&fileName=2023%E8%87%AA%E6%88%91%E4%BB%8B%E7%BB%8DPPT_%E6%9D%8E%E7%88%B1%E6%B3%A20831.pptx&fileType=pptx&assetId=asset_ppt_1&documentId=doc_1&mode=edit",
    );
  });

  it("resolveOnlyOfficeDocumentUrl wraps signed url with proxy", () => {
    const result = resolveOnlyOfficeDocumentUrl({
      effectiveFileUrl: "https://public.example.com/storage/v1/object/sign/documents/a.docx?token=abc",
      proxyOrigin: "https://app.example.com",
      storageHostOverride: "",
      runtimeSupabaseUrl: "https://public.example.com",
      useConvex: false,
    });
    expect(result).toContain("https://app.example.com/api/onlyoffice/proxy?u=");
  });

  it("buildOnlyOfficeCallbackUrl keeps asset and user", () => {
    const result = buildOnlyOfficeCallbackUrl({
      callbackOrigin: "http://host.docker.internal:3000",
      proxyOrigin: "",
      windowOrigin: "https://app.example.com",
      assetId: "asset_1",
      userId: "user_1",
    });
    expect(result).toBe(
      "http://host.docker.internal:3000/api/onlyoffice/callback?assetId=asset_1&userId=user_1",
    );
  });

  it("buildOnlyOfficeForcesaveUrl keeps key", () => {
    const result = buildOnlyOfficeForcesaveUrl({
      windowOrigin: "https://app.example.com",
      assetId: "asset_1",
      key: "doc_key_1",
    });
    expect(result).toBe(
      "https://app.example.com/api/onlyoffice/forcesave?assetId=asset_1&key=doc_key_1",
    );
  });

  it("buildOnlyOfficeOpenFileId prefers asset id", () => {
    expect(
      buildOnlyOfficeOpenFileId({
        assetId: "asset_1",
        docKey: "doc_key_1",
        resolvedFileUrl: "https://app.example.com/file.docx",
        fileName: "file.docx",
      }),
    ).toBe("asset_1");
  });
});
