/* ============================================================
   HQ Dispatch Dashboard — primary surface (desktop)
   ============================================================ */

/* ---- Assign modal ---- */
function VehicleBadge({ vehicle, tone, size = 40 }) {
  const num = vehicle ? (String(vehicle.name).match(/\d+/) || [String(vehicle.name).slice(0, 2)])[0] : "?";
  const isCar = vehicle && vehicle.type === "car";
  return (
    <div className="veh-badge" style={{ width: size, height: size, background: `linear-gradient(150deg, var(--${tone}), color-mix(in oklab, var(--${tone}) 70%, #000))` }}>
      <Icon name="car2" style={{ width: 13, height: 13, opacity: 0.85 }} />
      <span className="vb-num">{num}</span>
    </div>
  );
}

function AssignModal({ state, ride, onClose }) {
  const guest = state.guests.find((g) => g.id === ride.guestId);
  // rank drivers: available first, then by vehicle capacity fit
  const avail = state.drivers
    .map((d) => ({ d, v: state.vehicles.find((v) => v.id === d.vehicleId) }))
    .filter((x) => x.v && x.v.cap >= ride.party)
    .sort((a, b) => {
      const av = a.d.status === "available" ? 0 : 1;
      const bv = b.d.status === "available" ? 0 : 1;
      if (av !== bv) return av - bv;
      return a.v.cap - b.v.cap;
    });

  const assign = (driverId) => { Store.assignRide(ride.id, driverId); onClose(); };

  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-h">
          <h3>Assign vehicle</h3>
          <div className="x" onClick={onClose}>✕</div>
        </div>
        <div className="modal-b">
          <div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 16 }}>
            <span className="ride-ic"><Icon name={RIDE_TYPES[ride.type].icon} /></span>
            <div>
              <div className="ride-route">{locName(Store, ride.from)} <span className="ar">→</span> {locName(Store, ride.to)}</div>
              <div className="ride-guest">{guest ? guest.name : (ride.guestName || "Guest")} · party of {ride.party} · {relTime(ride.time)}</div>
            </div>
          </div>
          <label className="lbl">Tap a vehicle to assign</label>
          <div style={{ display: "flex", flexDirection: "column", gap: 8, marginTop: 4 }}>
            {avail.map(({ d, v }) => {
              const st = Store.STATUSES[d.status];
              return (
                <button key={d.id} onClick={() => assign(d.id)} className="assign-opt">
                  <VehicleBadge vehicle={v} tone={st.tone} />
                  <div style={{ textAlign: "left", minWidth: 0 }}>
                    <div style={{ fontWeight: 600 }}>{v.name} <span className="faint" style={{ fontWeight: 500 }}>· {d.name}</span></div>
                    <div className="mono" style={{ fontSize: 11, color: "var(--ink-dim)" }}>{v.cap} seats · {v.plate}</div>
                  </div>
                  <div style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: 10 }}>
                    <Pill tone={st.tone}>{st.label}</Pill>
                    <span className="assign-go"><Icon name="arrow" style={{ width: 16, height: 16 }} /></span>
                  </div>
                </button>
              );
            })}
            {avail.length === 0 && <div className="empty">No vehicle large enough is free.</div>}
          </div>
        </div>
      </div>
    </div>
  );
}

function RideCard({ state, ride, onAssign }) {
  const guest = state.guests.find((g) => g.id === ride.guestId);
  const guestLabel = guest ? guest.name : (ride.guestName || (ride.manual ? "Off-system job" : "New guest"));
  const driver = state.drivers.find((d) => d.id === ride.driverId);
  const t = RIDE_TYPES[ride.type];
  const st = RIDE_STATUS[ride.status];
  const urgent = ride.status === "requested" && ride.time - Date.now() < 20 * 60000;
  return (
    <div className={"ride" + (urgent ? " urgent" : "")}>
      <div className="ride-top">
        <span className="ride-ic"><Icon name={t.icon} /></span>
        <div style={{ minWidth: 0 }}>
          <div className="ride-route">{locName(Store, ride.from)} <span className="ar">→</span> {locName(Store, ride.to)}{ride.walkup && <span className="walkup-tag">WALK-UP</span>}</div>
          <div className="ride-guest">{guestLabel}{ride.flight ? " · " + ride.flight : ""}</div>
        </div>
        <div style={{ marginLeft: "auto" }}><Pill tone={st.tone}>{st.label}</Pill></div>
      </div>
      <div className="ride-meta">
        <span className="m"><Icon name="clock" /> {relTime(ride.time)} · {fmtTime(ride.time)}</span>
        <span className="m"><Icon name="user" /> party {ride.party}</span>
        {driver && <span className="m"><Icon name="car2" /> {driver.name.split(" ")[0]}</span>}
      </div>
      {ride.note && <div style={{ fontSize: 12, color: "var(--ink-dim)", marginTop: 9, fontStyle: "italic" }}>“{ride.note}”</div>}
      {ride.status === "requested" && (
        <div className="ride-actions">
          <button className="btn btn-primary btn-sm" onClick={() => onAssign(ride)}><Icon name="car2" style={{ width: 15, height: 15 }} /> Assign vehicle</button>
        </div>
      )}
      {ride.status === "assigned" && (
        <div className="ride-actions">
          <button className="btn btn-ghost btn-sm" onClick={() => Store.setRideStatus(ride.id, "enroute")}>Mark en route</button>
        </div>
      )}
      {ride.status === "enroute" && (
        <div className="ride-actions">
          <button className="btn btn-ghost btn-sm" onClick={() => Store.setRideStatus(ride.id, "completed")}><Icon name="check" style={{ width: 15, height: 15 }} /> Complete</button>
        </div>
      )}
    </div>
  );
}

