// track-page.jsx — standalone driver tracking page (opened from a tracking link)
const { useState: useStateTP, useEffect: useEffectTP } = React;

function qparam(k) {
  try {
    var h = (window.location.hash || "").replace(/^#/, "");
    var fromHash = new URLSearchParams(h).get(k);
    if (fromHash) return fromHash;
    return new URLSearchParams(window.location.search).get(k) || "";
  } catch (e) { return ""; }
}

function resolveShipment(code) {
  const c = (code || "").trim().toUpperCase();
  // delivery run?
  for (const run of window.FX.DELIVERY_RUNS) {
    if (run.id.toUpperCase() === c) {
      const pr = window.FX.runProgress(run);
      const stop = pr.current || run.stops.find(s => s.status === "Pending") || run.stops[run.stops.length - 1];
      return { code: run.id, from: run.start.suburb, to: stop ? stop.suburb : run.end.suburb, driverId: run.driverId, progress: pr.pct || 0.4, kind: run.status === "Completed" ? "delivered" : "transit", context: run.name + " · stop " + (pr.done + 1) + " of " + pr.total };
    }
    for (const s of run.stops) {
      if (s.tracking.toUpperCase() === c) {
        return { code: s.tracking, from: run.start.suburb, to: s.suburb, driverId: run.driverId, progress: s.status === "Delivered" ? 1 : s.status === "In transit" ? 0.6 : 0.15, kind: s.status === "Delivered" ? "delivered" : "transit", context: run.name };
      }
    }
  }
  // seed history
  const h = window.FX.HISTORY.find(x => x.id.toUpperCase() === c);
  if (h) return { code: h.id, from: h.from, to: h.to, driverId: "dr2", progress: 1, kind: "delivered", context: "Same-day delivery" };
  // localStorage bookings (customer portal + CSR console)
  for (const key of ["fedexPortal_v1", "fedexCsr_v2"]) {
    try {
      const st = JSON.parse(localStorage.getItem(key)) || {};
      const b = (st.bookings || []).find(x => (x.tracking || "").toUpperCase() === c);
      if (b) return shipFromBooking(b);
    } catch (e) {}
  }
  return null;
}

function shipFromBooking(b) {
  const delivered = b.status === "Delivered", cancelled = b.status === "Cancelled";
  let progress = typeof b.progress === "number" ? b.progress : (delivered ? 1 : b.status === "In transit" ? 0.5 : (b.driver ? 0.15 : 0.05));
  if (delivered) progress = 1;
  if (window.FX.isNextFlight(b)) {
    const info = window.FX.nextFlightInfo(b);
    return { code: b.tracking, nf: true, info, booking: b, from: info.dep.city, to: info.arr.city, progress, kind: delivered ? "delivered" : cancelled ? "cancelled" : "transit", context: "Next Flight air freight" };
  }
  return { code: b.tracking, from: b.pickup.suburb, to: b.dropoff.suburb, driverId: (b.driver && b.driver.id) || "dr1", progress, kind: delivered ? "delivered" : "transit", context: "Same-day delivery" };
}

function DriverTrackMap({ ship, driver }) {
  const p = Math.max(0, Math.min(1, ship.progress || 0));
  const delivered = ship.kind === "delivered";
  const pts = [[70,360],[180,300],[260,250],[330,215],[430,175],[540,70]];
  const idx = Math.min(pts.length - 2, Math.floor(p * (pts.length - 1)));
  const f = p * (pts.length - 1) - idx;
  const x = pts[idx][0] + (pts[idx+1][0] - pts[idx][0]) * f;
  const y = pts[idx][1] + (pts[idx+1][1] - pts[idx][1]) * f;
  return (
    <div style={{ position: "relative", borderRadius: "var(--r-2xl)", overflow: "hidden", background: "#0B2240", height: 440, border: "1px solid var(--border)" }}>
      <svg width="100%" height="100%" style={{ position: "absolute", inset: 0, opacity: 0.2 }}>
        <defs><pattern id="tpg" width="40" height="40" patternUnits="userSpaceOnUse"><path d="M40 0 L0 0 0 40" fill="none" stroke="rgba(120,160,220,0.6)" strokeWidth="0.5" /></pattern></defs>
        <rect width="100%" height="100%" fill="url(#tpg)" />
      </svg>
      <svg width="100%" height="100%" viewBox="0 0 600 440" preserveAspectRatio="none" style={{ position: "absolute", inset: 0 }}>
        <path d="M 70 360 C 180 320 240 250 320 220 C 410 186 470 130 540 70" stroke="rgba(255,255,255,0.25)" strokeWidth="4" fill="none" strokeDasharray="3 8" strokeLinecap="round" />
        <path d="M 70 360 C 180 320 240 250 320 220 C 410 186 470 130 540 70" stroke="var(--accent)" strokeWidth="4" fill="none" strokeLinecap="round" strokeDasharray="900" strokeDashoffset={900 - 900 * p} />
      </svg>
      <TPin x="11.6%" y="81.8%" color="var(--brand)" label={ship.from} />
      <TPin x="90%" y="15.9%" color="#fff" ring="var(--accent)" label={ship.to} />
      {!delivered && (
        <div style={{ position: "absolute", left: `${x/600*100}%`, top: `${y/440*100}%`, transform: "translate(-50%,-50%)" }}>
          <span style={{ width: 38, height: 38, borderRadius: "50%", background: "#fff", display: "inline-flex", alignItems: "center", justifyContent: "center", boxShadow: "0 4px 12px rgba(0,0,0,0.4)", animation: "pulseDot 1.8s infinite" }}>
            <Icon name="navigation" size={19} color="var(--brand)" />
          </span>
        </div>
      )}
      {delivered && <div style={{ position: "absolute", top: 16, left: 16 }}><Badge tone="success" style={{ background: "#fff" }}><StatusDot color="#22b86e" /> Delivered</Badge></div>}
      {!delivered && driver && (
        <div style={{ position: "absolute", left: 16, bottom: 16, right: 16, display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 12 }}>
          <div style={{ background: "#fff", borderRadius: 14, padding: "12px 16px", boxShadow: "var(--shadow-pop)", display: "flex", alignItems: "center", gap: 12 }}>
            <span style={{ width: 40, height: 40, borderRadius: "50%", background: "var(--brand)", color: "#fff", display: "inline-flex", alignItems: "center", justifyContent: "center", fontWeight: 700, fontSize: 14 }}>{driver.initials}</span>
            <div>
              <div style={{ fontWeight: 600, fontSize: 14, color: "var(--fg-strong)" }}>{driver.name.split(/\s+/)[0]}</div>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, color: "var(--fg-mute)" }}>{driver.vehicle} · {driver.rego}</div>
            </div>
          </div>
          <div style={{ background: "var(--accent)", color: "#fff", borderRadius: 14, padding: "12px 16px", boxShadow: "var(--shadow-pop)", textAlign: "right" }}>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: "1px", opacity: 0.85 }}>EN ROUTE</div>
            <div style={{ fontWeight: 800, fontSize: 20 }}>{Math.round(p * 100)}%</div>
          </div>
        </div>
      )}
    </div>
  );
}
function TPin({ x, y, color, ring, label }) {
  return (
    <div style={{ position: "absolute", left: x, top: y, transform: "translate(-50%,-50%)", display: "flex", flexDirection: "column", alignItems: "center", gap: 5 }}>
      <span style={{ width: 16, height: 16, borderRadius: "50%", background: color, border: `3px solid ${ring || "#fff"}`, boxShadow: "0 3px 8px rgba(0,0,0,0.4)" }} />
      <span style={{ fontSize: 11, fontWeight: 600, color: "#fff", background: "rgba(1,16,31,0.6)", padding: "2px 8px", borderRadius: 6, whiteSpace: "nowrap" }}>{label}</span>
    </div>
  );
}

