import { describe, expect, it } from "vitest";
import {
  addressInputMatchesQuery,
  arrowDownCountForPacIndex,
  buildAddressAutocompleteQueries,
  buildAddressBindingLabels,
  buildAddressEnumerationQueries,
  extractStreetFromLabel,
  formatAddressQuery,
  formatMothershipFormattedAddress,
  isMotherShipEchoCandidate,
  isMotherShipEnumerationRowForTest,
  labelToCandidate,
  resolveAddressAutocompleteInput,
  scoreSuggestionLabelMatch,
} from "@/workers/rpa/address-suggestions";

const laQuery = {
  street: "1234 Warehouse Blvd",
  city: "Los Angeles",
  state: "CA",
  zip: "90001",
};

describe("address-suggestions", () => {
  it("addressInputMatchesQuery：已有等效文案时不应再 fill 清空", () => {
    expect(
      addressInputMatchesQuery(
        "293 Pike St, Seattle, Washington",
        "293 Pike St, Seattle, WA, USA",
      ),
    ).toBe(true);
    expect(addressInputMatchesQuery("", "293 Pike St")).toBe(false);
    expect(
      addressInputMatchesQuery("123 Main", "456 Oak Ave, Dallas, TX, USA"),
    ).toBe(false);
  });

  it("arrowDownCountForPacIndex：Google Places 默认高亮首项，index 0 无需 ArrowDown", () => {
    expect(arrowDownCountForPacIndex(0)).toBe(0);
    expect(arrowDownCountForPacIndex(1)).toBe(1);
    expect(arrowDownCountForPacIndex(2)).toBe(2);
  });

  it("formatAddressQuery 不含邮编（仅街道+城市+州+国家）", () => {
    expect(formatAddressQuery(laQuery)).toBe(
      "1234 Warehouse Blvd, Los Angeles, CA, USA",
    );
  });

  it("formatAddressQuery 无 zip 字段时仍含国家", () => {
    expect(
      formatAddressQuery({ street: "1 Main", city: "Austin", state: "TX", zip: "" }),
    ).toBe("1 Main, Austin, TX, USA");
  });

  it("formatMothershipFormattedAddress 不含邮编", () => {
    expect(
      formatMothershipFormattedAddress(
        "1234 Warehouse Street",
        "Los Angeles",
        "CA",
      ),
    ).toBe("1234 Warehouse Street, Los Angeles, CA, USA");
  });

  it("pipe 副行含 USA 时州码取 TX 而非 USA", () => {
    const item = labelToCandidate(
      "5678 Distribution Dr|Garland, Dallas, TX, USA",
      {
        street: "5678 Distribution Dr",
        city: "Dallas",
        state: "TX",
        zip: "75201",
      },
    );
    expect(item?.city).toBe("Garland");
    expect(item?.state).toBe("TX");
    expect(item?.display_label).toBe("5678 Distribution DrGarland, TX");
  });

  it("无法解析时不回退用户输入街道", () => {
    expect(
      labelToCandidate("invalid short", {
        street: "5678 Distribution Dr",
        city: "Dallas",
        state: "TX",
        zip: "75201",
      }),
    ).toBeNull();
  });

  it("仅街道行联想可补全 city/state（Warehouse Street/Avenue）", () => {
    const query = {
      street: "1234 Warehouse Blvd",
      city: "Los Angeles",
      state: "CA",
      zip: "90001",
    };
    const street = labelToCandidate("1234 Warehouse Street", query);
    const avenue = labelToCandidate("1234 Warehouse Avenue", query);
    expect(street?.street).toBe("1234 Warehouse Street");
    expect(avenue?.street).toBe("1234 Warehouse Avenue");
    expect(street?.city).toBe("Los Angeles");
    expect(isMotherShipEchoCandidate(street!, query)).toBe(false);
    expect(street?.option_id).not.toBe(avenue?.option_id);
  });

  it("pipe 联想主行等于 streetToken 时仍应保留（Garland 等副行）", () => {
    const query = {
      street: "5678 Distribution Dr",
      city: "Dallas",
      state: "TX",
      zip: "75201",
    };
    expect(isMotherShipEnumerationRowForTest("5678 Distribution Dr|Garland, Texas, USA", query)).toBe(true);
    expect(isMotherShipEnumerationRowForTest("5678 Distribution Dr|Wilmer, TX, USA", query)).toBe(true);
    expect(isMotherShipEnumerationRowForTest("5678 Distribution Dr|Dallas, TX, USA", query)).toBe(false);
  });

  it("不同街道名不算 echo（Warehouse Street vs Blvd）", () => {
    const item = labelToCandidate(
      "1234 Warehouse Street|Los Angeles, California, USA",
      {
        street: "1234 Warehouse Blvd",
        city: "Los Angeles",
        state: "CA",
        zip: "90001",
      },
    );
    expect(item).not.toBeNull();
    if (item) {
      expect(
        isMotherShipEchoCandidate(item, {
          street: "1234 Warehouse Blvd",
          city: "Los Angeles",
          state: "CA",
          zip: "90001",
        }),
      ).toBe(false);
    }
  });

  it("isMotherShipEchoCandidate 识别用户输入回显", () => {
    const echo = labelToCandidate(
      "5678 Distribution Dr|Dallas, TX, USA",
      {
        street: "5678 Distribution Dr",
        city: "Dallas",
        state: "TX",
        zip: "75201",
      },
    );
    expect(echo).not.toBeNull();
    if (echo) {
      expect(
        isMotherShipEchoCandidate(echo, {
          street: "5678 Distribution Dr",
          city: "Dallas",
          state: "TX",
          zip: "75201",
        }),
      ).toBe(true);
    }
    const real = labelToCandidate(
      "5678 Distribution Dr|Garland, Dallas, TX, USA",
      {
        street: "5678 Distribution Dr",
        city: "Dallas",
        state: "TX",
        zip: "75201",
      },
    );
    expect(real).not.toBeNull();
    if (real) {
      expect(
        isMotherShipEchoCandidate(real, {
          street: "5678 Distribution Dr",
          city: "Dallas",
          state: "TX",
          zip: "75201",
        }),
      ).toBe(false);
    }
  });

  it("buildAddressEnumerationQueries 完整 query 优先（含 USA）", () => {
    expect(
      buildAddressEnumerationQueries({
        street: "5678 Distribution Dr",
        city: "Dallas",
        state: "TX",
        zip: "75201",
      })[0],
    ).toBe("5678 Distribution Dr, Dallas, TX, USA");
  });

  it("enrichCandidateFromQuery 联想缺门牌时补全用户 street", () => {
    const item = labelToCandidate("Distribution WayFarmers Branch, TX", {
      street: "5678 Distribution Way",
      city: "Farmers Branch",
      state: "TX",
      zip: "",
    });
    expect(item?.street).toBe("5678 Distribution Way");
    expect(item?.display_label).toContain("5678");
    expect(item?.formatted_address).toContain("5678 Distribution Way");
  });

  it("buildAddressBindingLabels 完整街道优先于粘连 label", () => {
    const labels = buildAddressBindingLabels(
      {
        street: "5678 Distribution Way",
        city: "Farmers Branch",
        state: "TX",
        zip: "",
      },
      "Distribution WayFarmers Branch, TX",
    );
    expect(labels[0]).toBe("5678 Distribution Way, Farmers Branch, TX");
    expect(labels).toContain("Distribution WayFarmers Branch, TX");
  });

  it("pac-item 结构化标签保留 suburb 差异", () => {
    const garland = labelToCandidate(
      "5678 Distribution Dr|Garland, Dallas, TX, USA",
      {
        street: "5678 Distribution Dr",
        city: "Dallas",
        state: "TX",
        zip: "75201",
      },
    );
    const wilmer = labelToCandidate(
      "5678 Distribution Dr|Wilmer, Dallas, TX, USA",
      {
        street: "5678 Distribution Dr",
        city: "Dallas",
        state: "TX",
        zip: "75201",
      },
    );
    expect(garland?.city).toBe("Garland");
    expect(wilmer?.city).toBe("Wilmer");
    expect(garland?.display_label).not.toBe(wilmer?.display_label);
  });

  it("粘连 innerText 解析 suburb（Farmers Branch）", () => {
    const item = labelToCandidate(
      "5678 Distribution Way Farmers Branch, Dallas, TX, USA",
      {
        street: "5678 Distribution Dr",
        city: "Dallas",
        state: "TX",
        zip: "75201",
      },
    );
    expect(item?.street).toBe("5678 Distribution Way");
    expect(item?.city).toBe("Farmers Branch");
    expect(item?.display_label).toContain("Farmers Branch");
  });

  it("解析粘连格式（录制 112133）", () => {
    const item = labelToCandidate(
      "1234 Warehouse StreetLos Angeles, CA",
      laQuery,
    );
    expect(item?.street).toBe("1234 Warehouse Street");
    expect(item?.city).toBe("Los Angeles");
    expect(item?.state).toBe("CA");
    expect(item?.zip).toBe("90001");
    expect(item?.display_label).toBe("1234 Warehouse StreetLos Angeles, CA");
    expect(item?.formatted_address).toBe(
      "1234 Warehouse Street, Los Angeles, CA, USA",
    );
  });

  it("候选 zip 从用户输入补全", () => {
    const item = labelToCandidate("5678 Distribution DrEagle Pass, TX", {
      street: "5678 Distribution Dr",
      city: "Dallas",
      state: "TX",
      zip: "75201",
    });
    expect(item?.zip).toBe("75201");
    expect(item?.display_label).not.toMatch(/\d{5}/);
  });

  it("scoreSuggestionLabelMatch 对齐 USA/粘连差异", () => {
    const userLabel = "1234 Warehouse Street Los Angeles, CA, USA";
    const domLabel = "1234 Warehouse StreetLos Angeles, CA";
    expect(scoreSuggestionLabelMatch(userLabel, domLabel, laQuery)).toBeGreaterThanOrEqual(
      90,
    );
  });

  it("scoreSuggestionLabelMatch 区分 West Seattle 与 Western Ave", () => {
    const query = {
      street: "3131 Western Avenue",
      city: "West Seattle",
      state: "WA",
      zip: "",
    };
    const userLabel = "3131 Western AvenueWest Seattle, WA";
    const wrongDom = "3131 Western Ave Seattle, WA, USA";
    const rightDom = "3131 Western Avenue West Seattle, WA, USA";
    expect(scoreSuggestionLabelMatch(userLabel, wrongDom, query)).toBeLessThan(
      scoreSuggestionLabelMatch(userLabel, rightDom, query),
    );
  });

  it("解析无门牌号街道（Fifth Avenue / Hollywood Boulevard）", () => {
    const fifth = labelToCandidate("Fifth Avenue New York, NY, USA", {
      street: "Fifth Avenue",
      city: "New York",
      state: "NY",
      zip: "",
    });
    expect(fifth?.street).toBe("Fifth Avenue");
    expect(fifth?.city).toBe("New York");
    expect(fifth?.state).toBe("NY");

    const hollywood = labelToCandidate(
      "Hollywood Boulevard Los Angeles, CA, USA",
      {
        street: "Hollywood Boulevard",
        city: "Los Angeles",
        state: "CA",
        zip: "",
      },
    );
    expect(hollywood?.street).toBe("Hollywood Boulevard");
    expect(hollywood?.city).toBe("Los Angeles");
  });

  it("normalizeParsedStreet 去除误并入街道的城市名", () => {
    const item = labelToCandidate(
      "5678 Distribution Dr Garland, Dallas, TX",
      {
        street: "5678 Distribution Dr",
        city: "Dallas",
        state: "TX",
        zip: "75201",
      },
    );
    expect(item?.street).toBe("5678 Distribution Dr");
    expect(item?.city).toBe("Garland");
  });

  it("buildAddressAutocompleteQueries preferConfirmedLabel 时完整 POI 标签优先", () => {
    const queries = buildAddressAutocompleteQueries(
      {
        street: "Washington State Convention Center Main Garage, Pike Street",
        city: "Seattle",
        state: "WA",
        zip: "",
      },
      {
        mothershipLabel:
          "Washington State Convention Center Main Garage, Pike Street, Seattle, Washington, USA",
        preferConfirmedLabel: true,
      },
    );
    expect(queries[0]).toBe(
      "Washington State Convention Center Main Garage, Pike Street, Seattle, Washington",
    );
  });

  it("buildAddressAutocompleteQueries 从 mothershipLabel 提取纯街道查询（触发多候选联想）", () => {
    const queries = buildAddressAutocompleteQueries(
      {
        street: "La Concha Key West, Autograph Collection Duval Street",
        city: "Key West",
        state: "FL",
        zip: "",
      },
      { mothershipLabel: "La Concha Key West, Autograph Collection, Duval Street, Key West, FL" },
    );
    expect(queries[0]).toBe("Duval Street, Key West, FL, USA");
    expect(queries[1]).toBe("Duval Street, Key West, FL");
    const poiIdx = queries.indexOf(
      "La Concha Key West, Autograph Collection Duval Street, Key West, FL, USA",
    );
    expect(poiIdx).toBeGreaterThan(1);
  });

  it("extractStreetFromLabel 处理 POI 与街道粘连（无逗号）", () => {
    expect(
      extractStreetFromLabel(
        "La Concha Key West, Autograph Collection Duval Street, FL",
      ),
    ).toBe("Duval Street");
  });

  it("resolveAddressAutocompleteInput 用纯街道替换 POI street", () => {
    const resolved = resolveAddressAutocompleteInput(
      {
        street: "La Concha Key West, Autograph Collection Duval Street",
        city: "Key West",
        state: "FL",
        zip: "",
      },
      {
        mothershipLabel:
          "La Concha Key West, Autograph Collection Duval Street, FL",
      },
    );
    expect(resolved.street).toBe("Duval Street");
  });

  it("buildAddressAutocompleteQueries 无 mothershipLabel 时保留原有行为", () => {
    const queries = buildAddressAutocompleteQueries({
      street: "5678 Distribution Dr",
      city: "Dallas",
      state: "TX",
      zip: "75201",
    });
    expect(queries[0]).toBe("5678 Distribution Dr, Dallas, TX, USA");
  });

  it("buildAddressAutocompleteQueries 处理粘连格式 mothershipLabel", () => {
    const queries = buildAddressAutocompleteQueries(
      {
        street: "3131 Western AvenueWest Seattle",
        city: "West Seattle",
        state: "WA",
        zip: "",
      },
      { mothershipLabel: "3131 Western AvenueWest Seattle, WA" },
    );
    expect(queries[0]).toBe("3131 Western Avenue, West Seattle, WA, USA");
  });
});