/* ---- New request modal (HQ creates on behalf of guest) ---- */
function NewRequestModal({ state, onClose }) {
  const [type, setType] = useState("airport_pickup");
  const [guestName, setGuestName] = useState("");
  const [party, setParty] = useState(1);
  const [mins, setMins] = useState(30);
  const [note, setNote] = useState("");
  // pick sensible default endpoints from the real locations
  const airport = (state.locations.find((l) => l.kind === "airport") || {}).id || "apt";
  const venue = (state.locations.find((l) => l.kind === "venue") || {}).id || "venue";
  const firstHotel = (state.locations.find((l) => l.kind === "hotel") || {}).id || venue;
  const [hotel, setHotel] = useState(firstHotel);
  const hotels = state.locations.filter((l) => l.kind === "hotel" || l.kind === "other");
  const routeFor = (t) => ({
    airport_pickup: [airport, hotel], hotel_venue: [hotel, venue],
    venue_hotel: [venue, hotel], hotel_airport: [hotel, airport],
  }[t]);
  const submit = () => {
    const [from, to] = routeFor(type);
    Store.addRideRequest({ type, guestId: null, guestName: guestName.trim(), from, to, party: Number(party), time: Date.now() + mins * 60000, flight: "", note });
    onClose();
  };
  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-h"><h3>New ride request</h3><div className="x" onClick={onClose}>✕</div></div>
        <div className="modal-b" style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <div><label className="lbl">Type</label>
            <select className="field" value={type} onChange={(e) => setType(e.target.value)}>
              {Object.entries(RIDE_TYPES).map(([k, v]) => <option key={k} value={k}>{v.label}</option>)}
            </select></div>
          <div><label className="lbl">Guest / group name</label>
            <input className="field" value={guestName} onChange={(e) => setGuestName(e.target.value)} placeholder="e.g. Pastor Mark Collard" /></div>
          <div><label className="lbl">{type === "airport_pickup" ? "Drop at hotel" : type === "hotel_airport" ? "Pick up from hotel" : "Hotel"}</label>
            <select className="field" value={hotel} onChange={(e) => setHotel(e.target.value)}>
              {hotels.map((h) => <option key={h.id} value={h.id}>{h.name}</option>)}
            </select></div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
            <div><label className="lbl">Party size</label><input className="field" type="number" min="1" value={party} onChange={(e) => setParty(e.target.value)} /></div>
            <div><label className="lbl">Needed in (min)</label><input className="field" type="number" min="0" value={mins} onChange={(e) => setMins(e.target.value)} /></div>
          </div>
          <div><label className="lbl">Note</label><input className="field" value={note} onChange={(e) => setNote(e.target.value)} placeholder="Optional — gate, terminal, special needs" /></div>
          <div style={{ display: "flex", gap: 9, justifyContent: "flex-end", marginTop: 4 }}>
            <button className="btn btn-ghost" onClick={onClose}>Cancel</button>
            <button className="btn btn-primary" onClick={submit}><Icon name="plus" style={{ width: 16, height: 16 }} /> Add to queue</button>
          </div>
        </div>
      </div>
    </div>
  );
}

