import { createHash } from "crypto";
import type { NormalizedCargo } from "@/modules/quote/types";

export type CargoHashInput = {
  pickupSerialized: string;
  deliverySerialized: string;
  weightLb: number;
  dimLIn: number;
  dimWIn: number;
  dimHIn: number;
  palletCount: number;
  cargoType: string;
  /** 登录态附加服务 / ready 纳入 hash，避免错价缓存 */
  loggedInExtras?: string;
};

/** 地址序列化为含 place_id 的标准 JSON（BR-4.4） */
export function serializeAddress(addr: {
  street: string;
  city: string;
  state: string;
  zip: string;
  place_id: string;
  mothership_option_id?: string;
}): string {
  return JSON.stringify({
    street: addr.street.trim(),
    city: addr.city.trim(),
    state: addr.state.trim().toUpperCase(),
    zip: addr.zip.trim(),
    place_id: addr.mothership_option_id?.trim() || addr.place_id,
  });
}

/** cargo_hash = MD5(pickup+delivery+weight_lb+dims+pallet_count+cargo_type[+loggedInExtras]) */
export function buildCargoHash(input: CargoHashInput): string {
  const parts = [
    input.pickupSerialized,
    input.deliverySerialized,
    input.weightLb.toFixed(2),
    input.dimLIn.toFixed(2),
    input.dimWIn.toFixed(2),
    input.dimHIn.toFixed(2),
    String(input.palletCount),
    input.cargoType,
  ];
  // 仅登录态附加字段存在时追加，保持匿名 hash 兼容
  if (input.loggedInExtras) {
    parts.push(input.loggedInExtras);
  }
  return createHash("md5").update(parts.join("|")).digest("hex");
}

export function buildLoggedInCargoHashExtras(input: {
  pickupAccessorials?: string[];
  deliveryAccessorials?: string[];
  readyDate?: string;
  readyTime?: string;
  cargoLines?: Array<{
    cargoType: string;
    quantity: number;
    weightLb: number;
    lengthIn: number;
    widthIn: number;
    heightIn: number;
  }>;
}): string | undefined {
  const pickup = [...(input.pickupAccessorials ?? [])]
    .map((s) => s.trim())
    .filter(Boolean)
    .sort();
  const delivery = [...(input.deliveryAccessorials ?? [])]
    .map((s) => s.trim())
    .filter(Boolean)
    .sort();
  const readyDate = input.readyDate?.trim() ?? "";
  const readyTime = input.readyTime?.trim() ?? "";
  const lines = (input.cargoLines ?? [])
    .map(
      (r) =>
        `${r.cargoType}:${r.quantity}:${r.weightLb}:${r.lengthIn}x${r.widthIn}x${r.heightIn}`,
    )
    .join(";");
  if (
    pickup.length === 0 &&
    delivery.length === 0 &&
    !readyDate &&
    !readyTime &&
    !lines
  ) {
    return undefined;
  }
  return `pa=${pickup.join(",")}|da=${delivery.join(",")}|rd=${readyDate}|rt=${readyTime}|cl=${lines}`;
}

export function buildCargoHashFromNormalized(cargo: NormalizedCargo): string {
  return buildCargoHash({
    pickupSerialized: cargo.pickupSerialized,
    deliverySerialized: cargo.deliverySerialized,
    weightLb: cargo.weightLb,
    dimLIn: cargo.dimLIn,
    dimWIn: cargo.dimWIn,
    dimHIn: cargo.dimHIn,
    palletCount: cargo.palletCount,
    cargoType: cargo.cargoType,
    loggedInExtras: buildLoggedInCargoHashExtras(cargo),
  });
}