function hmToMin(hm) { const m = /^(\d{1,2}):(\d{2})/.exec(hm || ""); return m ? (+m[1]) * 60 + (+m[2]) : 0; }
function minToHm(x) { x = ((x % 1440) + 1440) % 1440; return String(Math.floor(x / 60)).padStart(2, "0") + ":" + String(x % 60).padStart(2, "0"); }
function hmMinus(hm, mins) { return minToHm(hmToMin(hm) - mins); }
function hmPlus(hm, mins) { return minToHm(hmToMin(hm) + mins); }

function FlightJourneyMap({ ship }) {
  const info = ship.info;
  const bk = ship.booking || {};
  const f = info.flight;
  const delivered = ship.kind === "delivered";
  const p = delivered ? 1 : Math.max(0.04, Math.min(0.98, ship.progress || 0));
  const pickupName = (bk.pickup && bk.pickup.suburb) || info.dep.city;
  const deliveryName = (bk.dropoff && bk.dropoff.suburb) || info.arr.city;
  const puDriver = (info.pickupDriver && info.pickupDriver.name.split(/\s+/)[0]) || "Courier";
  const doDriver = (info.deliveryDriver && info.deliveryDriver.name.split(/\s+/)[0]) || "Courier";
  const mode = info.mode || "flight";
  const midIcon = mode === "truck" ? "truck" : mode === "train" ? "train" : "plane";
  const hubSuffix = mode === "flight" ? " Airport" : " hub";

  // 4 nodes: pickup · origin airport · dest airport · delivery  (flight = middle leg)
  const nodeFrac = [0, 1 / 3.5, 2.5 / 3.5, 1];
  const X = fr => 4 + fr * 92;                        // inset % across the strip
  const arrive = [0.15, 0.30, 0.75, 0.999];          // progress at which each node is reached
  const legWin = [[0.15, 0.30], [0.30, 0.75], [0.75, 0.98]];
  const legFill = i => Math.max(0, Math.min(1, (p - legWin[i][0]) / (legWin[i][1] - legWin[i][0])));
  const markerFrac = pp => {
    const pb = [0, 0.30, 0.75, 1];
    for (let i = 1; i < pb.length; i++) if (pp <= pb[i]) { const t = (pp - pb[i - 1]) / (pb[i] - pb[i - 1]); return nodeFrac[i - 1] + (nodeFrac[i] - nodeFrac[i - 1]) * t; }
    return 1;
  };
  const mFrac = markerFrac(p);
  const curLeg = p < 0.30 ? 0 : p < 0.75 ? 1 : 2;
  const firstUndone = arrive.findIndex(a => !(delivered || p >= a));
  const nodes = [
    { icon: "package", eyebrow: "PICKUP", main: pickupName, code: false },
    { icon: midIcon, eyebrow: info.dep.code, main: info.dep.city + hubSuffix, code: true },
    { icon: midIcon, eyebrow: info.arr.code, main: mode === "flight" ? info.arr.city + " Airport" : ((info.linehaul && info.linehaul.destination) || info.arr.city + " hub"), code: true },
    { icon: "map-pin", eyebrow: "DELIVERY", main: deliveryName, code: false },
  ];
  const railTop = 66;

  return (
    <div style={{ position: "relative", borderRadius: "var(--r-2xl)", overflow: "hidden", background: "#0B2240", border: "1px solid var(--border)", padding: "58px 44px 26px" }}>
      <svg width="100%" height="100%" style={{ position: "absolute", inset: 0, opacity: 0.18 }}>
        <defs><pattern id="fjg" width="40" height="40" patternUnits="userSpaceOnUse"><path d="M40 0 L0 0 0 40" fill="none" stroke="rgba(120,160,220,0.6)" strokeWidth="0.5" /></pattern></defs>
        <rect width="100%" height="100%" fill="url(#fjg)" />
      </svg>

      <div style={{ position: "absolute", top: 16, left: 16, display: "flex", alignItems: "center", gap: 8, background: "rgba(255,255,255,0.12)", borderRadius: 999, padding: "6px 12px", zIndex: 3 }}>
        <Icon name={midIcon} size={14} color="#fff" />
        <span style={{ color: "#fff", fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 13 }}>{info.dep.code} → {info.arr.code}</span>
      </div>
      <div style={{ position: "absolute", top: 16, right: 16, zIndex: 3 }}>
        {delivered && <Badge tone="success" style={{ background: "#fff" }}><StatusDot color="#22b86e" /> Delivered</Badge>}
      </div>

      <div style={{ position: "relative", height: 150 }}>
        <div style={{ position: "absolute", left: "4%", right: "4%", top: railTop, height: 4, borderRadius: 4, background: "rgba(255,255,255,0.16)" }} />
        {[0, 1, 2].map(i => (
          <div key={"fill" + i} style={{ position: "absolute", top: railTop, height: 4, borderRadius: 4, background: "var(--accent)", left: `${X(nodeFrac[i])}%`, width: `${(X(nodeFrac[i + 1]) - X(nodeFrac[i])) * legFill(i)}%` }} />
        ))}

        {[[0, puDriver], [2, doDriver]].map(([i, nm]) => (
          <div key={"leg" + i} style={{ position: "absolute", top: railTop - 28, left: `${X((nodeFrac[i] + nodeFrac[i + 1]) / 2)}%`, transform: "translateX(-50%)", display: "flex", alignItems: "center", gap: 5, whiteSpace: "nowrap" }}>
            <Icon name="truck" size={12} color="rgba(255,255,255,0.6)" />
            <span style={{ fontSize: 11, color: "rgba(255,255,255,0.72)" }}>{nm}</span>
          </div>
        ))}

        <div style={{ position: "absolute", top: railTop - 47, left: "50%", transform: "translateX(-50%)", background: "#fff", borderRadius: 12, boxShadow: "var(--shadow-pop)", padding: "7px 13px", textAlign: "center", whiteSpace: "nowrap", zIndex: 2 }}>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 6 }}>
            <Icon name={midIcon} size={15} color="var(--brand)" />
          </div>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, color: "var(--fg-mute)", marginTop: 2 }}>
            {f.dep_hm} → <span style={{ color: "var(--fg-strong)", fontWeight: 700 }}>{delivered ? (f.arr_est_hm || f.arr_hm) : info.eta}</span>
          </div>
        </div>

        {nodes.map((n, i) => {
          const done = delivered || p >= arrive[i];
          const current = !done && i === firstUndone;
          const bg = done ? "var(--accent)" : current ? "#fff" : "rgba(255,255,255,0.14)";
          const ic = done ? "#fff" : current ? "var(--brand)" : "rgba(255,255,255,0.6)";
          return (
            <div key={"node" + i}>
              <div style={{ position: "absolute", top: railTop + 2, left: `${X(nodeFrac[i])}%`, transform: "translate(-50%,-50%)", width: 26, height: 26, borderRadius: "50%", background: bg, border: current ? "2px solid var(--accent)" : "none", display: "inline-flex", alignItems: "center", justifyContent: "center", zIndex: 2, animation: current ? "pulseDot 1.8s infinite" : "none" }}>
                <Icon name={n.icon} size={13} color={ic} />
              </div>
              <div style={{ position: "absolute", top: railTop + 22, left: `${X(nodeFrac[i])}%`, transform: "translateX(-50%)", width: 112, textAlign: "center" }}>
                <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.8px", color: n.code ? "var(--accent)" : "rgba(255,255,255,0.5)", fontWeight: 700 }}>{n.eyebrow}</div>
                <div style={{ fontSize: 12.5, color: "#fff", fontWeight: 600, marginTop: 2, lineHeight: 1.25 }}>{n.main}</div>
              </div>
            </div>
          );
        })}

        {!delivered && (
          <div style={{ position: "absolute", top: railTop + 2, left: `${X(mFrac)}%`, transform: "translate(-50%,-50%)", zIndex: 3 }}>
            <span style={{ width: 34, height: 34, borderRadius: "50%", background: "#fff", display: "inline-flex", alignItems: "center", justifyContent: "center", boxShadow: "0 4px 14px rgba(0,0,0,0.45)", animation: "pulseDot 1.8s infinite" }}>
              <Icon name={curLeg === 1 ? midIcon : "truck"} size={17} color="var(--accent)" />
            </span>
          </div>
        )}
      </div>
    </div>
  );
}

