// Recursive MLS — Screen 7: Showings (scheduling + tours + feedback).
// RECEIVED: requests on my listings — schedule with seller calendar sync, collect
// buyer-agent feedback, share with seller, get AI selling tips.
// SENT: tours I book for buyers — calendar-synced availability, route optimization,
// per-stop walkthrough feedback, submit feedback to listing agents.
function Showings({ go }) {
  const S = window.RC_SHOWINGS;
  const [side, setSide] = useState("received");
  const [selId, setSelId] = useState("SR-3092");
  const list = side === "received" ? S.received : S.sent;
  const sel = list.find((x) => x.id === selId) || list[0];
  React.useEffect(() => { if (!list.find((x) => x.id === selId)) setSelId(list[0].id); }, [side]);

  const Pill = ({ map, k, sm }) => { const c = map[k] || { c: "#6b706a", b: "#f0efe9" }; return <span style={{ fontSize: sm ? 10.5 : 11, fontWeight: 600, color: c.c, background: c.b, borderRadius: 999, padding: sm ? "2px 8px" : "3px 10px", whiteSpace: "nowrap" }}>{k}</span>; };

  const counts = {
    received: S.received.filter((x) => x.status === "Requested").length,
    sent: S.sent.filter((x) => x.status === "Planning").length,
  };

  return (
    <div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
      <div style={{ flex: "none", padding: "18px 24px 0", display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 14, flexWrap: "wrap" }}>
        <div>
          <h1 style={{ margin: 0, fontSize: 23, fontWeight: 600, letterSpacing: "-0.5px", color: "#1d241f" }}>Showings</h1>
          <p style={{ margin: "4px 0 0", fontSize: 13.5, color: "#8a8e88" }}>{counts.received} request{counts.received !== 1 ? "s" : ""} awaiting your response · {counts.sent} tour being planned</p>
        </div>
        <button style={btnPrimary}><Icon name={side === "received" ? "calendar-plus" : "route"} size={15} color="#fff" /> {side === "received" ? "Block showing time" : "Plan a tour"}</button>
      </div>

      <div style={{ flex: 1, display: "grid", gridTemplateColumns: "minmax(340px, 0.85fr) 1.7fr", minHeight: 0, padding: "16px 24px 0" }}>
        {/* LIST */}
        <div style={{ display: "flex", flexDirection: "column", minHeight: 0, background: "#fff", borderRadius: "3px 0 0 3px", boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)" }}>
          <div style={{ padding: "11px 12px", borderBottom: "1px solid #f1f0ea" }}>
            <div style={{ display: "inline-flex", width: "100%", background: "#f1f0ea", borderRadius: 8, padding: 3 }}>
              {[["received", "Received", "on my listings"], ["sent", "Sent", "for my buyers"]].map(([k, lab, sub]) => (
                <button key={k} onClick={() => setSide(k)} style={{ flex: 1, fontFamily: "inherit", cursor: "pointer", border: 0, borderRadius: 6, padding: "7px 10px",
                  background: side === k ? "#fff" : "transparent", boxShadow: side === k ? "0 1px 2px rgba(0,0,0,.12)" : "none" }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color: side === k ? "#006747" : "#8a8e88" }}>{lab}</div>
                  <div style={{ fontSize: 10.5, color: "#a8aca6" }}>{sub}</div>
                </button>
              ))}
            </div>
          </div>
          <div style={{ flex: 1, overflowY: "auto" }}>
            {list.map((x) => {
              const on = x.id === sel.id;
              const title = side === "received" ? x.property : `${x.client}'s tour`;
              const subtitle = side === "received" ? `${x.buyerAgent.brokerage} · ${x.buyerName}` : `${x.stops.length} stops · ${x.date}`;
              return (
                <div key={x.id} onClick={() => setSelId(x.id)} className="rc-row" style={{ display: "flex", gap: 11, padding: "13px 14px", cursor: "pointer", borderBottom: "1px solid #f6f5f0", background: on ? "#f3f6f4" : "transparent", borderLeft: on ? "2.5px solid #006747" : "2.5px solid transparent" }}>
                  {side === "received"
                    ? <div style={{ width: 50, height: 50, borderRadius: 6, backgroundImage: `url(${S.img(x.photo)})`, backgroundSize: "cover", backgroundPosition: "center", flex: "none" }} />
                    : <div style={{ width: 50, height: 50, borderRadius: 6, background: "#eef4f1", display: "flex", alignItems: "center", justifyContent: "center", flex: "none", position: "relative" }}><Icon name="route" size={20} color="#006747" /><span style={{ position: "absolute", bottom: -4, right: -4, width: 19, height: 19, borderRadius: "50%", background: "#006747", color: "#fff", fontSize: 10, fontWeight: 700, display: "flex", alignItems: "center", justifyContent: "center", border: "2px solid #fff" }}>{x.stops.length}</span></div>}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600, color: "#1d241f", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{title}</div>
                    <div style={{ fontSize: 11.5, color: "#8a8e88", marginTop: 2, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{subtitle}</div>
                    <div style={{ display: "flex", alignItems: "center", gap: 7, marginTop: 7 }}>
                      <Pill map={S.statusColor} k={x.status} sm />
                      <span style={{ fontSize: 11, color: "#bcbfba" }}>{side === "received" ? (x.confirmedSlot || x.requested) : x.window}</span>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {/* DETAIL */}
        <div style={{ display: "flex", flexDirection: "column", minHeight: 0, background: "#fbfaf7", borderRadius: "0 3px 3px 0", boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)" }}>
          {side === "received" ? <ReceivedDetail key={sel.id} r={sel} S={S} go={go} /> : <TourDetail key={sel.id} t={sel} S={S} go={go} />}
        </div>
      </div>
    </div>
  );
}

// ============ shared: calendar sync + 7-day availability ============
function CalendarSync({ S, parties, labels, syncable }) {
  const provLogos = { google: "Google Calendar", o365: "Microsoft 365", ical: "Apple iCloud" };
  const [synced, setSynced] = useState(() => { const o = {}; parties.forEach((p) => { o[p] = syncable[p] || null; }); return o; });
  const firstWeekend = S.DAYS.findIndex((d) => d.weekend);
  const [day, setDay] = useState(firstWeekend < 0 ? 0 : firstWeekend); // default to the weekend — when most showings happen
  const free = S.mutualFreeDay(parties, day);
  const windows = S.weekWindows(parties);

  return (
    <div style={{ background: "#fff", borderRadius: 6, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", padding: 16, marginBottom: 14 }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
        <h3 style={{ margin: 0, fontSize: 13.5, fontWeight: 600, color: "#1d241f", display: "flex", alignItems: "center", gap: 7 }}><Icon name="calendar-sync" size={16} color="#006747" /> Find a time that works</h3>
        <span style={{ fontSize: 11.5, color: "#a8aca6" }}>next 7 days · synced live</span>
      </div>

      {/* parties + connect */}
      <div style={{ display: "flex", flexDirection: "column", gap: 7, marginBottom: 14 }}>
        {parties.map((p) => (
          <div key={p} style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <span style={{ width: 22, height: 22, borderRadius: "50%", background: "#e7e1d4", color: "#006747", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 10, fontWeight: 700, flex: "none" }}>{labels[p][0]}</span>
            <span style={{ fontSize: 13, color: "#1d241f", fontWeight: 500, flex: 1 }}>{labels[p]}</span>
            {synced[p]
              ? <span style={{ display: "inline-flex", alignItems: "center", gap: 5, fontSize: 11.5, fontWeight: 600, color: "#1f8a5b" }}><Icon name="check-circle-2" size={13} color="#1f8a5b" /> {provLogos[synced[p]]}</span>
              : <button onClick={() => setSynced({ ...synced, [p]: "google" })} style={{ display: "inline-flex", alignItems: "center", gap: 5, fontFamily: "inherit", fontSize: 11.5, fontWeight: 600, color: "#006747", background: "#eef4f1", border: 0, borderRadius: 6, padding: "4px 9px", cursor: "pointer" }}><Icon name="calendar-plus" size={12} color="#006747" /> Connect calendar</button>}
          </div>
        ))}
      </div>

      {/* 7-day selector — weekends emphasized */}
      <div style={{ display: "flex", gap: 6, marginBottom: 14 }}>
        {S.DAYS.map((d, i) => {
          const on = i === day;
          return (
            <button key={d.key} onClick={() => setDay(i)} style={{ flex: 1, fontFamily: "inherit", cursor: "pointer", borderRadius: 8, padding: "7px 4px", textAlign: "center",
              border: on ? "1px solid #006747" : "1px solid #e7e5df", background: on ? "#006747" : (d.weekend ? "#f3f6f4" : "#fff") }}>
              <div style={{ fontSize: 11, fontWeight: 700, color: on ? "#fff" : (d.weekend ? "#006747" : "#8a8e88"), display: "flex", alignItems: "center", justifyContent: "center", gap: 3 }}>{d.weekend && !on ? <Icon name="star" size={9} color="#006747" style={{ fill: "#006747" }} /> : null}{d.dow}</div>
              <div style={{ fontSize: 10, color: on ? "rgba(255,255,255,.85)" : "#bcbfba", marginTop: 1 }}>{d.date.replace("Jun ", "")}</div>
            </button>
          );
        })}
      </div>
      {S.DAYS[day].weekend && <div style={{ fontSize: 11.5, color: "#006747", marginBottom: 10, display: "flex", alignItems: "center", gap: 5 }}><Icon name="sparkles" size={12} color="#006747" /> Weekend — the most popular showing window.</div>}

      {/* availability grid for selected day */}
      <div style={{ overflowX: "auto" }}>
        <div style={{ minWidth: 540 }}>
          <div style={{ display: "grid", gridTemplateColumns: `92px repeat(${S.SLOTS.length}, 1fr)`, gap: 2, alignItems: "center" }}>
            <div></div>
            {S.SLOTS.map((s, i) => <div key={i} style={{ fontSize: 8.5, color: "#bcbfba", textAlign: "center" }}>{i % 2 === 0 ? S.fmtSlot(s) : ""}</div>)}
            {parties.map((p) => (
              <React.Fragment key={p}>
                <div style={{ fontSize: 11.5, color: "#6b706a", fontWeight: 600, paddingRight: 6, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{labels[p].split(" ")[0]}</div>
                {S.SLOTS.map((s, i) => { const b = S.busyFor(p, day).includes(i); return <div key={i} title={S.fmtSlot(s)} style={{ height: 16, borderRadius: 2, background: b ? "#ede9e0" : "#cfe6da" }} />; })}
              </React.Fragment>
            ))}
            <div style={{ fontSize: 11.5, color: "#006747", fontWeight: 700, paddingRight: 6, paddingTop: 4 }}>All free</div>
            {free.map((f, i) => <div key={i} style={{ height: 16, borderRadius: 2, marginTop: 4, background: f ? "#006747" : "#f1f0ea" }} />)}
          </div>
        </div>
      </div>

      {/* suggested windows across the week (weekends first) */}
      <div style={{ marginTop: 14 }}>
        <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".6px", color: "#a8aca6", marginBottom: 8 }}>When everyone's free this week</div>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
          {windows.length ? windows.slice(0, 6).map((w, i) => {
            const d = S.DAYS[w.dayIdx];
            return (
              <button key={i} onClick={() => setDay(w.dayIdx)} style={{ display: "inline-flex", alignItems: "center", gap: 7, fontFamily: "inherit", fontSize: 12.5, fontWeight: 600, color: d.weekend ? "#fff" : "#006747", background: d.weekend ? "#006747" : "#fff", border: "1px solid #006747", borderRadius: 8, padding: "7px 12px", cursor: "pointer" }}>
                <Icon name="clock" size={13} color={d.weekend ? "#fff" : "#006747"} /> {d.dow} {S.fmtSlot(S.SLOTS[w.a])}–{S.fmtSlot(S.SLOTS[Math.min(w.b + 1, S.SLOTS.length - 1)])}
                {d.weekend && <span style={{ fontSize: 9, fontWeight: 700, background: "rgba(255,255,255,.25)", borderRadius: 4, padding: "1px 5px", textTransform: "uppercase", letterSpacing: ".3px" }}>Wknd</span>}
              </button>
            );
          }) : <span style={{ fontSize: 12.5, color: "#a8aca6" }}>No fully-mutual window — propose a time or adjust.</span>}
        </div>
      </div>
    </div>
  );
}

// ============ RECEIVED detail ============
function ReceivedDetail({ r, S, go }) {
  const labels = { agent: "You (listing agent)", seller: r.seller.name + " (seller)" };
  const [tab, setTab] = useState(r.status === "Completed" ? "feedback" : "schedule");
  const tips = S.sellerTips(r.property);
  return (
    <React.Fragment>
      <div style={{ flex: "none", background: "#fff", borderRadius: "0 3px 0 0", borderBottom: "1px solid #f1f0ea" }}>
        <div style={{ position: "relative", height: 104, backgroundImage: `linear-gradient(180deg, rgba(0,0,0,0) 35%, rgba(0,0,0,.5)), url(${S.img(r.photo, 800)})`, backgroundSize: "cover", backgroundPosition: "center", borderRadius: "0 3px 0 0" }}>
          <div style={{ position: "absolute", left: 20, bottom: 12, right: 20, display: "flex", alignItems: "flex-end", justifyContent: "space-between" }}>
            <div>
              <div style={{ fontSize: 17, fontWeight: 600, color: "#fff" }}>{r.property}</div>
              <div style={{ fontSize: 12.5, color: "rgba(255,255,255,.85)", marginTop: 2 }}>{r.area} · ${(r.listPrice / 1000).toFixed(0)}K · {r.dom} days on market · {r.type}</div>
            </div>
            <span style={{ fontSize: 12, fontWeight: 600, color: (S.statusColor[r.status] || {}).c, background: "#fff", borderRadius: 999, padding: "4px 11px" }}>{r.status}</span>
          </div>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "12px 20px" }}>
          <div style={{ width: 30, height: 30, borderRadius: "50%", background: "#006747", color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 11, fontWeight: 600 }}>{r.buyerAgent.name.split(" ").map((w) => w[0]).join("")}</div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 600, color: "#1d241f" }}>{r.buyerAgent.name} · {r.buyerAgent.brokerage}</div>
            <div style={{ fontSize: 11.5, color: "#8a8e88" }}>Showing buyer {r.buyerName} · {r.buyerAgent.phone}</div>
          </div>
          <button style={{ ...btnOutline, padding: "7px 11px", fontSize: 12.5 }}><Icon name="message-square" size={14} color="#006747" /> Message</button>
        </div>
        <div style={{ display: "flex", gap: 4, padding: "0 20px" }}>
          {[["schedule", "Schedule"], ["feedback", "Feedback"], ["tips", "Selling tips"]].map(([id, lab]) => (
            <button key={id} onClick={() => setTab(id)} style={{ fontFamily: "inherit", fontSize: 13, fontWeight: 600, cursor: "pointer", border: 0, background: "transparent", padding: "10px 12px", color: tab === id ? "#006747" : "#8a8e88", borderBottom: tab === id ? "2px solid #006747" : "2px solid transparent", marginBottom: -1 }}>{lab}</button>
          ))}
        </div>
      </div>

      <div style={{ flex: 1, overflowY: "auto", padding: 20 }}>
        {tab === "schedule" && (
          <React.Fragment>
            {r.status === "Confirmed" && (
              <div style={{ display: "flex", alignItems: "center", gap: 11, padding: "12px 14px", marginBottom: 14, borderRadius: 8, background: "#e8f4ee", border: "1px solid #cfe6da" }}>
                <Icon name="check-circle-2" size={18} color="#1f8a5b" />
                <div style={{ flex: 1 }}><div style={{ fontSize: 13, fontWeight: 600, color: "#1d241f" }}>Confirmed · {r.confirmedSlot}</div><div style={{ fontSize: 12, color: "#6b706a" }}>Added to your calendar and {r.seller.name}'s. Buyer's agent notified.</div></div>
                <button style={{ ...btnOutline, padding: "7px 11px", fontSize: 12.5 }}>Reschedule</button>
              </div>
            )}
            {/* requested windows */}
            {r.proposed.length > 0 && r.status !== "Confirmed" && (
              <div style={{ marginBottom: 14 }}>
                <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".6px", color: "#a8aca6", marginBottom: 8 }}>Buyer's agent proposed</div>
                <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                  {r.proposed.map((w, i) => (
                    <div key={i} style={{ display: "flex", alignItems: "center", gap: 11, padding: "11px 13px", borderRadius: 8, background: "#fff", boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)" }}>
                      <Icon name="calendar" size={16} color="#006747" />
                      <div style={{ flex: 1 }}><div style={{ fontSize: 13, fontWeight: 600, color: "#1d241f" }}>{w.day}</div><div style={{ fontSize: 12, color: "#8a8e88" }}>{S.fmtSlot(w.start)}–{S.fmtSlot(w.end)}</div></div>
                      <button style={{ ...btnPrimary, padding: "7px 13px", fontSize: 12.5 }}><Icon name="check" size={13} color="#fff" /> Confirm</button>
                    </div>
                  ))}
                </div>
              </div>
            )}
            <CalendarSync S={S} parties={r.parties} labels={labels} syncable={{ seller: r.seller.synced }} />
            <div style={{ display: "flex", gap: 9 }}>
              <button style={{ ...btnPrimary, flex: 1, justifyContent: "center" }}><Icon name="user-plus" size={15} color="#fff" /> Invite {r.seller.name} to confirm</button>
              <button style={{ ...btnOutline, flex: 1, justifyContent: "center" }}><Icon name="calendar-clock" size={15} color="#006747" /> Propose a different time</button>
            </div>
          </React.Fragment>
        )}

        {tab === "feedback" && (r.feedback ? <FeedbackCard fb={r.feedback} S={S} listingSide /> : <Empty icon="message-square-dashed" title="No feedback yet" body="Feedback appears here after the showing is completed and the buyer's agent submits it." />)}

        {tab === "tips" && (
          <React.Fragment>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }}>
              <Icon name="sparkles" size={16} color="#006747" />
              <h3 style={{ margin: 0, fontSize: 14.5, fontWeight: 600, color: "#1d241f" }}>Tips to get {r.property} sold</h3>
              <span style={{ fontSize: 11, fontWeight: 600, color: "#006747", background: "#eef4f1", borderRadius: 999, padding: "2px 8px" }}>reCURSIVE AI</span>
            </div>
            <p style={{ margin: "0 0 16px", fontSize: 12.5, color: "#8a8e88", lineHeight: 1.5 }}>Synthesized from {S.listingContext[r.property] ? S.listingContext[r.property].showings : "recent"} showings of feedback and {r.dom} days on market vs. the area average.</p>
            <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
              {tips.map((t, i) => {
                const tone = { warn: { c: "#9a6a12", b: "#fbf2dc" }, ok: { c: "#1f8a5b", b: "#e8f4ee" }, info: { c: "#2a6f8a", b: "#e8f0f3" } }[t.tone];
                return (
                  <div key={i} style={{ display: "flex", gap: 12, padding: "13px 15px", borderRadius: 8, background: "#fff", boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)" }}>
                    <span style={{ width: 32, height: 32, borderRadius: 8, background: tone.b, display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}><Icon name={t.icon} size={16} color={tone.c} /></span>
                    <div><div style={{ fontSize: 13.5, fontWeight: 600, color: "#1d241f", marginBottom: 3 }}>{t.title}</div><div style={{ fontSize: 12.5, color: "#6b706a", lineHeight: 1.5 }}>{t.body}</div></div>
                  </div>
                );
              })}
            </div>
            <button onClick={() => go && go("clients")} style={{ ...btnOutline, marginTop: 14 }}><Icon name="send" size={14} color="#006747" /> Share summary with {r.seller.name}</button>
          </React.Fragment>
        )}
      </div>
    </React.Fragment>
  );
}

// ============ SENT (tour) detail ============
function TourDetail({ t, S, go }) {
  const [stops, setStops] = useState(t.stops);
  const [optimized, setOptimized] = useState(t.routeOptimized);
  const [fbStop, setFbStop] = useState(null);
  const labels = { agent: "You", buyer: t.client, coBuyer: t.coClient || "Co-buyer" };
  const parties = t.parties;
  const totalDrive = stops.reduce((s, x) => s + x.driveMin, 0);
  const dist = (a, b) => Math.hypot(a.coord[0] - b.coord[0], a.coord[1] - b.coord[1]);

  const optimize = () => {
    // nearest-neighbour from the first stop, recompute drive minutes
    const rest = stops.slice(1);
    const ordered = [stops[0]];
    let cur = stops[0];
    while (rest.length) {
      let bi = 0, bd = Infinity;
      rest.forEach((s, i) => { const d = dist(cur, s); if (d < bd) { bd = d; bi = i; } });
      cur = rest.splice(bi, 1)[0];
      ordered.push(cur);
    }
    // recompute times + drive from 1:00 PM
    let mins = 13 * 60;
    const out = ordered.map((s, i) => {
      const dm = i === 0 ? 0 : Math.max(5, Math.round(dist(ordered[i - 1], s) * 900));
      mins += dm + (i === 0 ? 0 : 30); // 30 min per showing
      const hh = Math.floor(mins / 60), mm = mins % 60;
      const t12 = (hh > 12 ? hh - 12 : hh) + ":" + String(mm).padStart(2, "0") + " " + (hh >= 12 ? "PM" : "AM");
      return { ...s, driveMin: dm, time: t12 };
    });
    setStops(out); setOptimized(true);
  };

  const completed = t.status === "Completed";
  const withFb = stops.filter((s) => s.feedback).length;

  return (
    <React.Fragment>
      <div style={{ flex: "none", background: "#fff", borderRadius: "0 3px 0 0", borderBottom: "1px solid #f1f0ea", padding: "16px 20px" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <div style={{ flex: 1 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <h2 style={{ margin: 0, fontSize: 18, fontWeight: 600, color: "#1d241f" }}>{t.client}'s tour</h2>
              <span style={{ fontSize: 12, fontWeight: 600, color: (S.statusColor[t.status] || {}).c, background: (S.statusColor[t.status] || {}).b, borderRadius: 999, padding: "3px 10px" }}>{t.status}</span>
            </div>
            <div style={{ fontSize: 12.5, color: "#8a8e88", marginTop: 3 }}>{t.date} · {t.window} · {stops.length} homes{t.coClient ? ` · with ${t.coClient}` : ""}</div>
          </div>
          <button onClick={() => go && go("clients")} style={{ ...btnOutline, padding: "7px 11px", fontSize: 12.5 }}><Icon name="user" size={14} color="#006747" /> Client</button>
        </div>
      </div>

      <div style={{ flex: 1, overflowY: "auto", padding: 20 }}>
        {fbStop !== null ? (
          <WalkthroughForm stop={stops[fbStop]} client={t.client} onSave={(fb) => { setStops(stops.map((s, i) => i === fbStop ? { ...s, feedback: fb, status: "Completed" } : s)); setFbStop(null); }} onCancel={() => setFbStop(null)} />
        ) : (
          <React.Fragment>
            {/* route */}
            <div style={{ background: "#fff", borderRadius: 6, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", padding: 16, marginBottom: 14 }}>
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
                <h3 style={{ margin: 0, fontSize: 13.5, fontWeight: 600, color: "#1d241f", display: "flex", alignItems: "center", gap: 7 }}><Icon name="route" size={16} color="#006747" /> Tour route</h3>
                <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                  <span style={{ fontSize: 12, color: "#6b706a" }}><b style={{ fontFamily: "'Space Mono', monospace" }}>{totalDrive}</b> min driving · <b style={{ fontFamily: "'Space Mono', monospace" }}>{stops.length}</b> stops</span>
                  <button onClick={optimize} disabled={optimized} style={{ ...(optimized ? btnOutline : btnPrimary), padding: "7px 12px", fontSize: 12.5, opacity: optimized ? 0.6 : 1, cursor: optimized ? "default" : "pointer" }}>
                    <Icon name={optimized ? "check" : "wand-2"} size={14} color={optimized ? "#006747" : "#fff"} /> {optimized ? "Route optimized" : "Optimize route"}
                  </button>
                </div>
              </div>
              <RouteMap stops={stops} S={S} />
            </div>

            {/* stops */}
            <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".6px", color: "#a8aca6", marginBottom: 10 }}>Stops {completed ? `· ${withFb}/${stops.length} with feedback` : ""}</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 9, marginBottom: 16 }}>
              {stops.map((s, i) => (
                <div key={s.listingId} style={{ display: "flex", gap: 12, padding: 11, borderRadius: 8, background: "#fff", boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)" }}>
                  <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 4, flex: "none" }}>
                    <span style={{ width: 24, height: 24, borderRadius: "50%", background: "#006747", color: "#fff", fontSize: 12, fontWeight: 700, display: "flex", alignItems: "center", justifyContent: "center" }}>{i + 1}</span>
                    <span style={{ fontSize: 11, fontWeight: 700, fontFamily: "'Space Mono', monospace", color: "#1d241f" }}>{s.time}</span>
                  </div>
                  <div style={{ width: 56, height: 56, borderRadius: 6, backgroundImage: `url(${S.img(s.photo)})`, backgroundSize: "cover", backgroundPosition: "center", flex: "none" }} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600, color: "#1d241f", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{s.property}</div>
                    <div style={{ fontSize: 11.5, color: "#8a8e88", marginTop: 1 }}>{s.area} · ${(s.price / 1000).toFixed(0)}K · {s.beds}bd · {s.listingAgent}</div>
                    <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 6 }}>
                      <span style={{ fontSize: 11, fontWeight: 600, color: (S.statusColor[s.status] || {}).c, background: (S.statusColor[s.status] || {}).b, borderRadius: 999, padding: "2px 8px" }}>{s.status}</span>
                      {i > 0 && <span style={{ fontSize: 11, color: "#bcbfba", display: "inline-flex", alignItems: "center", gap: 3 }}><Icon name="car" size={11} color="#bcbfba" /> {s.driveMin} min</span>}
                      {s.feedback && <span style={{ fontSize: 11, color: (S.interestColor[s.feedback.interest] || {}).c, fontWeight: 600 }}>★ {s.feedback.rating}/5 · {s.feedback.interest}</span>}
                    </div>
                  </div>
                  <button onClick={() => setFbStop(i)} style={{ ...btnOutline, padding: "7px 11px", fontSize: 12, alignSelf: "center" }}>
                    <Icon name={s.feedback ? "pencil" : "clipboard-list"} size={13} color="#006747" /> {s.feedback ? "Edit" : "Feedback"}
                  </button>
                </div>
              ))}
            </div>

            {/* calendar sync to confirm window */}
            {!completed && <CalendarSync S={S} parties={parties} labels={labels} syncable={{ buyer: "google" }} />}

            <div style={{ display: "flex", gap: 9 }}>
              {!completed
                ? <React.Fragment>
                    <button style={{ ...btnPrimary, flex: 1, justifyContent: "center" }}><Icon name="send" size={15} color="#fff" /> Request all showings</button>
                    <button style={{ ...btnOutline, flex: 1, justifyContent: "center" }}><Icon name="share-2" size={15} color="#006747" /> Share itinerary with {t.client}</button>
                  </React.Fragment>
                : <button style={{ ...btnPrimary, flex: 1, justifyContent: "center" }}><Icon name="send" size={15} color="#fff" /> Send feedback to listing agents</button>}
            </div>
          </React.Fragment>
        )}
      </div>
    </React.Fragment>
  );
}

// ============ route map (real map via Leaflet) ============
function RouteMap({ stops, S }) {
  const ref = React.useRef(null);
  const mapRef = React.useRef(null);
  const layersRef = React.useRef([]);
  React.useEffect(() => {
    if (!window.L || !ref.current) return;
    if (!mapRef.current) {
      mapRef.current = window.L.map(ref.current, { zoomControl: false, scrollWheelZoom: false, attributionControl: true });
      window.L.tileLayer("https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png", {
        maxZoom: 19, attribution: "© OpenStreetMap, © CARTO",
      }).addTo(mapRef.current);
      window.L.control.zoom({ position: "bottomright" }).addTo(mapRef.current);
    }
    const map = mapRef.current;
    layersRef.current.forEach((l) => map.removeLayer(l));
    layersRef.current = [];
    const coords = stops.map((s) => s.coord);
    const line = window.L.polyline(coords, { color: "#006747", weight: 3, opacity: 0.85, dashArray: "7 7" }).addTo(map);
    layersRef.current.push(line);
    stops.forEach((s, i) => {
      const icon = window.L.divIcon({
        className: "",
        html: `<div style="width:26px;height:26px;border-radius:50% 50% 50% 0;transform:rotate(-45deg);background:#006747;box-shadow:0 2px 6px rgba(0,0,0,.4);border:2px solid #fff;display:flex;align-items:center;justify-content:center"><span style="transform:rotate(45deg);color:#fff;font:700 12px 'Space Grotesk',sans-serif">${i + 1}</span></div>`,
        iconSize: [26, 26], iconAnchor: [13, 24],
      });
      const m = window.L.marker(s.coord, { icon }).addTo(map);
      m.bindTooltip(`${i + 1}. ${s.property}`, { direction: "top", offset: [0, -22] });
      layersRef.current.push(m);
    });
    map.fitBounds(window.L.latLngBounds(coords).pad(0.3));
    const t = setTimeout(() => map.invalidateSize(), 120);
    return () => clearTimeout(t);
  }, [stops]);
  React.useEffect(() => () => { if (mapRef.current) { mapRef.current.remove(); mapRef.current = null; } }, []);
  return (
    <div style={{ position: "relative" }}>
      <div ref={ref} style={{ height: 230, borderRadius: 8, overflow: "hidden", boxShadow: "inset 0 0 0 1px rgba(0,0,0,.1)", background: "#eef1ee", zIndex: 0 }} />
      <div style={{ position: "absolute", top: 10, left: 10, zIndex: 500, fontSize: 10.5, color: "#1d241f", background: "rgba(255,255,255,.92)", borderRadius: 6, padding: "4px 9px", fontWeight: 600, boxShadow: "0 1px 4px rgba(0,0,0,.15)", display: "inline-flex", alignItems: "center", gap: 5, pointerEvents: "none" }}>
        <span style={{ width: 8, height: 8, borderRadius: "50%", background: "#006747" }}></span> Optimized for least driving
      </div>
    </div>
  );
}

// ============ walkthrough feedback form (buyer, on-site) ============
function WalkthroughForm({ stop, client, onSave, onCancel }) {
  const init = stop.feedback || { rating: 0, interest: "Moderate", priceOpinion: "About right", liked: [], concerns: [], comments: "", wouldReturn: false };
  const [rating, setRating] = useState(init.rating);
  const [interest, setInterest] = useState(init.interest);
  const [price, setPrice] = useState(init.priceOpinion);
  const [comments, setComments] = useState(init.comments);
  const [liked, setLiked] = useState(init.liked);
  const [concerns, setConcerns] = useState(init.concerns);
  const likeOpts = ["Layout", "Kitchen", "Natural light", "Outdoor space", "Location", "Finishes", "Views", "Storage"];
  const concernOpts = ["Price", "Condition", "Noise", "Small bedrooms", "No parking", "Dated baths", "Layout", "HOA fees"];
  const tog = (arr, set, v) => set(arr.includes(v) ? arr.filter((x) => x !== v) : [...arr, v]);
  const Chip = ({ on, onClick, children, color }) => (
    <button onClick={onClick} style={{ fontFamily: "inherit", fontSize: 12.5, fontWeight: 500, cursor: "pointer", padding: "6px 11px", borderRadius: 999, border: on ? `1px solid ${color}` : "1px solid #e2e0d8", background: on ? (color === "#c0612f" ? "#faece3" : "#eef4f1") : "#fff", color: on ? color : "#4a504a" }}>{children}</button>
  );
  return (
    <div>
      <button onClick={onCancel} style={{ display: "inline-flex", alignItems: "center", gap: 5, fontFamily: "inherit", fontSize: 12.5, fontWeight: 600, color: "#6b706a", background: "none", border: 0, cursor: "pointer", padding: 0, marginBottom: 12 }}><Icon name="arrow-left" size={14} color="#6b706a" /> Back to tour</button>
      <div style={{ display: "flex", gap: 12, marginBottom: 16, alignItems: "center" }}>
        <div style={{ width: 52, height: 52, borderRadius: 6, backgroundImage: `url(${window.RC_SHOWINGS.img(stop.photo)})`, backgroundSize: "cover", backgroundPosition: "center", flex: "none" }} />
        <div><div style={{ fontSize: 15, fontWeight: 600, color: "#1d241f" }}>{stop.property}</div><div style={{ fontSize: 12.5, color: "#8a8e88" }}>Walkthrough feedback · {client}</div></div>
      </div>

      <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
        <div>
          <label style={fbLabel}>Overall rating</label>
          <div style={{ display: "flex", gap: 6 }}>
            {[1, 2, 3, 4, 5].map((n) => <button key={n} onClick={() => setRating(n)} style={{ background: "none", border: 0, cursor: "pointer", padding: 0 }}><Icon name="star" size={28} color={n <= rating ? "#e0a020" : "#dcdad1"} style={{ fill: n <= rating ? "#e0a020" : "none" }} /></button>)}
          </div>
        </div>
        <div style={{ display: "flex", gap: 24, flexWrap: "wrap" }}>
          <div>
            <label style={fbLabel}>Buyer interest</label>
            <div style={{ display: "flex", gap: 7 }}>{["High", "Moderate", "Low"].map((o) => <Chip key={o} on={interest === o} onClick={() => setInterest(o)} color="#006747">{o}</Chip>)}</div>
          </div>
          <div>
            <label style={fbLabel}>Price opinion</label>
            <div style={{ display: "flex", gap: 7 }}>{["Worth it", "About right", "Overpriced"].map((o) => <Chip key={o} on={price === o} onClick={() => setPrice(o)} color="#006747">{o}</Chip>)}</div>
          </div>
        </div>
        <div>
          <label style={fbLabel}>What they liked</label>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 7 }}>{likeOpts.map((o) => <Chip key={o} on={liked.includes(o)} onClick={() => tog(liked, setLiked, o)} color="#006747">{o}</Chip>)}</div>
        </div>
        <div>
          <label style={fbLabel}>Concerns</label>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 7 }}>{concernOpts.map((o) => <Chip key={o} on={concerns.includes(o)} onClick={() => tog(concerns, setConcerns, o)} color="#c0612f">{o}</Chip>)}</div>
        </div>
        <div>
          <label style={fbLabel}>Notes for the listing agent</label>
          <textarea value={comments} onChange={(e) => setComments(e.target.value)} rows={3} placeholder="What stood out, objections, next steps…" style={{ width: "100%", boxSizing: "border-box", border: "1px solid #e2e0d8", borderRadius: 8, padding: "10px 12px", fontFamily: "inherit", fontSize: 13, color: "#1d241f", resize: "vertical", outline: "none", lineHeight: 1.5 }} />
        </div>
        <div style={{ display: "flex", gap: 9 }}>
          <button onClick={() => onSave({ rating, interest, priceOpinion: price, liked, concerns, comments, wouldReturn: interest !== "Low" })} style={btnPrimary}><Icon name="check" size={15} color="#fff" /> Save feedback</button>
          <button onClick={onCancel} style={btnOutline}>Cancel</button>
        </div>
      </div>
    </div>
  );
}

