import { describe, expect, it } from "vitest";

import type { ParsedProduct, SearchPipelineConfig } from "../core/types.ts";
import { buildFixedSearchPlanRows, buildSearchPlanRows, buildSearchPlanRowsFromConfig } from "./keyword-generator.ts";

const PRODUCT: ParsedProduct = {
  material_id: "material-2",
  raw: {
    发票种类: "专票",
    名称: "不锈钢法兰",
    规格型号: "DN50 PN16",
    品牌: "沪工",
    数量: "10",
    单位: "个",
    "备注/附件": "304不锈钢",
    收货地址: "上海",
  },
  analysis: {
    material: "304不锈钢",
    usage: "",
    simplified_spec: "DN50 PN16",
    brand_term: "沪工",
    keyword_parameter_terms: ["304不锈钢"],
    modifier_terms: ["带孔"],
    alternative_terms: [],
  },
};

const STANDARDIZED_RESULT = {
  primary_search_term: "接地汇流铜排",
  alt_search_terms: ["铜排接地", "汇流铜排", ""],
  original_name: "铜排",
  standardized_name: "接地汇流铜排",
  original_spec: "50mm*50mm*5mm",
  standardized_spec: "50mm*50mm*5mm",
  brand: "沪工",
  category: "铜",
  quantity: 10,
  notes: "镀锡",
} as const;

describe("buildSearchPlanRows", () => {
  it("keeps the ai keyword as the first round before progressive fallback", () => {
    const rows = buildSearchPlanRows(PRODUCT, "法兰DN50");

    expect(rows[0]?.primary_keyword).toBe("法兰DN50");
    expect(rows[0]?.keyword_source).toBe("ai_semantic");
    expect(rows.at(-1)?.primary_keyword).toBe("不锈钢法兰");
  });
});

describe("buildSearchPlanRowsFromConfig", () => {
  it("builds configured rounds from standardized result fields and expands alternative terms", () => {
    const config: SearchPipelineConfig = {
      keywordSearchEnabled: true,
      imageSearchEnabled: true,
      keywordCombinations: [
        { fields: ["primary_search_term", "standardized_spec"], label: "主搜索词+标准化规格" },
        { fields: ["alt_search_terms", "brand"], label: "备用搜索词+品牌" },
        { fields: ["standardized_name", "quantity", "notes"], label: "标准化名称+数量+备注" },
      ],
      includeAiKeyword: false,
    };

    const rows = buildSearchPlanRowsFromConfig(PRODUCT, config, "法兰DN50", "", STANDARDIZED_RESULT);

    expect(rows.map((row) => row.primary_keyword)).toEqual([
      "接地汇流铜排 50mm*50mm*5mm",
      "铜排接地 沪工",
      "汇流铜排 沪工",
      "接地汇流铜排 10 镀锡",
    ]);
    expect(rows.map((row) => row.search_strategy)).toEqual([
      "configured_round_1",
      "configured_round_2",
      "configured_round_2",
      "configured_round_3",
    ]);
    expect(rows.every((row) => row.keyword_source === "progressive")).toBe(true);
  });

  it("skips configured rounds that only select empty alternative search terms", () => {
    const config: SearchPipelineConfig = {
      keywordSearchEnabled: true,
      imageSearchEnabled: true,
      keywordCombinations: [{ fields: ["alt_search_terms"], label: "备用搜索词" }],
      includeAiKeyword: false,
    };

    expect(buildSearchPlanRowsFromConfig(PRODUCT, config, "法兰DN50", "", {
      ...STANDARDIZED_RESULT,
      alt_search_terms: [],
    })).toEqual([]);
  });

  it("returns no search rows when keyword search is disabled", () => {
    const config: SearchPipelineConfig = {
      keywordSearchEnabled: false,
      imageSearchEnabled: true,
      keywordCombinations: [{ fields: ["standardized_name"], label: "标准化名称" }],
      includeAiKeyword: true,
    };

    expect(buildSearchPlanRowsFromConfig(PRODUCT, config, "法兰DN50")).toEqual([]);
  });
});

describe("buildFixedSearchPlanRows", () => {
  it("builds the fixed 7 runtime rounds from standardized fields", () => {
    const result = buildFixedSearchPlanRows(PRODUCT, "法兰DN50", "", STANDARDIZED_RESULT);

    expect(result.searchPlanRows.map((row) => row.search_round)).toEqual([1, 3, 4, 5, 6, 7]);
    expect(result.searchPlanRows.map((row) => row.primary_keyword)).toEqual([
      "接地汇流铜排",
      "接地汇流铜排 沪工",
      "沪工 接地汇流铜排",
      "接地汇流铜排 50mm*50mm*5mm",
      "50mm*50mm*5mm 接地汇流铜排",
      "接地汇流铜排 铜",
    ]);
    expect(result.roundStatuses.map((status) => status.status)).toEqual([
      "success",
      "duplicate_skip",
      "success",
      "success",
      "success",
      "success",
      "success",
    ]);
    expect(result.roundStatuses[2]?.search_strategy).toBe("fixed_round_3");
  });

  it("marks missing and duplicate rounds in the runtime audit status file", () => {
    const result = buildFixedSearchPlanRows(PRODUCT, "不锈钢法兰", "", {
      ...STANDARDIZED_RESULT,
      primary_search_term: "不锈钢法兰",
      standardized_name: "不锈钢法兰",
      brand: "",
      standardized_spec: "",
      category: "--",
    });

    expect(result.searchPlanRows.map((row) => row.search_round)).toEqual([1]);
    expect(result.roundStatuses.map((status) => ({ round: status.round, status: status.status }))).toEqual([
      { round: 1, status: "success" },
      { round: 2, status: "duplicate_skip" },
      { round: 3, status: "failed" },
      { round: 4, status: "failed" },
      { round: 5, status: "failed" },
      { round: 6, status: "failed" },
      { round: 7, status: "failed" },
    ]);
    expect(result.roundStatuses[1]?.failure_reason).toContain("重复");
    expect(result.roundStatuses[2]?.failure_reason).toContain("品牌为空");
    expect(result.roundStatuses[6]?.failure_reason).toContain("分类(材质/用途)为空");
  });
});