/**
 * MotherShip 登录后二级 Details：提货 / 送货 / 货物明细
 * 字段与一级 Create shipment 一一对应并预填
 */
"use client";

import { useMemo, useState } from "react";
import { CaretDown, Info, Plus, Warning, X } from "@phosphor-icons/react";
import {
  MS_CARGO_TYPES,
  MS_DEFAULT_READY_TIME,
  MS_DELIVERY_ACCESSORIALS,
  MS_PICKUP_ACCESSORIALS,
  MS_READY_TIMES,
  type MothershipLoggedInShipmentPayload,
  type MsCargoTypeId,
} from "@/components/mothership/mothership-logged-in-shipment-form";
import { MothershipWeekdayDatePicker } from "@/components/mothership/mothership-weekday-date-picker";
import {
  snapMothershipReadyDateToWeekday,
} from "@/lib/mothership/logged-in-constraints";
import {
  evaluateMothershipAccessorialCompat,
  MS_PICKUP_BLOCKED_ACCESSORIALS,
  toggleMothershipAccessorial,
} from "@/lib/mothership/option-compat";

export type MsLocationDetails = {
  address: string;
  companyName: string;
  suite: string;
  contactFirst: string;
  contactLast: string;
  contactEmail: string;
  contactPhone: string;
  extension: string;
  reference: string;
  accessorials: string[];
  notes: string;
  opensAt: string;
  closesAt: string;
  readyDate: string;
  readyTime: string;
};

export type MsDetailsCargoLine = {
  key: string;
  cargoType: MsCargoTypeId;
  quantity: string;
  freightClass: string;
  weightLb: string;
  lengthIn: string;
  widthIn: string;
  heightIn: string;
  pieceCountType: string;
  pieceCountQty: string;
  description: string;
  nmfc: string;
  hazmat: boolean;
  alcohol: boolean;
  tobacco: boolean;
};

export type MothershipLoggedInDetailsState = {
  pickup: MsLocationDetails;
  delivery: MsLocationDetails;
  requestDeliveryAppointment: boolean;
  fbaNumber: string;
  fbaPoNumber: string;
  cargo: MsDetailsCargoLine[];
};

export type MothershipLoggedInDetailsPayload = {
  pickup: {
    companyName: string;
    suite: string;
    contactFirst: string;
    contactLast: string;
    contactEmail: string;
    contactPhone: string;
    reference: string;
    notes: string;
    opensAt: string;
    closesAt: string;
  };
  delivery: {
    companyName: string;
    suite: string;
    contactFirst: string;
    contactLast: string;
    contactEmail: string;
    contactPhone: string;
    reference: string;
    notes: string;
    opensAt: string;
    closesAt: string;
  };
  requestDeliveryAppointment: boolean;
  fbaNumber: string;
  fbaPoNumber: string;
  cargo: Array<{
    pieceCountType: string;
    pieceCountQty: number;
    description: string;
    nmfc: string;
    hazmat: boolean;
    alcohol: boolean;
    tobacco: boolean;
  }>;
};

function RequiredMark() {
  return <span className="text-error">*</span>;
}

function FieldLabel({
  children,
  required,
  tip,
}: {
  children: React.ReactNode;
  required?: boolean;
  tip?: boolean;
}) {
  return (
    <span className="mb-1 flex items-center gap-1 text-xs font-medium text-text-primary">
      {children}
      {required ? <RequiredMark /> : null}
      {tip ? <Info size={12} className="text-text-disabled" /> : null}
    </span>
  );
}

function TextInput({
  value,
  onChange,
  placeholder,
  disabled,
  className = "",
}: {
  value: string;
  onChange: (v: string) => void;
  placeholder?: string;
  disabled?: boolean;
  className?: string;
}) {
  return (
    <input
      disabled={disabled}
      value={value}
      placeholder={placeholder}
      onChange={(e) => onChange(e.target.value)}
      className={`h-10 w-full rounded-md border border-border bg-surface px-3 text-sm focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 disabled:opacity-60 ${className}`}
    />
  );
}