// ============ feedback card (listing side view) ============
function FeedbackCard({ fb, S, listingSide }) {
  const [shared, setShared] = useState(fb.sharedWithSeller);
  const ic = S.interestColor[fb.interest] || { c: "#6b706a", b: "#f0efe9" };
  return (
    <div>
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 16 }}>
        <div style={{ display: "flex", gap: 3 }}>{[1, 2, 3, 4, 5].map((n) => <Icon key={n} name="star" size={20} color={n <= fb.rating ? "#e0a020" : "#dcdad1"} style={{ fill: n <= fb.rating ? "#e0a020" : "none" }} />)}</div>
        <span style={{ fontSize: 11.5, fontWeight: 600, color: ic.c, background: ic.b, borderRadius: 999, padding: "3px 10px" }}>{fb.interest} interest</span>
        <span style={{ fontSize: 11.5, fontWeight: 600, color: fb.priceOpinion === "Overpriced" ? "#b3261e" : "#6b706a", background: fb.priceOpinion === "Overpriced" ? "#fbe9e7" : "#f0efe9", borderRadius: 999, padding: "3px 10px" }}>{fb.priceOpinion}</span>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 14 }}>
        <div style={{ background: "#fff", borderRadius: 8, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", padding: 14 }}>
          <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".5px", color: "#1f8a5b", marginBottom: 9 }}>Liked</div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>{fb.liked.map((l) => <span key={l} style={{ fontSize: 12, color: "#1f8a5b", background: "#e8f4ee", borderRadius: 999, padding: "3px 10px" }}>{l}</span>)}</div>
        </div>
        <div style={{ background: "#fff", borderRadius: 8, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", padding: 14 }}>
          <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".5px", color: "#c0612f", marginBottom: 9 }}>Concerns</div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>{fb.concerns.map((l) => <span key={l} style={{ fontSize: 12, color: "#c0612f", background: "#faece3", borderRadius: 999, padding: "3px 10px" }}>{l}</span>)}</div>
        </div>
      </div>

      <div style={{ background: "#fff", borderRadius: 8, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", padding: "14px 16px", marginBottom: 14 }}>
        <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".5px", color: "#a8aca6", marginBottom: 7 }}>Agent's notes</div>
        <p style={{ margin: 0, fontSize: 13, color: "#2d332e", lineHeight: 1.6 }}>{fb.comments}</p>
      </div>

      {listingSide && (
        <div style={{ display: "flex", alignItems: "center", gap: 11, padding: "12px 14px", borderRadius: 8, background: shared ? "#e8f4ee" : "#fff", boxShadow: shared ? "inset 0 0 0 1px #cfe6da" : "inset 0 0 0 1px rgba(0,0,0,.07)" }}>
          <Icon name={shared ? "check-circle-2" : "share-2"} size={18} color={shared ? "#1f8a5b" : "#006747"} />
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 600, color: "#1d241f" }}>{shared ? "Shared with seller" : "Share this feedback with your seller"}</div>
            <div style={{ fontSize: 11.5, color: "#8a8e88" }}>{shared ? "Visible in the seller's update — you control what's shared." : "You decide what the seller sees."}</div>
          </div>
          <button onClick={() => setShared(!shared)} style={{ ...(shared ? btnOutline : btnPrimary), padding: "7px 13px", fontSize: 12.5 }}>{shared ? "Unshare" : "Share with seller"}</button>
        </div>
      )}
    </div>
  );
}

function Empty({ icon, title, body }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", padding: "48px 20px", textAlign: "center" }}>
      <span style={{ width: 52, height: 52, borderRadius: "50%", background: "#f0efe9", display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 14 }}><Icon name={icon} size={24} color="#a8aca6" /></span>
      <div style={{ fontSize: 15, fontWeight: 600, color: "#1d241f", marginBottom: 5 }}>{title}</div>
      <div style={{ fontSize: 13, color: "#8a8e88", maxWidth: 320, lineHeight: 1.5 }}>{body}</div>
    </div>
  );
}

const fbLabel = { display: "block", fontSize: 11.5, fontWeight: 600, color: "#6b706a", marginBottom: 8, textTransform: "uppercase", letterSpacing: ".5px" };

window.Showings = Showings;