function StepList({ steps }) {
  return (
    <div style={{ position: "relative" }}>
      {steps.map((st, i, arr) => (
        <div key={i} style={{ display: "flex", gap: 14, paddingBottom: i < arr.length - 1 ? 18 : 0, position: "relative" }}>
          {i < arr.length - 1 && <span style={{ position: "absolute", left: 12, top: 24, bottom: 0, width: 2, background: st.done ? "var(--brand)" : "var(--border)" }} />}
          <span style={{ width: 25, height: 25, borderRadius: "50%", flex: "none", zIndex: 1, display: "inline-flex", alignItems: "center", justifyContent: "center", background: st.done ? "var(--brand)" : st.active ? "var(--accent)" : "var(--bg-mist-2)", color: st.done || st.active ? "#fff" : "var(--fg-mute)" }}>
            {st.done ? <Icon name="check" size={14} /> : st.active ? <StatusDot color="#fff" pulse /> : <span style={{ width: 7, height: 7, borderRadius: "50%", background: "var(--fg-faint)" }} />}
          </span>
          <div style={{ paddingTop: 1, flex: 1, minWidth: 0 }}>
            <div style={{ display: "flex", alignItems: "baseline", gap: 8, flexWrap: "wrap" }}>
              <div style={{ fontWeight: 600, fontSize: 14, color: st.done || st.active ? "var(--fg-strong)" : "var(--fg-mute)" }}>{st.t}</div>
              {st.time && <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, color: st.done || st.active ? "var(--brand)" : "var(--fg-faint)" }}>{st.time}</span>}
            </div>
            <div style={{ fontSize: 12.5, color: "var(--fg-mute)", marginTop: 2 }}>{st.d}</div>
          </div>
        </div>
      ))}
    </div>
  );
}