function AccessorialSelect({
  options,
  selected,
  disabled,
  onChange,
  hintPickUp,
  side,
}: {
  options: readonly { id: string; label: string }[];
  selected: string[];
  disabled?: boolean;
  onChange: (next: string[]) => void;
  hintPickUp?: boolean;
  side: "pickup" | "delivery";
}) {
  const [open, setOpen] = useState(false);
  const [hint, setHint] = useState<string | null>(null);
  const issues = useMemo(
    () => evaluateMothershipAccessorialCompat({ side, selected }),
    [side, selected],
  );
  const summary =
    selected.length === 0
      ? "选择"
      : selected.length === 1
        ? (options.find((o) => o.id === selected[0])?.label ?? "已选择")
        : `${selected.length} 项已选`;

  return (
    <div className="relative">
      <div className="mb-1 flex flex-wrap items-center gap-2">
        <FieldLabel tip>附加服务</FieldLabel>
        <span className="inline-flex items-center gap-1 rounded bg-warning/15 px-2 py-0.5 text-[11px] text-warning">
          <Warning size={12} weight="fill" />
          避免追收附加费
        </span>
      </div>
      <button
        type="button"
        disabled={disabled}
        onClick={() => setOpen((v) => !v)}
        className="flex h-10 w-full items-center justify-between rounded-md border border-border px-3 text-left text-sm"
      >
        <span>{summary}</span>
        <CaretDown size={14} />
      </button>
      {open && !disabled && (
        <div className="absolute z-30 mt-1 max-h-64 w-full overflow-auto rounded-md border border-border bg-surface shadow-modal">
          <p className="bg-warning/10 px-3 py-2 text-xs text-text-secondary">
            下列附加服务建议勾选，以
            {hintPickUp ? "避免提货问题" : "避免送货问题"}
            并减少事后追收。住宅提货承运商不支持；预约与 Amazon 预约不能同选。
          </p>
          {options.map((opt) => {
            const checked = selected.includes(opt.id);
            const warn =
              opt.id === "liftgate" ||
              opt.id === "residential" ||
              opt.id === "limitedAccess";
            const pickupBlocked =
              side === "pickup" &&
              Boolean(MS_PICKUP_BLOCKED_ACCESSORIALS[opt.id]);
            return (
              <label
                key={opt.id}
                className={[
                  "flex items-start gap-2 border-b border-border/60 px-3 py-2 text-sm last:border-0",
                  pickupBlocked && !checked
                    ? "cursor-not-allowed opacity-60"
                    : "cursor-pointer hover:bg-bg",
                ].join(" ")}
              >
                <input
                  type="checkbox"
                  className="mt-0.5"
                  checked={checked}
                  disabled={pickupBlocked && !checked}
                  onChange={() => {
                    const r = toggleMothershipAccessorial({
                      side,
                      selected,
                      id: opt.id,
                    });
                    if (!r.applied) {
                      setHint(r.message ?? null);
                      return;
                    }
                    setHint(r.message ?? null);
                    onChange(r.next);
                  }}
                />
                <span>
                  <span className="block">{opt.label}</span>
                  {pickupBlocked ? (
                    <span className="text-[11px] text-[#EF4444]">
                      {MS_PICKUP_BLOCKED_ACCESSORIALS[opt.id]}
                    </span>
                  ) : warn ? (
                    <span className="text-[11px] text-warning">
                      建议勾选以避免追收
                    </span>
                  ) : null}
                </span>
              </label>
            );
          })}
        </div>
      )}
      {hint ? (
        <p className="mt-1 text-[11px] leading-snug text-[#B45309]">{hint}</p>
      ) : null}
      {issues.length > 0 ? (
        <ul className="mt-1 space-y-0.5 text-[11px] leading-snug text-[#92400E]">
          {issues.map((i) => (
            <li
              key={i.code}
              className={i.severity === "block" ? "text-[#EF4444]" : ""}
            >
              {i.message}
            </li>
          ))}
        </ul>
      ) : null}
    </div>
  );
}

function locationFromL1(
  address: string,
  accessorials: string[],
  readyDate: string,
  readyTime: string,
): MsLocationDetails {
  return {
    address,
    companyName: "",
    suite: "",
    contactFirst: "",
    contactLast: "",
    contactEmail: "",
    contactPhone: "",
    extension: "",
    reference: "",
    accessorials: [...accessorials],
    notes: "",
    opensAt: "",
    closesAt: "",
    readyDate: snapMothershipReadyDateToWeekday(readyDate),
    readyTime,
  };
}

