/**
 * Priority1 表单填写规则与站点硬限制（RPA / 系统联调 / canonical 用例校验）
 * 来源：form-logic-map 探测、批量验收、人工录制与页面校验文案
 */

import type { Priority1DemoInput } from "@/workers/rpa/priority1/demo-input";
import type {
  ExpeditedTrailerType,
  FtlTrailerType,
  Priority1ShipmentType,
} from "@/workers/rpa/priority1/shipment-types";
import { expeditedLiftgateAvailable } from "@/workers/rpa/priority1/shipment-types";

export type Priority1ConstraintSeverity = "error" | "warning";

export type Priority1ConstraintViolation = {
  severity: Priority1ConstraintSeverity;
  code: string;
  message: string;
  field?: string;
};

/** 互斥与结构规则（选 A 则不能/不必选 B） */
export const PRIORITY1_MUTEX_RULES: readonly {
  id: string;
  rule: string;
}[] = [
  {
    id: "shipment_type_one",
    rule: "Step1 运输类型三选一：LTL / FTL / Expedited，不可多选",
  },
  {
    id: "ftl_trailer_one",
    rule: "FTL Step2 主拖车四选一：Dry Van / Open Deck / Temperature Controlled / Expedited（内嵌）",
  },
  {
    id: "expedited_trailer_one",
    rule: "Expedited 主类型 Step2 拖车三选一：Sprinter / Small Straight / Large Straight",
  },
  {
    id: "ftl_expedited_sub_one",
    rule: "FTL 内嵌 Expedited 须再选子车型三选一（同 Expedited 三卡）",
  },
  {
    id: "open_deck_requires_subtype",
    rule: "选 Open Deck 后必须选 Open Deck Type（#PickupLocation3），否则无法继续",
  },
  {
    id: "temp_requires_range",
    rule: "选 Temperature Controlled 后必须填最低/最高温度（°F）",
  },
  {
    id: "liftgate_large_only",
    rule: "Liftgate 仅在选择 Large Straight Box Truck 时出现且有意义（Expedited 主类型或 FTL 内嵌 Expedited）",
  },
  {
    id: "no_pallets_expedited",
    rule: "Expedited 主类型与 FTL 内嵌 Expedited 无 Number of Pallets 字段",
  },
  {
    id: "ftl_non_expedited_has_pallets",
    rule: "FTL Dry Van / Open Deck / Temperature 须填托盘数",
  },
  {
    id: "zip_distinct",
    rule: "起运 ZIP 与目的 ZIP 不能相同",
  },
];

/** 重量/托盘硬上限（超限时站点拦截提交或无法即时报价） */
export const PRIORITY1_WEIGHT_LIMITS: Record<
  string,
  { maxLb: number; minLb?: number; maxPallets?: number; siteMessage?: string }
> = {
  "expedited:sprinter_van": {
    minLb: 1,
    maxLb: 3500,
    siteMessage: "Sprinter 卡片标注约 3500 lb 上限",
  },
  "expedited:small_straight": {
    minLb: 1,
    maxLb: 8000,
  },
  "expedited:large_straight": {
    minLb: 1,
    maxLb: 10000,
    maxPallets: 14,
    siteMessage:
      "Expedited shipments must be 10,000 lbs or less; for overweight choose Full Truckload – Dry Van with Team Drivers",
  },
  "ftl:dry_van": { minLb: 1, maxLb: 45000, maxPallets: 26 },
  "ftl:open_deck": { minLb: 1, maxLb: 45000, maxPallets: 22 },
  "ftl:temperature_controlled": { minLb: 1, maxLb: 40000, maxPallets: 24 },
  /** FTL 内嵌 Expedited 子车型沿用 Expedited 拖车重量规则 */
  "ftl_expedited:sprinter_van": { minLb: 1, maxLb: 3500 },
  "ftl_expedited:small_straight": { minLb: 1, maxLb: 8000 },
  "ftl_expedited:large_straight": { minLb: 1, maxLb: 10000, maxPallets: 14 },
};

function weightKey(
  shipmentType: Priority1ShipmentType,
  ftlTrailer?: FtlTrailerType,
  expeditedTrailer?: ExpeditedTrailerType,
): string | null {
  if (shipmentType === "expedited" && expeditedTrailer) {
    return `expedited:${expeditedTrailer}`;
  }
  if (shipmentType === "ftl" && ftlTrailer === "ftl_expedited" && expeditedTrailer) {
    return `ftl_expedited:${expeditedTrailer}`;
  }
  if (shipmentType === "ftl" && ftlTrailer && ftlTrailer !== "ftl_expedited") {
    return `ftl:${ftlTrailer}`;
  }
  return null;
}