function NFHero({ ship, nf, delivered }) {
  const mode = nf.mode || "flight";
  const stats = [
    { label: "From", value: nf.dep.code, sub: nf.dep.city },
    { label: "To", value: nf.arr.code, sub: nf.arr.city },
    { label: "Items", value: nf.items + (nf.items === 1 ? " item" : " items") },
    { label: "Weight", value: nf.weightKg + " kg" },
  ];
  return (
    <Card pad={0} style={{ overflow: "hidden" }}>
      <div style={{ padding: "22px 26px", display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 20, flexWrap: "wrap" }}>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "1.2px", textTransform: "uppercase", color: "var(--accent)", fontWeight: 700 }}>{mode === "flight" ? "Next Flight delivery" : mode === "truck" ? "Interstate delivery — road line haul" : "Interstate delivery — rail line haul"}</div>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginTop: 9, flexWrap: "wrap" }}>
            <span style={{ fontSize: 26, fontWeight: 800, letterSpacing: "-0.5px", color: "var(--fg-strong)" }}>{nf.dep.city}</span>
            <Icon name="arrow-right" size={19} color="var(--fg-faint)" />
            <span style={{ fontSize: 26, fontWeight: 800, letterSpacing: "-0.5px", color: "var(--fg-strong)" }}>{nf.arr.city}</span>
          </div>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, color: "var(--fg-mute)", marginTop: 8 }}>{ship.code}</div>
        </div>
        <div style={{ textAlign: "right", flex: "none" }}>
          <Badge tone={delivered ? "success" : "brand"}><StatusDot color={delivered ? "#22b86e" : "var(--brand)"} pulse={!delivered} /> {delivered ? "Delivered" : "In transit"}</Badge>
          <div style={{ marginTop: 12 }}>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "1px", textTransform: "uppercase", color: "var(--fg-mute)" }}>{delivered ? "Arrived" : "Est. arrival"}</div>
            <div style={{ fontSize: 30, fontWeight: 800, fontFamily: "var(--font-mono)", color: "var(--fg-strong)", lineHeight: 1.1, marginTop: 2 }}>{nf.eta}</div>
          </div>
        </div>
      </div>
      <div style={{ display: "flex", borderTop: "1px solid var(--border)", background: "var(--bg-mist)" }}>
        {stats.map((s, i) => (
          <div key={i} style={{ flex: 1, minWidth: 0, padding: "13px 18px", borderLeft: i ? "1px solid var(--border)" : "none" }}>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.7px", textTransform: "uppercase", color: "var(--fg-mute)" }}>{s.label}</div>
            <div style={{ fontSize: 14, fontWeight: 700, color: "var(--fg-strong)", marginTop: 4, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{s.value}</div>
            {s.sub && <div style={{ fontSize: 11, color: "var(--fg-mute)", marginTop: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{s.sub}</div>}
          </div>
        ))}
      </div>
    </Card>
  );
}

function FlightDetailsCard({ nf }) {
  const f = nf.flight;
  const mode = nf.mode || "flight";
  const mIcon = mode === "truck" ? "truck" : mode === "train" ? "train" : "plane";
  const row = (label, value, time) => (
    <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, padding: "10px 0", borderTop: "1px solid var(--border)" }}>
      <span style={{ fontSize: 12.5, color: "var(--fg-mute)" }}>{label}</span>
      <span style={{ textAlign: "right", minWidth: 0 }}>
        <span style={{ fontSize: 13.5, fontWeight: 600, color: "var(--fg-strong)" }}>{value}</span>
        {time && <span style={{ display: "block", fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--accent-700)", fontWeight: 700, marginTop: 1 }}>{time}</span>}
      </span>
    </div>
  );
  return (
    <Card pad={20}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 10 }}>
        <span style={{ width: 32, height: 32, borderRadius: 8, flex: "none", background: "var(--brand-soft)", color: "var(--brand)", display: "inline-flex", alignItems: "center", justifyContent: "center" }}><Icon name={mIcon} size={16} /></span>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 14.5, fontWeight: 700, color: "var(--fg-strong)" }}>Journey</div>
          <div style={{ fontSize: 12, color: "var(--fg-mute)" }}>{nf.dep.city} → {nf.arr.city}</div>
        </div>
      </div>
      {row("Departs", nf.dep.code + " · " + nf.dep.city, f.dep_hm)}
      {row("Arrives", nf.arr.code + " · " + nf.arr.city, f.arr_est_hm || f.arr_hm)}
      {mode !== "flight" && nf.linehaul && nf.linehaul.destination && row("Destination", nf.linehaul.destination)}
    </Card>
  );
}