function locationFromConfirmed(
  confirmed: {
    formatted_address: string;
    display_label: string;
    street: string;
    city: string;
    state: string;
    zip: string;
  },
  fallbackQuery: string,
  accessorials: string[],
  readyDate: string,
  readyTime: string,
): MsLocationDetails {
  const label =
    confirmed.formatted_address ||
    confirmed.display_label ||
    fallbackQuery;
  const composed = [confirmed.street, confirmed.city, confirmed.state, confirmed.zip]
    .map((p) => p?.trim())
    .filter(Boolean)
    .join(", ");
  return {
    ...locationFromL1(label || composed || fallbackQuery, accessorials, readyDate, readyTime),
  };
}

export function buildDetailsStateFromL1(
  payload: MothershipLoggedInShipmentPayload,
): MothershipLoggedInDetailsState {
  const wantFba = payload.deliveryAccessorials.includes("fbaAppointment");
  return {
    pickup: locationFromConfirmed(
      payload.pickupConfirmed,
      payload.pickupQuery,
      payload.pickupAccessorials,
      payload.readyDate,
      payload.readyTime,
    ),
    delivery: locationFromConfirmed(
      payload.deliveryConfirmed,
      payload.deliveryQuery,
      payload.deliveryAccessorials,
      payload.readyDate,
      payload.readyTime,
    ),
    requestDeliveryAppointment:
      wantFba || payload.deliveryAccessorials.includes("appointment"),
    fbaNumber: "",
    fbaPoNumber: "",
    cargo: payload.cargo.map((c, i) => ({
      key: `d-${i}-${c.cargoType}`,
      cargoType: c.cargoType,
      quantity: String(c.quantity),
      freightClass: "",
      weightLb: String(c.weightLb),
      lengthIn: String(c.lengthIn),
      widthIn: String(c.widthIn),
      heightIn: String(c.heightIn),
      pieceCountType: "",
      pieceCountQty: "0",
      description: "",
      nmfc: "",
      hazmat: false,
      alcohol: false,
      tobacco: false,
    })),
  };
}

