import { describe, expect, it } from "vitest";
import {
  MOTHERSHIP_LIMITS,
  validateQuoteInput,
  rejectQuantityField,
} from "@/modules/quote/validation";
import { ValidationError } from "@/modules/quote/types";
import {
  MOTHERSHIP_DELIVERY_CONFIRMED,
  MOTHERSHIP_PICKUP_CONFIRMED,
} from "@/__tests__/fixtures/mothership-address";

const VALID_BODY = {
  request_id: "550e8400-e29b-41d4-a716-446655440000",
  customer_id: "CUST_001",
  pickup_address: {
    street: "1234 Warehouse Blvd",
    city: "Los Angeles",
    state: "CA",
    zip: "90001",
    place_id: "ChIJ_pickup",
    formatted_address: "1234 Warehouse Blvd, Los Angeles, CA 90001, USA",
    selected_from_suggestions: true,
    ...MOTHERSHIP_PICKUP_CONFIRMED,
  },
  delivery_address: {
    street: "5678 Distribution Dr",
    city: "Dallas",
    state: "TX",
    zip: "75201",
    place_id: "ChIJ_delivery",
    formatted_address: "5678 Distribution Dr, Dallas, TX 75201, USA",
    selected_from_suggestions: true,
    ...MOTHERSHIP_DELIVERY_CONFIRMED,
  },
  weight: { value: 500, unit: "lb" },
  dimensions: { length: 48, width: 40, height: 48, unit: "in" },
  pallet_count: 2,
  cargo_type: "general_freight",
};

describe("validateQuoteInput", () => {
  it("正常入参通过", () => {
    const result = validateQuoteInput(VALID_BODY);
    expect(result.cargoHash).toHaveLength(32);
    expect(result.weightLb).toBe(500);
  });

  it("TC-201：weight 缺失 → VALIDATION_FAILED", () => {
    const { weight: _w, ...rest } = VALID_BODY;
    expect(() => validateQuoteInput(rest)).toThrow(ValidationError);
  });

  it("TC-202：weight=0 → 无效", () => {
    expect(() =>
      validateQuoteInput({
        ...VALID_BODY,
        weight: { value: 0, unit: "lb" },
      }),
    ).toThrow(/有效的重量|超出 Mothership/);
  });

  it("空邮编通过（MotherShip 不要求填写邮编）", () => {
    const result = validateQuoteInput({
      ...VALID_BODY,
      pickup_address: { ...VALID_BODY.pickup_address, zip: "" },
      delivery_address: { ...VALID_BODY.delivery_address, zip: "" },
    });
    expect(result.cargoHash).toHaveLength(32);
  });

  it("TC-203：zip 4 位 → 无效", () => {
    expect(() =>
      validateQuoteInput({
        ...VALID_BODY,
        pickup_address: {
          ...VALID_BODY.pickup_address,
          zip: "9001",
        },
      }),
    ).toThrow(/邮编/);
  });

  it("TC-204：request_id 非 UUID → 无效", () => {
    expect(() =>
      validateQuoteInput({ ...VALID_BODY, request_id: "not-uuid" }),
    ).toThrow("请求标识无效");
  });

  it("E4.3：selected_from_suggestions=false", () => {
    expect(() =>
      validateQuoteInput({
        ...VALID_BODY,
        pickup_address: {
          ...VALID_BODY.pickup_address,
          selected_from_suggestions: false,
        },
      }),
    ).toThrow(ValidationError);
  });

  it("未确认 MotherShip 精确地址 → 拒绝询价", () => {
    const { mothership_option_id: _a, mothership_display_label: _b, selected_from_mothership: _c, ...pickup } =
      VALID_BODY.pickup_address;
    expect(() =>
      validateQuoteInput({
        ...VALID_BODY,
        pickup_address: pickup,
      }),
    ).toThrow(ValidationError);
  });

  it("E4.7：quantity 字段拒绝", () => {
    expect(() =>
      rejectQuantityField({ ...VALID_BODY, quantity: 5 }),
    ).toThrow("请使用托盘数 pallet_count");
  });

  it("E4.6：pallet_count 超 25", () => {
    expect(() =>
      validateQuoteInput({ ...VALID_BODY, pallet_count: 26 }),
    ).toThrow(/托盘数超出/);
  });

  it("E4.6：单托重量超 9999", () => {
    expect(() =>
      validateQuoteInput({
        ...VALID_BODY,
        weight: { value: 10_000, unit: "lb" },
      }),
    ).toThrow(/重量超出/);
  });

  it("E4.6：长度超 999 in", () => {
    expect(() =>
      validateQuoteInput({
        ...VALID_BODY,
        dimensions: { length: 1000, width: 40, height: 48, unit: "in" },
      }),
    ).toThrow(/尺寸超出/);
  });

  it("边界：25 托、9999 lb、999×99×99 in 通过", () => {
    const result = validateQuoteInput({
      ...VALID_BODY,
      weight: { value: 9_999, unit: "lb" },
      dimensions: { length: 999, width: 99, height: 99, unit: "in" },
      pallet_count: 25,
    });
    expect(result.palletCount).toBe(25);
  });

  it("SQL 注入拦截", () => {
    expect(() =>
      validateQuoteInput({
        ...VALID_BODY,
        pickup_address: {
          ...VALID_BODY.pickup_address,
          street: "'; DROP TABLE users; --",
        },
      }),
    ).toThrow(/无效，请检查/);
  });

  it("kg/cm 换算并向上取整", () => {
    const result = validateQuoteInput({
      ...VALID_BODY,
      weight: { value: 227, unit: "kg" },
      dimensions: { length: 120, width: 100, height: 100, unit: "cm" },
    });
    expect(result.weightLb).toBe(501);
    expect(result.dimLIn).toBe(48);
    expect(result.dimWIn).toBe(40);
    expect(result.dimHIn).toBe(40);
  });

  it("500 kg 换算为 1103 lb", () => {
    const result = validateQuoteInput({
      ...VALID_BODY,
      weight: { value: 500, unit: "kg" },
    });
    expect(result.weightLb).toBe(1103);
  });

  it("0.5 t 换算为 1103 lb", () => {
    const result = validateQuoteInput({
      ...VALID_BODY,
      weight: { value: 0.5, unit: "t" },
    });
    expect(result.weightLb).toBe(1103);
  });

  it("1.2 m 尺寸换算并向上取整", () => {
    const result = validateQuoteInput({
      ...VALID_BODY,
      dimensions: { length: 1.2, width: 1, height: 1, unit: "m" },
    });
    expect(result.dimLIn).toBe(48);
    expect(result.dimWIn).toBe(40);
    expect(result.dimHIn).toBe(40);
  });

  it("拒绝 ton/tons 歧义单位", () => {
    expect(() =>
      validateQuoteInput({
        ...VALID_BODY,
        weight: { value: 0.5, unit: "ton" },
      }),
    ).toThrow(/歧义/);
  });

  it("拒绝 Infinity 重量", () => {
    expect(() =>
      validateQuoteInput({
        ...VALID_BODY,
        weight: { value: Number.POSITIVE_INFINITY, unit: "lb" },
      }),
    ).toThrow(ValidationError);
  });
});

describe("MOTHERSHIP_LIMITS", () => {
  it("托盘 1-25", () => {
    expect(MOTHERSHIP_LIMITS.palletCount.max).toBe(25);
  });
});