function CourierContact({ driver, role, delivered }) {
  if (!driver) return null;
  return (
    <Card pad={18}>
      <div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: "0.9px", textTransform: "uppercase", color: "var(--fg-mute)", marginBottom: 12 }}>{role}</div>
      <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
        <span style={{ width: 42, height: 42, borderRadius: "50%", flex: "none", background: "var(--brand)", color: "#fff", display: "inline-flex", alignItems: "center", justifyContent: "center", fontWeight: 700, fontSize: 14 }}>{driver.initials}</span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontWeight: 600, fontSize: 14.5, color: "var(--fg-strong)" }}>{driver.name}</div>
          <div style={{ fontSize: 12.5, color: "var(--fg-mute)", fontFamily: "var(--font-mono)" }}>{driver.vehicle}{driver.rego && driver.rego !== "—" ? " · " + driver.rego : ""}</div>
        </div>
        {!delivered && driver.phone
          ? <a href={"tel:" + driver.phone} style={{ textDecoration: "none", flex: "none" }}><Button variant="secondary" size="sm" icon="phone">Call</Button></a>
          : delivered ? <Badge tone="success"><Icon name="check" size={12} /> Delivered</Badge> : null}
      </div>
    </Card>
  );
}

function TrackPage() {
  const initCode = qparam("t");
  const driverHint = qparam("driver");
  const [code, setCode] = useStateTP(initCode);
  const [active, setActive] = useStateTP(null);
  const [err, setErr] = useStateTP(false);

  useEffectTP(() => { if (initCode) doTrack(initCode); }, []);

  function doTrack(c) {
    const ship = resolveShipment(c);
    if (!ship) { setErr(true); setActive(null); return; }
    setErr(false); setActive(ship);
  }

  const driver = active ? window.FX.DRIVERS.find(d => d.id === active.driverId) : (driverHint ? { name: driverHint, initials: driverHint.split(/\s+/).map(w => w[0]).slice(0,2).join("").toUpperCase(), vehicle: "Delivery vehicle", rego: "—", phone: "" } : null);
  const ship = active;
  const delivered = ship && ship.kind === "delivered";
  const isNF = !!(ship && ship.nf);
  const nfInfo = isNF ? ship.info : null;
  const p = ship ? ship.progress : 0;
  const nfSteps = isNF ? [
    { t: "Booking confirmed", d: "Consignment created", time: hmMinus(nfInfo.flight.dep_hm, 180), done: true },
    { t: "Allocated to courier", d: nfInfo.pickupDriver.name + " · pickup", time: hmMinus(nfInfo.flight.dep_hm, 120), done: p >= 0.12 || delivered },
    { t: "Picked up", d: "Collected in " + nfInfo.dep.city, time: (ship.booking && ship.booking.time) || hmMinus(nfInfo.flight.dep_hm, 75), done: p >= 0.28 || delivered, active: !delivered && p >= 0.12 && p < 0.28 },
    { t: nfInfo.mode === "truck" ? "Road line haul" : nfInfo.mode === "train" ? "Rail line haul" : "In flight", d: nfInfo.dep.code + " → " + nfInfo.arr.code, time: (nfInfo.flight.dep_est_hm || nfInfo.flight.dep_hm) + "–" + (nfInfo.flight.arr_est_hm || nfInfo.flight.arr_hm), done: p >= 0.72 || delivered, active: !delivered && p >= 0.28 && p < 0.72 },
    { t: "Out for delivery", d: nfInfo.deliveryDriver.name + " · " + nfInfo.arr.city, time: nfInfo.flight.arr_est_hm || nfInfo.flight.arr_hm, done: p >= 0.95 || delivered, active: !delivered && p >= 0.72 && p < 0.95 },
    { t: "Delivered", d: delivered ? "Completed" : "Estimated arrival", time: delivered ? hmPlus(nfInfo.flight.arr_hm, 45) : ("ETA " + nfInfo.eta), done: delivered },
  ] : [];
  const steps = ship ? [
    { t: "Booking confirmed", d: "Driver matched", done: true },
    { t: "Picked up", d: "Collected from " + ship.from, done: ship.progress >= 0.2 || delivered },
    { t: "In transit", d: "On the way", done: ship.progress >= 0.5 || delivered, active: !delivered && ship.progress >= 0.2 && ship.progress < 0.85 },
    { t: "Out for delivery", d: "Approaching " + ship.to, done: ship.progress >= 0.85 || delivered, active: !delivered && ship.progress >= 0.85 },
    { t: "Delivered", d: delivered ? "Completed" : "Awaiting completion", done: delivered },
  ] : [];

  return (
    <div style={{ minHeight: "100vh", background: "var(--bg-page)" }}>
      <header style={{ height: 60, display: "flex", alignItems: "center", justifyContent: "space-between", padding: "0 24px", background: "var(--brand)", color: "#fff" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <Wordmark size={22} onDark />
          <span style={{ width: 1, height: 24, background: "rgba(255,255,255,0.2)" }} />
          <span style={{ fontWeight: 600, fontSize: 14.5 }}>Live tracking</span>
        </div>
        <a href="Fedex Booking Portal.html" style={{ fontSize: 13, color: "rgba(255,255,255,0.85)", textDecoration: "none", display: "inline-flex", alignItems: "center", gap: 6 }}><Icon name="arrow-left" size={15} /> Back to portal</a>
      </header>

      <div style={{ maxWidth: 980, margin: "0 auto", padding: "28px 24px 60px" }}>
        <div style={{ display: "flex", gap: 10, marginBottom: 22, maxWidth: 520 }}>
          <div style={{ position: "relative", flex: 1 }}>
            <span style={{ position: "absolute", left: 14, top: "50%", transform: "translateY(-50%)", color: "var(--fg-mute)" }}><Icon name="navigation" size={16} /></span>
            <TextInput value={code} onChange={v => { setCode(v); setErr(false); }} placeholder="Tracking number" mono style={{ paddingLeft: 40 }} />
          </div>
          <Button variant="primary" icon="search" onClick={() => doTrack(code)}>Track</Button>
        </div>

        {err && (
          <Card pad={24} style={{ display: "flex", alignItems: "center", gap: 12, background: "var(--danger-soft)", borderColor: "transparent" }}>
            <Icon name="info" size={20} color="var(--danger)" />
            <div style={{ fontSize: 14, color: "var(--fg-strong)" }}>No shipment found for “{code}”. Check the tracking number and try again.</div>
          </Card>
        )}

        {!ship && !err && (
          <Card pad={48} style={{ textAlign: "center", borderStyle: "dashed", background: "var(--bg-mist)" }}>
            <div style={{ width: 56, height: 56, borderRadius: "50%", background: "var(--surface)", display: "inline-flex", alignItems: "center", justifyContent: "center", margin: "0 auto 14px", color: "var(--fg-faint)" }}><Icon name="navigation" size={26} /></div>
            <div style={{ fontSize: 15.5, fontWeight: 600, color: "var(--fg-strong)" }}>Enter a tracking number</div>
            <div style={{ fontSize: 13.5, color: "var(--fg-mute)", marginTop: 5 }}>Open a tracking link from your booking to follow the driver live.</div>
          </Card>
        )}

        {ship && isNF && (
          <div className="fade-up" style={{ display: "flex", flexDirection: "column", gap: 18 }}>
            <NFHero ship={ship} nf={nfInfo} delivered={delivered} />
            <FlightJourneyMap ship={ship} />
            <div style={{ display: "grid", gridTemplateColumns: "minmax(0,1.35fr) minmax(0,1fr)", gap: 18, alignItems: "start" }}>
              <Card pad={22}>
                <div style={{ fontSize: 15, fontWeight: 700, color: "var(--fg-strong)", marginBottom: 18 }}>Progress</div>
                <StepList steps={nfSteps} />
              </Card>
              <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
                <FlightDetailsCard nf={nfInfo} />
                <CourierContact driver={nfInfo.deliveryDriver} role="Delivery courier" delivered={delivered} />
              </div>
            </div>
          </div>
        )}

        {ship && !isNF && (
          <div className="fade-up" style={{ display: "grid", gridTemplateColumns: "minmax(0,1.4fr) minmax(0,1fr)", gap: 22, alignItems: "start" }}>
            <DriverTrackMap ship={ship} driver={driver} />
            <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
              <Card pad={22}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
                  <div>
                    <div style={{ fontFamily: "var(--font-mono)", fontSize: 12, fontWeight: 600, color: "var(--brand)" }}>{ship.code}</div>
                    <div style={{ fontSize: 13, color: "var(--fg-mute)", marginTop: 3 }}>{ship.from} → {ship.to}</div>
                  </div>
                  <Badge tone={delivered ? "success" : "brand"}><StatusDot color={delivered ? "#22b86e" : "var(--brand)"} pulse={!delivered} /> {delivered ? "Delivered" : "In transit"}</Badge>
                </div>
                {ship.context && <div style={{ fontSize: 12.5, color: "var(--fg-mute)", marginBottom: 16, paddingBottom: 14, borderBottom: "1px solid var(--border)" }}>{ship.context}</div>}
                <StepList steps={steps} />
              </Card>
              {driver && driver.phone && (
                <Card pad={18}>
                  <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                    <span style={{ width: 40, height: 40, borderRadius: 10, background: "var(--brand-soft)", color: "var(--brand)", display: "inline-flex", alignItems: "center", justifyContent: "center", flex: "none" }}><Icon name="phone" size={18} /></span>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontWeight: 600, fontSize: 14, color: "var(--fg-strong)" }}>Call your driver</div>
                      <div style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, color: "var(--fg-mute)" }}>{driver.name.split(/\s+/)[0]} · {driver.phone}</div>
                    </div>
                    <a href={"tel:" + driver.phone} style={{ textDecoration: "none" }}><Button variant="secondary" size="sm" icon="phone">Call</Button></a>
                  </div>
                </Card>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<TrackPage />);