function LocationSection({
  title,
  value,
  disabled,
  accessorialOptions,
  hintPickUp,
  showFreightReady,
  onChange,
}: {
  title: string;
  value: MsLocationDetails;
  disabled?: boolean;
  accessorialOptions: readonly { id: string; label: string }[];
  hintPickUp?: boolean;
  showFreightReady?: boolean;
  onChange: (next: MsLocationDetails) => void;
}) {
  const set = <K extends keyof MsLocationDetails>(
    key: K,
    v: MsLocationDetails[K],
  ) => onChange({ ...value, [key]: v });

  return (
    <section className="rounded-lg border border-border bg-surface p-4 shadow-card md:p-5">
      <h3 className="mb-4 text-base font-semibold text-text-primary">{title}</h3>

      <div className="space-y-4">
        <label className="block">
          <FieldLabel required>地址</FieldLabel>
          <TextInput
            disabled={disabled}
            value={value.address}
            onChange={(v) => set("address", v)}
            placeholder="街道、城市、州、邮编"
          />
        </label>

        <div className="grid gap-3 md:grid-cols-[1fr_8rem]">
          <label className="block">
            <FieldLabel required>完整公司名</FieldLabel>
            <TextInput
              disabled={disabled}
              value={value.companyName}
              onChange={(v) => set("companyName", v)}
              placeholder="Acme Co."
            />
            <p className="mt-1 text-[11px] text-text-secondary">
              非住宅件请勿用人名作公司名，以免承运商加收附加费。
            </p>
          </label>
          <label className="block">
            <FieldLabel>套房 / 单元</FieldLabel>
            <TextInput
              disabled={disabled}
              value={value.suite}
              onChange={(v) => set("suite", v)}
              placeholder="Ste 301"
            />
          </label>
        </div>

        <div className="grid gap-3 sm:grid-cols-2">
          <label className="block">
            <FieldLabel>现场联系人名</FieldLabel>
            <TextInput
              disabled={disabled}
              value={value.contactFirst}
              onChange={(v) => set("contactFirst", v)}
              placeholder="名"
            />
          </label>
          <label className="block">
            <FieldLabel>现场联系人姓</FieldLabel>
            <TextInput
              disabled={disabled}
              value={value.contactLast}
              onChange={(v) => set("contactLast", v)}
              placeholder="姓"
            />
          </label>
        </div>

        <label className="block">
          <FieldLabel required>现场联系人邮箱</FieldLabel>
          <TextInput
            disabled={disabled}
            value={value.contactEmail}
            onChange={(v) => set("contactEmail", v)}
            placeholder="email@company.com"
          />
          <p className="mt-1 text-[11px] text-text-secondary">
            {hintPickUp
              ? "填写提货方邮箱以接收提单与跟踪更新。"
              : "填写收货方邮箱以接收跟踪更新。"}
          </p>
        </label>

        <div className="grid gap-3 md:grid-cols-[1fr_6rem]">
          <label className="block">
            <FieldLabel required>现场联系人电话</FieldLabel>
            <TextInput
              disabled={disabled}
              value={value.contactPhone}
              onChange={(v) => set("contactPhone", v)}
              placeholder="(123) 456-7890"
            />
          </label>
          <label className="block">
            <FieldLabel>分机</FieldLabel>
            <TextInput
              disabled={disabled}
              value={value.extension}
              onChange={(v) => set("extension", v)}
              placeholder="1234"
            />
          </label>
        </div>

        <div className="grid gap-3 md:grid-cols-2">
          <label className="block">
            <FieldLabel tip>参考号</FieldLabel>
            <TextInput
              disabled={disabled}
              value={value.reference}
              onChange={(v) => set("reference", v)}
              placeholder="采购单或参考号"
            />
          </label>
          <AccessorialSelect
            options={accessorialOptions}
            selected={value.accessorials}
            disabled={disabled}
            hintPickUp={hintPickUp}
            side={hintPickUp ? "pickup" : "delivery"}
            onChange={(next) => set("accessorials", next)}
          />
        </div>

        <label className="block">
          <FieldLabel>备注</FieldLabel>
          <textarea
            disabled={disabled}
            value={value.notes}
            onChange={(e) => set("notes", e.target.value)}
            placeholder="例如：便于司机找到正确位置的关键信息"
            rows={2}
            className="w-full rounded-md border border-border px-3 py-2 text-sm focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20"
          />
        </label>

        <div>
          <p className="mb-2 text-xs font-medium text-text-primary">营业时间</p>
          <div className="flex flex-wrap items-end gap-3">
            <label className="block">
              <FieldLabel required>开门</FieldLabel>
              <select
                disabled={disabled}
                value={value.opensAt}
                onChange={(e) => set("opensAt", e.target.value)}
                className="h-10 min-w-[8rem] rounded-md border border-border px-2 text-sm"
              >
                <option value="">选择时间</option>
                {MS_READY_TIMES.map((t) => (
                  <option key={t} value={t}>
                    {t}
                  </option>
                ))}
              </select>
            </label>
            <span className="pb-2 text-xs text-text-secondary">EDT</span>
            <label className="block">
              <FieldLabel required>关门</FieldLabel>
              <select
                disabled={disabled}
                value={value.closesAt}
                onChange={(e) => set("closesAt", e.target.value)}
                className="h-10 min-w-[8rem] rounded-md border border-border px-2 text-sm"
              >
                <option value="">选择时间</option>
                {MS_READY_TIMES.map((t) => (
                  <option key={t} value={t}>
                    {t}
                  </option>
                ))}
              </select>
            </label>
            <span className="pb-2 text-xs text-text-secondary">EDT</span>
          </div>
        </div>

        {showFreightReady && (
          <div>
            <FieldLabel required tip>
              货运就绪时间（不可选周六、周日）
            </FieldLabel>
            <div className="mt-1 flex flex-wrap items-end gap-2">
              <MothershipWeekdayDatePicker
                disabled={disabled}
                value={value.readyDate}
                onChange={(iso) => set("readyDate", iso)}
                className="h-10 min-w-[11rem] rounded-md border border-border bg-surface px-3 text-sm"
              />
              <span className="pb-2 text-sm text-text-secondary">之后</span>
              <select
                disabled={disabled}
                value={value.readyTime || MS_DEFAULT_READY_TIME}
                onChange={(e) => set("readyTime", e.target.value)}
                className="h-10 min-w-[7.5rem] rounded-md border border-border px-2 text-sm"
              >
                {MS_READY_TIMES.map((t) => (
                  <option key={t} value={t}>
                    {t}
                  </option>
                ))}
              </select>
              <span className="pb-2 text-xs text-text-secondary">EDT</span>
            </div>
          </div>
        )}
      </div>
    </section>
  );
}

