import { beforeEach, describe, expect, it, vi } from "vitest";
import { fetchAxelQuoteItems } from "@/lib/axel/quote-from-request";
import { AxelHttpClient } from "@/lib/axel/client";
import { pickBestSearchCandidate } from "@/lib/axel/pick-candidate";
import { buildAxelShipmentPayload } from "@/lib/axel/shipment";
import { parseQuoteCliArgs } from "@/lib/axel/parse-cli-args";
import { AXEL_QUOTE_BODY } from "__tests__/fixtures/axel-quote";

describe("parseQuoteCliArgs", () => {
  it("解析必填参数", () => {
    const args = parseQuoteCliArgs([
      "--origin",
      "3131 Western Ave, Seattle, WA",
      "--dest",
      "123 Main St, Los Angeles, CA",
      "--pallets",
      "2",
      "--weight",
      "500",
    ]);
    expect(args.origin).toContain("Seattle");
    expect(args.pallets).toBe(2);
    expect(args.weightLb).toBe(500);
  });

  it("缺少 origin 时抛错", () => {
    expect(() =>
      parseQuoteCliArgs(["--dest", "x", "--pallets", "1", "--weight", "100"]),
    ).toThrow(/--origin/);
  });
});

describe("pickBestSearchCandidate", () => {
  it("优先匹配门牌号", () => {
    const picked = pickBestSearchCandidate("3131 Western Ave, Seattle, WA", [
      {
        placeId: "ChIJ-other",
        description: "Western Avenue, Seattle, WA, USA",
        mainText: "Western Avenue",
      },
      {
        placeId: "ChIJ-good",
        description: "3131 Western Avenue, Seattle, WA, USA",
        mainText: "3131 Western Avenue",
      },
    ]);
    expect(picked?.placeId).toBe("ChIJ-good");
  });

  it("门牌号查询不选泛化 route", () => {
    const picked = pickBestSearchCandidate(
      "123 Main St, Los Angeles, CA 90001",
      [
        {
          placeId: "ChIJ-good",
          description: "123 Main Street, Los Angeles, CA, USA",
          mainText: "123 Main Street",
        },
        {
          placeId: "Eh1-route",
          description: "Main St, Los Angeles, CA, USA",
          mainText: "Main St",
          types: ["geocode", "route"],
        },
      ],
    );
    expect(picked?.placeId).toBe("ChIJ-good");
  });
});

describe("buildAxelShipmentPayload", () => {
  it("生成 shipment 含 cargo 与 autocompleteResult", () => {
    const shipment = buildAxelShipmentPayload({
      pickup: { placeId: "ChIJ-pickup", street: "1 Main" },
      delivery: { placeId: "ChIJ-delivery", street: "2 Oak" },
      pickupDescription: "1 Main St, Seattle, WA",
      deliveryDescription: "2 Oak Ave, Miami, FL",
      cargo: {
        palletCount: 2,
        weightLb: 500,
        lengthIn: 48,
        widthIn: 40,
        heightIn: 45,
      },
    });
    expect(shipment.pickupDate).toMatch(/T19:00:00\.000Z$/);
    const pickup = shipment.pickupLocation as Record<string, unknown>;
    expect(pickup.autocompleteResult).toBeTruthy();
    expect(Object.keys(shipment.cargo as object)).toHaveLength(1);
  });
});

describe("fetchAxelQuoteItems", () => {
  beforeEach(() => {
    vi.restoreAllMocks();
  });

  it("已知 placeId 时每侧只 fetchPlace 一次", async () => {
    const client = {
      fetchPlace: vi
        .fn()
        .mockResolvedValueOnce({ placeId: "ChIJ-pickup" })
        .mockResolvedValueOnce({ placeId: "ChIJ-delivery" }),
      searchLocation: vi.fn(),
      postQuote: vi.fn().mockResolvedValue(AXEL_QUOTE_BODY),
    };

    vi.spyOn(AxelHttpClient, "create").mockResolvedValue(
      client as unknown as AxelHttpClient,
    );

    const items = await fetchAxelQuoteItems({
      pickup: {
        street: "1 Main St",
        city: "Seattle",
        state: "WA",
        zip: "98101",
        mothershipOptionId: "ChIJ-pickup",
      },
      delivery: {
        street: "2 Oak Ave",
        city: "Miami",
        state: "FL",
        zip: "33101",
        mothershipOptionId: "ChIJ-delivery",
      },
      palletCount: 2,
      weightLb: 500,
      dimsIn: { l: 48, w: 40, h: 45 },
    });

    expect(items).toHaveLength(4);
    expect(client.fetchPlace).toHaveBeenCalledTimes(2);
    expect(client.searchLocation).not.toHaveBeenCalled();
    expect(client.postQuote).toHaveBeenCalledTimes(1);
  });
});