/** 校验 canonical / API 入参是否违反已知站点规则 */
export function validatePriority1FormConstraints(
  demo: Priority1DemoInput,
): Priority1ConstraintViolation[] {
  const out: Priority1ConstraintViolation[] = [];
  const zipOk = /^\d{5}$/;

  if (!zipOk.test(demo.originZip) || !zipOk.test(demo.destinationZip)) {
    out.push({
      severity: "error",
      code: "ZIP_FORMAT",
      message: "ZIP 须为 5 位数字",
      field: "originZip",
    });
  }
  if (demo.originZip === demo.destinationZip) {
    out.push({
      severity: "error",
      code: "ZIP_SAME",
      message: "起运与目的 ZIP 不能相同",
      field: "destinationZip",
    });
  }

  if (demo.shipmentType === "ftl" && demo.ftlTrailer === "open_deck" && !demo.openDeckSubtype?.trim()) {
    out.push({
      severity: "error",
      code: "OPEN_DECK_SUBTYPE",
      message: "Open Deck 必须选择子类型",
      field: "openDeckSubtype",
    });
  }

  if (demo.shipmentType === "ftl" && demo.ftlTrailer === "temperature_controlled") {
    if (!demo.tempMinF?.trim() || !demo.tempMaxF?.trim()) {
      out.push({
        severity: "error",
        code: "TEMP_RANGE",
        message: "温控须填写最低与最高温度",
        field: "tempMinF",
      });
    } else if (Number(demo.tempMinF) > Number(demo.tempMaxF)) {
      out.push({
        severity: "error",
        code: "TEMP_ORDER",
        message: "最低温度不能高于最高温度",
        field: "tempMinF",
      });
    }
  }

  if (
    demo.expeditedLiftgate &&
    !expeditedLiftgateAvailable(
      demo.shipmentType === "ftl"
        ? demo.ftlExpeditedTrailer
        : demo.expeditedTrailer,
    )
  ) {
    out.push({
      severity: "error",
      code: "LIFTGATE_TRAILER",
      message: "Liftgate 仅适用于 Large Straight Box Truck",
      field: "expeditedLiftgate",
    });
  }

  const wKey = weightKey(
    demo.shipmentType,
    demo.ftlTrailer,
    demo.shipmentType === "ftl" ? demo.ftlExpeditedTrailer : demo.expeditedTrailer,
  );
  const weight = Number(demo.weightLb);
  if (wKey && Number.isFinite(weight)) {
    const lim = PRIORITY1_WEIGHT_LIMITS[wKey];
    if (lim) {
      if (lim.minLb != null && weight < lim.minLb) {
        out.push({
          severity: "warning",
          code: "WEIGHT_LOW",
          message: `${wKey} 建议重量 ≥ ${lim.minLb} lb`,
          field: "weightLb",
        });
      }
      if (weight > lim.maxLb) {
        out.push({
          severity: "error",
          code: "WEIGHT_MAX",
          message: `重量 ${weight} lb 超过 ${wKey} 上限 ${lim.maxLb} lb${lim.siteMessage ? `（${lim.siteMessage}）` : ""}`,
          field: "weightLb",
        });
      }
    }
  }

  if (
    demo.shipmentType === "ftl" &&
    demo.ftlTrailer !== "ftl_expedited" &&
    demo.palletCount
  ) {
    const pallets = Number(demo.palletCount);
    const lim = PRIORITY1_WEIGHT_LIMITS[`ftl:${demo.ftlTrailer}`];
    if (lim?.maxPallets != null && pallets > lim.maxPallets) {
      out.push({
        severity: "error",
        code: "PALLETS_MAX",
        message: `托盘数 ${pallets} 超过 ${demo.ftlTrailer} 建议上限 ${lim.maxPallets}`,
        field: "palletCount",
      });
    }
  }

  return out;
}

export function formatPriority1ConstraintsMarkdown(): string {
  const lines = [
    "# Priority1 填写规则与限制",
    "",
    "## 互斥与结构",
    "",
    ...PRIORITY1_MUTEX_RULES.map((r) => `- **${r.id}**：${r.rule}`),
    "",
    "## 重量 / 托盘上限（lb）",
    "",
    "| 场景 | 最小 | 最大重量 | 最大托盘 | 备注 |",
    "|------|------|----------|----------|------|",
  ];
  for (const [key, lim] of Object.entries(PRIORITY1_WEIGHT_LIMITS)) {
    lines.push(
      `| ${key} | ${lim.minLb ?? "—"} | ${lim.maxLb} | ${lim.maxPallets ?? "—"} | ${lim.siteMessage ?? ""} |`,
    );
  }
  lines.push(
    "",
    "## 报价终态（非表单错误）",
    "",
    "- **即时报价**：LTL 卡片 / FTL Dry Van·Open Deck 部分子类型 日历报价",
    "- **人工跟进**：温控、部分 Open Deck、FTL/主类型 Expedited 等 → 「MORE INFORMATION NEEDED」",
    "- 人工跟进 **不算 RPA 失败**，返回：表单已提交，站点判定需人工确认细节后报价",
    "",
  );
  return `${lines.join("\n")}\n`;
}
