import * as XLSX from "xlsx";
import { describe, expect, it, vi } from "vitest";

import { parseMaterialsFromExcel } from "../../src/lib/materialImportParser.ts";
import { buildProcurementListExportWorkbook } from "./procurement-list-export-api.ts";

function makeExcelBuffer() {
  const workbook = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(workbook, XLSX.utils.aoa_to_sheet([
    ["名称", "数量", "单位", "发票种类", "收货地址", "规格型号"],
    ["塑料保护罩覆盖", 130000, "个", "13%专票", "江苏省南京市建邺区", "B1 级低烟无卤"],
  ]), "Sheet1");
  return Buffer.from(XLSX.write(workbook, { type: "buffer", bookType: "xlsx" }));
}

function mojibakeFileName(value: string) {
  return Buffer.from(value, "utf8").toString("latin1");
}

function makeExtractionPayload(sourceFileName: string) {
  const isExcel = sourceFileName.endsWith(".xlsx");
  return {
    file_profile: {
      source_file_name: sourceFileName,
      file_type: sourceFileName.endsWith(".pdf") ? "cad_drawing_pdf" : "excel",
      document_title: "塑料保护罩覆盖",
      drawing_no: "005A",
      page_count: 1,
      diagnostics: ["测试诊断"],
    },
    purchase_objects: [{
      object_role: "primary_item",
      original_name: isExcel ? "" : "塑料保护罩覆盖",
      recommended_name: isExcel ? "" : "螺栓孔塑料保护罩",
      fields: {
        specification: "盾构区间螺栓保护罩，B1 级低烟无卤",
        material_requirement: "低烟无卤原生材料",
        technical_requirement: "燃烧性能不低于 B1 级",
        test_requirement: "GB8624-2012 5.2.3",
        technical_standard: "GB8624-2012",
        applicable_conditions: "盾构区间",
        main_dimensions: "",
        tolerance: "",
        performance_indicators: sourceFileName.endsWith(".pdf") ? "氧指数 >=23" : "",
        accessory_materials: "",
        supply_form: "",
        acceptance_documents: "",
        quantity: isExcel ? 130000 : 0,
        unit: isExcel ? "个" : "",
        invoice_type: isExcel ? "13%专票" : "",
        delivery_address: isExcel ? "江苏省南京市建邺区" : "",
        remarks: "",
        pending_confirmations: [],
      },
      evidence: [{
        source_file_name: sourceFileName,
        source_type: sourceFileName.endsWith(".pdf") ? "pdf_render" : "excel",
        field: "specification",
        quote: "B1 级低烟无卤",
        page_number: sourceFileName.endsWith(".pdf") ? 1 : undefined,
        row_index: isExcel ? 1 : undefined,
        confidence: 0.9,
      }],
      warnings: [],
      confidence: 0.9,
    }],
    warnings: [],
  } as const;
}

describe("buildProcurementListExportWorkbook", () => {
  it("processes uploaded files without DB/storage and returns an import-compatible detailed xlsx", async () => {
    const buildPdfDiagnosticArtifacts = vi.fn(async () => ({
      profile: {
        source_file_name: "塑料保护罩覆盖.pdf",
        file_type: "cad_drawing_pdf",
        page_count: 1,
        file_size_bytes: 12,
        text_layer_char_count: 0,
        text_layer_sample: "",
        requires_visual_route: true,
        diagnostics: ["文本层较少，疑似 CAD/工程图纸型 PDF。"],
      },
      renders: [{ dataUrl: "data:image/png;base64,cGRm", pageNumber: 1, scale: 2, renderer: "pdfjs" }],
      trimmed_high_res: {
        dataUrl: "data:image/png;base64,dHJpbQ==",
        source: { width: 100, height: 100 },
        crop: { x: 0, y: 0, width: 100, height: 100 },
      },
    }));
    const extractProcurementListFromMultimodalInputs = vi.fn(async (input: { fileProfiles: Array<{ source_file_name?: string }> }) => ({
      model: "glm-5.1",
      provider: "glm",
      payload: makeExtractionPayload(input.fileProfiles[0]?.source_file_name ?? "unknown"),
    }));

    const result = await buildProcurementListExportWorkbook({
      files: [
        {
          originalname: mojibakeFileName("塑料保护罩覆盖.pdf"),
          mimetype: "application/pdf",
          size: 12,
          buffer: Buffer.from("%PDF-1.7"),
        },
        {
          originalname: mojibakeFileName("塑料保护罩覆盖.xlsx"),
          mimetype: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
          size: 128,
          buffer: makeExcelBuffer(),
        },
      ],
      buildPdfDiagnosticArtifacts,
      extractProcurementListFromMultimodalInputs,
    });

    expect(buildPdfDiagnosticArtifacts).toHaveBeenCalledTimes(1);
    expect(extractProcurementListFromMultimodalInputs).toHaveBeenCalledWith(expect.objectContaining({
      fileProfiles: expect.arrayContaining([expect.objectContaining({ source_file_name: "塑料保护罩覆盖.pdf" })]),
      imageInputs: expect.arrayContaining([expect.objectContaining({ source_file_name: "塑料保护罩覆盖.pdf" })]),
    }));
    expect(extractProcurementListFromMultimodalInputs).toHaveBeenCalledWith(expect.objectContaining({
      fileProfiles: expect.arrayContaining([expect.objectContaining({ source_file_name: "塑料保护罩覆盖.xlsx" })]),
      excelRows: expect.arrayContaining([expect.objectContaining({ source_file_name: "塑料保护罩覆盖.xlsx" })]),
    }));

    const workbook = XLSX.read(result.buffer, { type: "buffer" });
    expect(workbook.SheetNames).toEqual([
      "采购清单",
      "采购信息卡",
      "PDF诊断与区域",
      "字段证据",
      "待确认事项",
      "源文件审计",
    ]);

    const mainRows = XLSX.utils.sheet_to_json<Record<string, unknown>>(workbook.Sheets["采购清单"]);
    expect(mainRows).toEqual([
      expect.objectContaining({
        名称: "塑料保护罩覆盖",
        数量: 130000,
        单位: "个",
        发票种类: "13%专票",
        收货地址: "江苏省南京市建邺区",
      }),
    ]);
    expect(result.filename).toMatch(/^塑料保护罩覆盖-采购物料清单-\d{4}-\d{2}-\d{2}\.xlsx$/);

    const parsed = await parseMaterialsFromExcel({
      name: result.filename,
      arrayBuffer: async () => Uint8Array.from(result.buffer).buffer,
    } as File);
    expect(parsed[0]).toMatchObject({
      material_name: "塑料保护罩覆盖",
      quantity: 130000,
      unit: "个",
      invoice_type: "13%专票",
      delivery_address: "江苏省南京市建邺区",
    });
  });
});