function DispatchView({ state }) {
  const [assign, setAssign] = useState(null);
  const [adding, setAdding] = useState(false);
  const [drawer, setDrawer] = useState(false);
  const queue = state.rides.filter((r) => r.status !== "completed")
    .sort((a, b) => a.time - b.time);
  const lastPush = state.broadcasts.find((b) => b.push);
  const pushFresh = lastPush && (Date.now() - lastPush.t < 5 * 60000);

  return (
    <>
      <div className="dispatch-wrap">
        <ShuttleStrip state={state} />
        <div className="dispatch-grid">
        {/* LEFT — ride queue (1/3) */}
        <div className="panel col-fill">
          <div className="panel-h">
            <h3>Ride queue</h3>
            <span className="count">{queue.length}</span>
            <div className="spacer" />
            <button className="btn btn-primary btn-sm" onClick={() => setAdding(true)}><Icon name="plus" style={{ width: 15, height: 15 }} /> New request</button>
          </div>
          <div className="rqueue scroll-fill">
            {queue.length === 0 && <div className="empty">Queue is clear. 🎉</div>}
            {queue.map((r) => <RideCard key={r.id} state={state} ride={r} onAssign={setAssign} />)}
          </div>
        </div>

        {/* RIGHT — live map (2/3) */}
        <div className="panel col-fill">
          <div className="panel-h">
            <h3>Live area map</h3>
            <span className="count">{state.drivers.filter((d) => d.status !== "offline").length} active</span>
            <div className="spacer" />
            <button className="btn btn-ghost btn-sm comms-btn" onClick={() => setDrawer(true)}>
              <Icon name="bell" style={{ width: 15, height: 15 }} /> Broadcast &amp; alerts
              {pushFresh && <span className="comms-dot" />}
            </button>
          </div>
          <div className="map-fill">
            <MapBoard state={state} />
          </div>
        </div>
        </div>
      </div>

      {/* RIGHT DRAWER — broadcast & alerts + activity */}
      <div className={"drawer-scrim" + (drawer ? " open" : "")} onClick={() => setDrawer(false)} />
      <aside className={"drawer" + (drawer ? " open" : "")}>
        <div className="drawer-h">
          <h3>Broadcast &amp; alerts</h3>
          <div className="x" onClick={() => setDrawer(false)}>✕</div>
        </div>
        <div className="drawer-b">
          <BroadcastBox state={state} />
          <div className="drawer-sec-h">Activity</div>
          <div className="feed">
            {state.activity.slice(0, 14).map((a, i) => (
              <div className="feed-row" key={i}>
                <span className="feed-dot" />
                <div><div className="ftext">{a.text}</div><div className="ftime mono">{fmtTime(a.t)}</div></div>
              </div>
            ))}
          </div>
        </div>
      </aside>

      {assign && <AssignModal state={state} ride={assign} onClose={() => setAssign(null)} />}
      {adding && <NewRequestModal state={state} onClose={() => setAdding(false)} />}
    </>
  );
}

function BroadcastBox({ state }) {
  const [txt, setTxt] = useState("");
  const presets = ["Lunch rush — stage at venue", "Heavy arrivals next hour", "Weather delay, hold for updates"];
  const pushPresets = [
    "Main session ending — guests heading out, all vans to venue now",
    "Evening session done — start hotel runs",
    "Keynote wrapping in 10 min — stage at venue",
  ];
  return (
    <div style={{ padding: 14 }}>
      {/* prominent push alert */}
      <div className="push-composer">
        <div className="pc-head"><Icon name="bell" style={{ width: 15, height: 15 }} /> Push alert — pops up on every driver’s phone</div>
        <div className="pc-presets">
          {pushPresets.map((p) => (
            <button key={p} className="pc-preset" onClick={() => Store.pushNotification(p)}>{p}</button>
          ))}
        </div>
      </div>

      <div className="m-sec-h" style={{ margin: "16px 0 8px" }}>Normal message</div>
      <div style={{ display: "flex", gap: 8 }}>
        <input className="field" placeholder={`Message all ${state.drivers.length} drivers…`} value={txt}
          onChange={(e) => setTxt(e.target.value)}
          onKeyDown={(e) => { if (e.key === "Enter" && txt.trim()) { Store.broadcast(txt.trim()); setTxt(""); } }} />
        <button className="btn btn-primary" disabled={!txt.trim()} onClick={() => { Store.broadcast(txt.trim()); setTxt(""); }}>
          <Icon name="send" style={{ width: 16, height: 16 }} /></button>
      </div>
      <div className="canned" style={{ padding: "10px 0 0" }}>
        {presets.map((p) => <button key={p} onClick={() => Store.broadcast(p)}>{p}</button>)}
      </div>
      {state.broadcasts.length > 0 && (
        <>
          <hr className="divider" />
          <div className="m-sec-h" style={{ margin: "0 0 8px" }}>Recent</div>
          {state.broadcasts.slice(0, 3).map((b) => (
            <div key={b.id} style={{ fontSize: 12.5, color: "var(--ink-dim)", padding: "6px 0", display: "flex", gap: 8 }}>
              <Icon name={b.push ? "bell" : "send"} style={{ width: 14, height: 14, color: b.push ? "var(--amber)" : "var(--ink-faint)", flex: "none", marginTop: 2 }} />
              <div>{b.text}{b.push && <span style={{ color: "var(--amber)", fontSize: 10.5, fontWeight: 700, marginLeft: 6 }}>PUSH</span>}<div className="mono faint" style={{ fontSize: 10.5, marginTop: 2 }}>{fmtTime(b.t)}</div></div>
            </div>
          ))}
        </>
      )}
    </div>
  );
}

Object.assign(window, { DispatchView, AssignModal, RideCard, NewRequestModal });