export interface MothershipLoggedInDetailsFormProps {
  formId?: string;
  initial: MothershipLoggedInShipmentPayload;
  disabled?: boolean;
  onChange?: (state: MothershipLoggedInDetailsState) => void;
  onValidSubmit?: (payload: MothershipLoggedInDetailsPayload) => void;
}

export function MothershipLoggedInDetailsForm({
  formId = "ms-logged-in-details-form",
  initial,
  disabled,
  onChange,
  onValidSubmit,
}: MothershipLoggedInDetailsFormProps) {
  const [state, setState] = useState(() => buildDetailsStateFromL1(initial));

  const patch = (next: MothershipLoggedInDetailsState) => {
    setState(next);
    onChange?.(next);
  };

  const showFba = useMemo(
    () =>
      state.requestDeliveryAppointment ||
      state.delivery.accessorials.includes("fbaAppointment"),
    [state],
  );

  const toPayload = (): MothershipLoggedInDetailsPayload => ({
    pickup: {
      companyName: state.pickup.companyName.trim(),
      suite: state.pickup.suite.trim(),
      contactFirst: state.pickup.contactFirst.trim(),
      contactLast: state.pickup.contactLast.trim(),
      contactEmail: state.pickup.contactEmail.trim(),
      contactPhone: state.pickup.contactPhone.trim(),
      reference: state.pickup.reference.trim(),
      notes: state.pickup.notes.trim(),
      opensAt: state.pickup.opensAt.trim(),
      closesAt: state.pickup.closesAt.trim(),
    },
    delivery: {
      companyName: state.delivery.companyName.trim(),
      suite: state.delivery.suite.trim(),
      contactFirst: state.delivery.contactFirst.trim(),
      contactLast: state.delivery.contactLast.trim(),
      contactEmail: state.delivery.contactEmail.trim(),
      contactPhone: state.delivery.contactPhone.trim(),
      reference: state.delivery.reference.trim(),
      notes: state.delivery.notes.trim(),
      opensAt: state.delivery.opensAt.trim(),
      closesAt: state.delivery.closesAt.trim(),
    },
    requestDeliveryAppointment: state.requestDeliveryAppointment,
    fbaNumber: state.fbaNumber.trim(),
    fbaPoNumber: state.fbaPoNumber.trim(),
    cargo: state.cargo.map((line) => ({
      pieceCountType: line.pieceCountType.trim(),
      pieceCountQty: Number(line.pieceCountQty || 0),
      description: line.description.trim(),
      nmfc: line.nmfc.trim(),
      hazmat: line.hazmat,
      alcohol: line.alcohol,
      tobacco: line.tobacco,
    })),
  });

  return (
    <form
      id={formId}
      className="space-y-5"
      onSubmit={(e) => {
        e.preventDefault();
        onValidSubmit?.(toPayload());
      }}
    >
      <div>
        <p className="text-xs text-text-secondary">
          报价 · <span className="font-medium text-primary">详情</span> · 复核
        </p>
        <h3 className="mt-1 text-xl font-semibold text-text-primary">
          货件详情
        </h3>
      </div>

      <LocationSection
        title="1. 提货信息"
        value={state.pickup}
        disabled={disabled}
        accessorialOptions={MS_PICKUP_ACCESSORIALS}
        hintPickUp
        showFreightReady
        onChange={(pickup) => patch({ ...state, pickup })}
      />

      {showFba && (
        <section className="rounded-lg border border-border bg-surface p-4 shadow-card md:p-5">
          <label className="flex items-start gap-2">
            <input
              type="checkbox"
              disabled={disabled}
              checked={state.requestDeliveryAppointment}
              onChange={(e) =>
                patch({
                  ...state,
                  requestDeliveryAppointment: e.target.checked,
                })
              }
              className="mt-1"
            />
            <span>
              <span className="block text-sm font-semibold text-text-primary">
                申请送货预约
              </span>
              <span className="text-xs text-text-secondary">
                自动为住宅/商业地址安排送货预约
              </span>
            </span>
          </label>
          {state.requestDeliveryAppointment && (
            <div className="mt-4 rounded-md bg-warning/10 p-4">
              <p className="text-sm font-semibold text-text-primary">
                填写 Fulfillment by Amazon（FBA）编号
              </p>
              <div className="mt-3 grid gap-3 sm:grid-cols-2">
                <label className="block">
                  <FieldLabel>FBA 编号</FieldLabel>
                  <TextInput
                    disabled={disabled}
                    value={state.fbaNumber}
                    onChange={(v) => patch({ ...state, fbaNumber: v })}
                    placeholder="输入 FBA 编号"
                  />
                </label>
                <label className="block">
                  <FieldLabel>采购单号</FieldLabel>
                  <TextInput
                    disabled={disabled}
                    value={state.fbaPoNumber}
                    onChange={(v) => patch({ ...state, fbaPoNumber: v })}
                    placeholder="输入采购单号"
                  />
                </label>
              </div>
              <ul className="mt-3 list-disc space-y-1 pl-5 text-xs text-text-secondary">
                <li>FBA 编号将写入提单</li>
                <li>
                  须在下方货物表单中填写{" "}
                  <strong className="text-text-primary">件数（piece count）</strong>
                </li>
              </ul>
            </div>
          )}
        </section>
      )}

      <LocationSection
        title="2. 送货信息"
        value={state.delivery}
        disabled={disabled}
        accessorialOptions={MS_DELIVERY_ACCESSORIALS}
        onChange={(delivery) => patch({ ...state, delivery })}
      />

      <section className="rounded-lg border border-border bg-surface p-4 shadow-card md:p-5">
        <div className="mb-4 flex items-center justify-between gap-3">
          <h3 className="text-base font-semibold text-text-primary">3. 货物</h3>
          <button
            type="button"
            disabled={disabled}
            onClick={() =>
              patch({
                ...state,
                cargo: [
                  ...state.cargo,
                  {
                    key: `d-${Date.now()}`,
                    cargoType: "pallet",
                    quantity: "",
                    freightClass: "",
                    weightLb: "",
                    lengthIn: "",
                    widthIn: "",
                    heightIn: "",
                    pieceCountType: "",
                    pieceCountQty: "0",
                    description: "",
                    nmfc: "",
                    hazmat: false,
                    alcohol: false,
                    tobacco: false,
                  },
                ],
              })
            }
            className="inline-flex h-9 items-center gap-1.5 rounded-md bg-text-primary px-3 text-sm font-medium text-white"
          >
            <Plus size={14} weight="bold" />
            添加另一行
          </button>
        </div>

        <div className="space-y-4">
          {state.cargo.map((line, idx) => (
            <div
              key={line.key}
              className="relative rounded-md border border-border p-4"
            >
              <div className="mb-3 flex items-center justify-between">
                <span className="text-sm font-semibold text-text-primary">
                  {idx + 1}
                </span>
                <button
                  type="button"
                  disabled={disabled || state.cargo.length <= 1}
                  aria-label="删除货物行"
                  onClick={() =>
                    patch({
                      ...state,
                      cargo: state.cargo.filter((c) => c.key !== line.key),
                    })
                  }
                  className="inline-flex h-8 w-8 items-center justify-center rounded border border-border text-text-secondary disabled:opacity-40"
                >
                  <X size={14} weight="bold" />
                </button>
              </div>

              <div className="grid gap-3 sm:grid-cols-3">
                <label className="block">
                  <FieldLabel required tip>
                    货物类型
                  </FieldLabel>
                  <select
                    disabled={disabled}
                    value={line.cargoType}
                    onChange={(e) => {
                      const cargo = state.cargo.map((c) =>
                        c.key === line.key
                          ? {
                              ...c,
                              cargoType: e.target.value as MsCargoTypeId,
                            }
                          : c,
                      );
                      patch({ ...state, cargo });
                    }}
                    className="h-10 w-full rounded-md border border-border px-2 text-sm"
                  >
                    {MS_CARGO_TYPES.map((t) => (
                      <option key={t.id} value={t.id}>
                        {t.label}
                      </option>
                    ))}
                  </select>
                </label>
                <label className="block">
                  <FieldLabel required>数量</FieldLabel>
                  <TextInput
                    disabled={disabled}
                    value={line.quantity}
                    onChange={(v) => {
                      const cargo = state.cargo.map((c) =>
                        c.key === line.key ? { ...c, quantity: v } : c,
                      );
                      patch({ ...state, cargo });
                    }}
                  />
                </label>
                <label className="block">
                  <FieldLabel tip>运费等级（可选）</FieldLabel>
                  <TextInput
                    disabled={disabled}
                    value={line.freightClass}
                    onChange={(v) => {
                      const cargo = state.cargo.map((c) =>
                        c.key === line.key ? { ...c, freightClass: v } : c,
                      );
                      patch({ ...state, cargo });
                    }}
                    placeholder="选择"
                  />
                </label>
              </div>

              <div className="mt-3 grid gap-3 sm:grid-cols-4">
                {(
                  [
                    ["weightLb", "单件重量", "lbs"],
                    ["lengthIn", "单件长", "inch"],
                    ["widthIn", "单件宽", "inch"],
                    ["heightIn", "单件高", "inch"],
                  ] as const
                ).map(([key, label, ph]) => (
                  <label key={key} className="block">
                    <FieldLabel required={key !== "weightLb"}>
                      {label}
                    </FieldLabel>
                    <TextInput
                      disabled={disabled}
                      value={line[key]}
                      onChange={(v) => {
                        const cargo = state.cargo.map((c) =>
                          c.key === line.key ? { ...c, [key]: v } : c,
                        );
                        patch({ ...state, cargo });
                      }}
                      placeholder={ph}
                    />
                  </label>
                ))}
              </div>

              <div className="mt-3 grid gap-3 sm:grid-cols-2">
                <label className="block">
                  <FieldLabel required tip>
                    件数类型
                  </FieldLabel>
                  <select
                    disabled={disabled}
                    value={line.pieceCountType}
                    onChange={(e) => {
                      const cargo = state.cargo.map((c) =>
                        c.key === line.key
                          ? { ...c, pieceCountType: e.target.value }
                          : c,
                      );
                      patch({ ...state, cargo });
                    }}
                    className="h-10 w-full rounded-md border border-border px-2 text-sm"
                  >
                    <option value="">选择</option>
                    <option value="pieces">件（Pieces）</option>
                    <option value="cartons">纸箱（Cartons）</option>
                    <option value="units">单元（Units）</option>
                  </select>
                </label>
                <label className="block">
                  <FieldLabel required>件数数量</FieldLabel>
                  <TextInput
                    disabled={disabled}
                    value={line.pieceCountQty}
                    onChange={(v) => {
                      const cargo = state.cargo.map((c) =>
                        c.key === line.key ? { ...c, pieceCountQty: v } : c,
                      );
                      patch({ ...state, cargo });
                    }}
                  />
                </label>
              </div>

              <label className="mt-3 block">
                <FieldLabel required>货物描述</FieldLabel>
                <textarea
                  disabled={disabled}
                  value={line.description}
                  onChange={(e) => {
                    const cargo = state.cargo.map((c) =>
                      c.key === line.key
                        ? { ...c, description: e.target.value }
                        : c,
                    );
                    patch({ ...state, cargo });
                  }}
                  rows={2}
                  placeholder="准确描述货物以避免查验与加收。例如：用「地毯」而非「一般商品」。"
                  className="w-full rounded-md border border-border px-3 py-2 text-sm"
                />
              </label>

              <label className="mt-3 block">
                <FieldLabel tip>NMFC 编码（可选）</FieldLabel>
                <TextInput
                  disabled={disabled}
                  value={line.nmfc}
                  onChange={(v) => {
                    const cargo = state.cargo.map((c) =>
                      c.key === line.key ? { ...c, nmfc: v } : c,
                    );
                    patch({ ...state, cargo });
                  }}
                  placeholder="输入 NMFC 编码"
                />
                <p className="mt-1 text-[11px] text-text-secondary">
                  添加该编码有助于减少承运商事后调整收费。
                </p>
              </label>

              <div className="mt-4">
                <p className="mb-2 text-xs font-medium text-text-primary">
                  受管制货物声明
                </p>
                <div className="flex flex-wrap gap-4 text-sm">
                  {(
                    [
                      ["hazmat", "危险品（Hazmat）"],
                      ["alcohol", "啤酒/葡萄酒/烈酒"],
                      ["tobacco", "尼古丁/烟草"],
                    ] as const
                  ).map(([key, label]) => (
                    <label key={key} className="inline-flex items-center gap-2">
                      <input
                        type="checkbox"
                        disabled={disabled}
                        checked={line[key]}
                        onChange={(e) => {
                          const cargo = state.cargo.map((c) =>
                            c.key === line.key
                              ? { ...c, [key]: e.target.checked }
                              : c,
                          );
                          patch({ ...state, cargo });
                        }}
                      />
                      {label}
                    </label>
                  ))}
                </div>
              </div>
            </div>
          ))}
        </div>
      </section>
    </form>
  );
}
