// app.jsx — root: routing between dashboard / public booking / confirmation + tweaks

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "industry": "generic"
}/*EDITMODE-END*/;

const INDUSTRY_OPTIONS = [
  { id: "generic", label: "Generic" },
  { id: "classes", label: "Classes" },
  { id: "hair",    label: "Hairdresser" },
  { id: "nails",   label: "Nail bar" },
  { id: "beauty",  label: "Beauty salon" },
  { id: "pool",    label: "Swimming pool" },
];

// ── Guest auth modal ─────────────────────────────────────────
function GuestAuthModal({ onSuccess, onClose }) {
  const [mode, setMode]       = React.useState("signin");
  const [email, setEmail]     = React.useState("");
  const [password, setPassword] = React.useState("");
  const [error, setError]     = React.useState("");
  const [busy, setBusy]       = React.useState(false);
  const [pending, setPending] = React.useState(false); // email confirmation pending

  const submit = async () => {
    if (!email.trim() || password.length < 6) {
      setError("Please enter a valid email and a password of at least 6 characters.");
      return;
    }
    setBusy(true); setError("");
    if (mode === "register") {
      const result = await registerGuest(email.trim(), password);
      if (result.error) { setError(result.error); setBusy(false); return; }
      if (!result.session) { setPending(true); setBusy(false); return; } // email confirmation required
      onSuccess(result.user);
    } else {
      const result = await loginGuest(email.trim(), password);
      if (result.error) { setError(result.error); setBusy(false); return; }
      onSuccess(result.user);
    }
    setBusy(false);
  };

  if (pending) return (
    <div className="guest-modal-overlay" onClick={onClose}>
      <div className="guest-modal" onClick={e => e.stopPropagation()}>
        <div style={{textAlign:"center", padding:"8px 0 4px"}}>
          <div style={{marginBottom:12, color:"var(--text-muted)"}}><I.mail size={36}/></div>
          <h2 style={{marginBottom:8}}>Check your email</h2>
          <p style={{color:"var(--text-muted)", fontSize:13, lineHeight:1.6, margin:0}}>
            We sent a confirmation link to <strong>{email}</strong>. Click it to activate your account, then come back and sign in.
          </p>
          <button className="btn primary" style={{marginTop:20, width:"100%"}} onClick={() => { setPending(false); setMode("signin"); }}>
            Back to sign in
          </button>
        </div>
      </div>
    </div>
  );

  return (
    <div className="guest-modal-overlay" onClick={onClose}>
      <div className="guest-modal" onClick={e => e.stopPropagation()}>
        <div className="guest-modal-tabs">
          <button className={mode === "signin" ? "active" : ""} onClick={() => { setMode("signin"); setError(""); }}>Sign in</button>
          <button className={mode === "register" ? "active" : ""} onClick={() => { setMode("register"); setError(""); }}>Create account</button>
        </div>
        <div className="bk-field">
          <label>Email</label>
          <input className="bk-input" type="email" placeholder="you@example.com" value={email}
            onChange={e => setEmail(e.target.value)} onKeyDown={e => e.key === "Enter" && submit()}/>
        </div>
        <div className="bk-field">
          <label>Password</label>
          <input className="bk-input" type="password" placeholder={mode === "register" ? "At least 6 characters" : "Your password"} value={password}
            onChange={e => setPassword(e.target.value)} onKeyDown={e => e.key === "Enter" && submit()}/>
        </div>
        {error && <div className="coupon-error" style={{marginBottom:10}}>{error}</div>}
        <button className="btn primary" style={{width:"100%", marginTop:4}} onClick={submit} disabled={busy}>
          {busy ? "…" : mode === "register" ? "Create account" : "Sign in"}
        </button>
        <button className="btn ghost" style={{width:"100%", marginTop:8}} onClick={onClose}>Cancel</button>
      </div>
    </div>
  );
}

// ── Guest bookings panel (slide-in) ───────────────────────────
function GuestBookingsPanel({ guestUser, onClose, onSignOut }) {
  const [bookings, setBookings] = React.useState(null);

  React.useEffect(() => {
    fetchGuestBookings(guestUser.id).then(setBookings);
  }, [guestUser.id]);

  const today = todayIso();
  const upcoming = (bookings || []).filter(b => b.date >= today && b.status !== "Cancelled");
  const past     = (bookings || []).filter(b => b.date < today  || b.status === "Cancelled");

  const reBook = (b) => {
    if (b.business?.booking_url) {
      window.location.href = getBookingUrl(b.business.booking_url);
    }
  };

  return (
    <div className="guest-panel-overlay" onClick={onClose}>
      <div className="guest-panel" onClick={e => e.stopPropagation()}>
        <div className="guest-panel-h">
          <div>
            <h2 style={{margin:0}}>My bookings</h2>
            <div style={{fontSize:12, color:"var(--text-muted)", marginTop:2}}>{guestUser.email}</div>
          </div>
          <div style={{display:"flex", gap:8, alignItems:"center"}}>
            <button className="btn ghost" style={{fontSize:12}} onClick={onSignOut}>Sign out</button>
            <button className="btn ghost" style={{padding:"6px 8px"}} onClick={onClose}><I.x size={14}/></button>
          </div>
        </div>
        <div className="guest-panel-body">
          {bookings === null ? (
            <div style={{textAlign:"center", padding:"40px 0"}}>
              <div className="loading-dots"><span/><span/><span/></div>
            </div>
          ) : bookings.length === 0 ? (
            <div style={{textAlign:"center", padding:"40px 0", color:"var(--text-muted)"}}>
              <div style={{marginBottom:12, color:"var(--text-muted)"}}><I.cal size={36}/></div>
              <p style={{margin:0}}>No bookings yet.</p>
            </div>
          ) : (
            <>
              {upcoming.length > 0 && (
                <>
                  <div className="guest-section-label">Upcoming</div>
                  {upcoming.map(b => <GuestBookingCard key={b.id} booking={b} onRebook={reBook}/>)}
                </>
              )}
              {past.length > 0 && (
                <>
                  <div className="guest-section-label" style={{marginTop: upcoming.length > 0 ? 20 : 0}}>Past</div>
                  {past.map(b => <GuestBookingCard key={b.id} booking={b} onRebook={reBook}/>)}
                </>
              )}
            </>
          )}
        </div>
      </div>
    </div>
  );
}

function GuestBookingCard({ booking, onRebook, onCancel, onReschedule }) {
  const accent    = booking.business?.accent || "#006e78";
  const brandName = booking.business?.brand_name || "Booking";
  const logoChar  = (booking.business?.logo_text || brandName.charAt(0) || "B").toUpperCase().slice(0, 2);
  const today     = todayIso();
  const isFuture  = booking.date >= today;
  const isActive  = booking.status !== "Cancelled";

  return (
    <div className="guest-booking-card">
      <div className="guest-booking-card-h">
        <div className="guest-booking-brand" style={{background: accent, color:"#fff"}}>{logoChar}</div>
        <div className="guest-booking-info">
          <div className="name">{booking.eventName}</div>
          <div className="meta">{brandName}</div>
        </div>
        <div className="guest-booking-datetime">
          <div className="date">{formatIsoDate(booking.date, { weekday:"short" })}</div>
          <div className="time">{booking.time}</div>
        </div>
      </div>
      <div style={{display:"flex", alignItems:"center", justifyContent:"space-between", marginTop:10, flexWrap:"wrap", gap:6}}>
        <span className={"pill " + booking.status.toLowerCase()}>{booking.status}</span>
        <div style={{display:"flex", gap:6}}>
          {isFuture && isActive && onReschedule && (
            <button className="btn ghost" style={{fontSize:12, padding:"5px 12px"}} onClick={() => onReschedule(booking)}>
              Reschedule
            </button>
          )}
          {isFuture && isActive && onCancel && (
            <button className="btn ghost" style={{fontSize:12, padding:"5px 12px", color:"var(--danger)"}} onClick={() => onCancel(booking)}>
              Cancel
            </button>
          )}
          {!isFuture && isActive && (
            <button className="btn ghost" style={{fontSize:12, padding:"5px 12px"}} onClick={() => onRebook(booking)}>
              Rebook →
            </button>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Guest reschedule modal ─────────────────────────────────────
function GuestRescheduleModal({ booking, onClose, onSaved }) {
  const [newDate, setNewDate] = React.useState(booking.date || "");
  const [newTime, setNewTime] = React.useState(booking.time || "");
  const [busy, setBusy]       = React.useState(false);
  const [done, setDone]       = React.useState(false);

  const handleSave = async () => {
    if (!newDate || !newTime) return;
    setBusy(true);
    await sb.from("bookings")
      .update({ date: newDate, time: newTime, status: "Rescheduled" })
      .eq("id", booking.id);
    setDone(true);
    setBusy(false);
    onSaved({ ...booking, date: newDate, time: newTime, status: "Rescheduled" });
  };

  if (done) return null;

  return (
    <div className="guest-modal-overlay" onClick={onClose}>
      <div className="guest-modal" onClick={e => e.stopPropagation()}>
        <h3 style={{margin:"0 0 16px"}}>Reschedule booking</h3>
        <div style={{fontSize:13, color:"var(--text-muted)", marginBottom:16}}>
          {booking.eventName} · currently {formatIsoDate(booking.date)} at {booking.time}
        </div>
        <div className="bk-field" style={{marginBottom:12}}>
          <label>New date</label>
          <input className="bk-input" type="date" value={newDate} min={todayIso()}
            onChange={e => setNewDate(e.target.value)}/>
        </div>
        <div className="bk-field" style={{marginBottom:20}}>
          <label>New time</label>
          <input className="bk-input" type="time" value={newTime}
            onChange={e => setNewTime(e.target.value)}/>
        </div>
        <div style={{display:"flex", gap:8}}>
          <button className="btn ghost" style={{flex:1}} onClick={onClose}>Cancel</button>
          <button className="btn primary" style={{flex:1}} onClick={handleSave} disabled={busy || !newDate || !newTime}>
            {busy ? "Saving…" : "Confirm reschedule"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Guest portal (standalone page when guest logs in directly) ─
function GuestPortal({ guestUser }) {
  const [bookings,       setBookings]       = React.useState(null);
  const [rescheduling,   setRescheduling]   = React.useState(null); // booking object
  const [cancelConfirm,  setCancelConfirm]  = React.useState(null); // booking object
  const [cancelling,     setCancelling]     = React.useState(false);

  React.useEffect(() => {
    fetchGuestBookings(guestUser.id).then(setBookings);
  }, [guestUser.id]);

  const today    = todayIso();
  const upcoming = (bookings || []).filter(b => b.date >= today && b.status !== "Cancelled");
  const past     = (bookings || []).filter(b => b.date < today  || b.status === "Cancelled");

  const reBook = (b) => {
    if (b.business?.booking_url) {
      window.location.href = getBookingUrl(b.business.booking_url);
    }
  };

  const handleRescheduled = (updated) => {
    setBookings(bs => bs.map(b => b.id === updated.id ? { ...b, ...updated } : b));
    setRescheduling(null);
  };

  const handleCancelConfirm = async () => {
    if (!cancelConfirm) return;
    setCancelling(true);
    await sb.from("bookings").update({ status: "Cancelled" }).eq("id", cancelConfirm.id);
    setBookings(bs => bs.map(b => b.id === cancelConfirm.id ? { ...b, status: "Cancelled" } : b));
    setCancelling(false);
    setCancelConfirm(null);
  };

  return (
    <div className="guest-portal">
      <div className="public-bar" style={{position:"sticky", top:0, zIndex:10, background:"var(--bg)"}}>
        <div className="brand">
          <img src="icon/nexus-bookings-icon.png" alt="" style={{width:24, height:24, borderRadius:6, objectFit:"contain"}}/>
          <span>Nexus Booking</span>
        </div>
        <div style={{display:"flex", alignItems:"center", gap:10}}>
          <span style={{fontSize:12, color:"var(--text-muted)"}}>{guestUser.email}</span>
          <button className="btn ghost" style={{fontSize:12}} onClick={() => sb.auth.signOut()}>Sign out</button>
        </div>
      </div>
      <div className="guest-portal-body">
        <h1 style={{marginBottom:4}}>My bookings</h1>
        <p style={{color:"var(--text-muted)", marginBottom:28, marginTop:0}}>Your upcoming and past appointments.</p>

        {bookings === null ? (
          <div style={{textAlign:"center", padding:"60px 0"}}>
            <div className="loading-dots"><span/><span/><span/></div>
          </div>
        ) : bookings.length === 0 ? (
          <div style={{textAlign:"center", padding:"60px 0", color:"var(--text-muted)"}}>
            <div style={{marginBottom:16, color:"var(--text-muted)"}}><I.cal size={40}/></div>
            <h3 style={{margin:"0 0 8px"}}>No bookings yet</h3>
            <p style={{margin:0, fontSize:14}}>Your confirmed bookings will appear here.</p>
          </div>
        ) : (
          <>
            {upcoming.length > 0 && (
              <>
                <div className="guest-section-label">Upcoming</div>
                {upcoming.map(b => (
                  <GuestBookingCard key={b.id} booking={b} onRebook={reBook}
                    onReschedule={() => setRescheduling(b)}
                    onCancel={() => setCancelConfirm(b)}/>
                ))}
              </>
            )}
            {past.length > 0 && (
              <>
                <div className="guest-section-label" style={{marginTop: upcoming.length > 0 ? 28 : 0}}>Past</div>
                {past.map(b => <GuestBookingCard key={b.id} booking={b} onRebook={reBook}/>)}
              </>
            )}
          </>
        )}
      </div>

      {rescheduling && (
        <GuestRescheduleModal
          booking={rescheduling}
          onClose={() => setRescheduling(null)}
          onSaved={handleRescheduled}/>
      )}

      {cancelConfirm && (
        <div className="guest-modal-overlay" onClick={() => setCancelConfirm(null)}>
          <div className="guest-modal" onClick={e => e.stopPropagation()}>
            <h3 style={{margin:"0 0 12px"}}>Cancel booking?</h3>
            <p style={{fontSize:13, color:"var(--text-muted)", margin:"0 0 20px", lineHeight:1.6}}>
              Are you sure you want to cancel your <strong>{cancelConfirm.eventName}</strong> appointment on <strong>{formatIsoDate(cancelConfirm.date)}</strong>? This cannot be undone.
            </p>
            <div style={{display:"flex", gap:8}}>
              <button className="btn ghost" style={{flex:1}} onClick={() => setCancelConfirm(null)}>Keep it</button>
              <button className="btn primary" style={{flex:1, background:"var(--danger)"}} onClick={handleCancelConfirm} disabled={cancelling}>
                {cancelling ? "Cancelling…" : "Yes, cancel"}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ── Star picker component ─────────────────────────────────────
function StarPicker({ value, onChange, size = 36 }) {
  const [hovered, setHovered] = React.useState(0);
  return (
    <div className="review-stars-lg" onMouseLeave={() => setHovered(0)}>
      {[1, 2, 3, 4, 5].map(n => (
        <button
          key={n}
          className={"star-btn" + (n <= (hovered || value) ? " is-filled" : "")}
          onMouseEnter={() => setHovered(n)}
          onClick={() => onChange(n)}
          type="button"
          aria-label={`${n} star${n !== 1 ? "s" : ""}`}
        >
          <I.star size={size}/>
        </button>
      ))}
    </div>
  );
}

// ── Review page (?review=TOKEN) ───────────────────────────────
function ReviewPage({ token }) {
  const [state, setState]     = React.useState("loading"); // loading | ready | already | error | done
  const [bookingData, setBookingData] = React.useState(null);
  const [rating, setRating]   = React.useState(0);
  const [comment, setComment] = React.useState("");
  const [busy, setBusy]       = React.useState(false);
  const [ratingErr, setRatingErr] = React.useState(false);

  React.useEffect(() => {
    fetchBookingByToken(token).then(r => {
      if (!r) { setState("error"); return; }
      // Check if a review already exists for this booking
      sb.from("reviews")
        .select("id")
        .eq("booking_id", r.booking.id)
        .maybeSingle()
        .then(({ data: existing }) => {
          setBookingData(r);
          setState(existing ? "already" : "ready");
        });
    });
  }, [token]);

  const handleSubmit = async () => {
    if (rating === 0) { setRatingErr(true); return; }
    setRatingErr(false);
    setBusy(true);
    const { booking } = bookingData;
    const result = await submitReview({
      bookingId:  booking.id,
      manageToken: token,
      rating,
      comment,
      guestName:  booking.guestName,
      eventName:  booking.eventName,
    });
    if (result.error) { setBusy(false); return; }
    setState("done");
    setBusy(false);
  };

  const profile = bookingData?.publicData?.profile;

  const Bar = () => (
    <div className="public-bar">
      <div className="brand">
        <div className="sb-mark" style={{width:24,height:24,fontSize:12}}>
          {profile?.logoUrl ? <img src={profile.logoUrl} alt=""/> : getLogoText(profile || {})}
        </div>
        <span>{profile?.brandName || "Nexus Booking"}</span>
      </div>
    </div>
  );

  if (state === "loading") return <LoadingShell/>;

  if (state === "error") return (
    <div className="review-page" style={profile ? getBrandStyle(profile) : {}}>
      <div className="public"><Bar/>
        <div className="public-body" style={{display:"flex",alignItems:"center"}}>
          <div className="review-card">
            <h2>Link not found</h2>
            <p className="sub">This review link may have expired.</p>
          </div>
        </div>
      </div>
    </div>
  );

  if (state === "already") return (
    <div className="review-page" style={getBrandStyle(profile)}>
      <div className="public"><Bar/>
        <div className="public-body" style={{display:"flex",alignItems:"center"}}>
          <div className="review-card">
            <div className="review-submitted">
              <div className="emoji"><I.shield size={36}/></div>
              <h3>Already reviewed</h3>
              <p>You've already left a review for this booking. Thanks!</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  );

  if (state === "done") return (
    <div className="review-page" style={getBrandStyle(profile)}>
      <div className="public"><Bar/>
        <div className="public-body" style={{display:"flex",alignItems:"center"}}>
          <div className="review-card">
            <div className="review-submitted">
              <div className="emoji"><I.hand size={36}/></div>
              <h3>Thank you!</h3>
              <p>Your review has been submitted. It means a lot to us.</p>
              {profile?.bookingUrl && (
                <button className="btn primary" style={{marginTop:20}}
                  onClick={() => window.location.href = getBookingUrl(profile.bookingUrl)}>
                  Book again →
                </button>
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  );

  const { booking } = bookingData;
  return (
    <div className="review-page" style={getBrandStyle(profile)}>
      <div className="public"><Bar/>
        <div className="public-body" style={{display:"flex",alignItems:"center"}}>
          <div className="review-card">
            <h2>How was your session?</h2>
            <p className="sub">
              {booking.eventName} · {formatIsoDate(booking.date, { weekday:"long", year:true })}
            </p>
            <StarPicker value={rating} onChange={v => { setRating(v); setRatingErr(false); }}/>
            {ratingErr && <div style={{color:"var(--danger)",fontSize:13,marginBottom:12}}>Please choose a star rating.</div>}
            <div className="bk-field" style={{textAlign:"left"}}>
              <label>Comment <span style={{color:"var(--text-muted)",fontWeight:400}}>(optional)</span></label>
              <textarea
                className="bk-input"
                rows={3}
                placeholder="Tell us what you thought…"
                value={comment}
                onChange={e => setComment(e.target.value)}
                style={{resize:"vertical"}}
              />
            </div>
            <button className="btn primary" style={{width:"100%",marginTop:4}} onClick={handleSubmit} disabled={busy}>
              {busy ? "Submitting…" : "Submit review"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Public booking page (no auth needed) ─────────────────────
function PublicBookingApp({ slug }) {
  const [state, setState]     = React.useState("loading"); // loading | ready | notfound
  const [pubData, setPubData] = React.useState(null);
  const [booking, setBooking] = React.useState(null);
  const [confirmed, setConfirmed] = React.useState(false);

  // Guest auth state
  const [guestUser, setGuestUser]         = React.useState(null);
  const [showGuestAuth, setShowGuestAuth] = React.useState(false);
  const [showGuestPanel, setShowGuestPanel] = React.useState(false);

  React.useEffect(() => {
    fetchPublicData(slug).then(d => {
      if (!d) setState("notfound");
      else { setPubData(d); setState("ready"); }
    });
    // Check for existing guest session
    sb.auth.getSession().then(({ data: { session } }) => {
      if (session?.user) {
        sb.from("profiles").select("role").eq("id", session.user.id).single().then(({ data: prof }) => {
          if (prof?.role === "guest") setGuestUser(session.user);
        });
      }
    });
  }, [slug]);

  if (state === "loading") return <LoadingShell/>;
  if (state === "notfound") return (
    <div className="login-shell">
      <div className="login-card" style={{textAlign:"center"}}>
        <img src="icon/nexus-bookings-icon.png" alt="" style={{width:40, height:40, borderRadius:10, objectFit:"contain", margin:"0 auto 16px", display:"block"}}/>
        <h2>Booking page not found</h2>
        <p style={{color:"var(--text-muted)", marginTop:8}}>This link may be incorrect or the business is no longer active.</p>
      </div>
    </div>
  );

  const handleConfirmed = (b) => {
    const bookId      = uid("book");
    const manageToken = (typeof crypto !== "undefined" && crypto.randomUUID) ? crypto.randomUUID() : uid("tok");
    const events = pubData.events || [];
    const event  = events.find(e => e.id === b.eventId) || events[0];
    const next   = {
      id: bookId, date: b.date, time: b.time,
      eventId: event?.id, eventName: event?.name,
      guestName: b.name, guestEmail: b.email,
      guestPhone: b.phone || "", notes: b.notes || "",
      answers: b.answers || {}, location: event?.location || "",
      paymentStatus: b.paymentStatus || (Number(event?.price||0) > 0 ? "Paid" : "Not required"),
      paymentProvider: b.paymentProvider || "",
      paymentAmount: b.paymentAmount ?? Number(event?.price||0),
      status: "Confirmed", source: "Public page",
      manageToken,
      couponCode:      b.couponCode      || "",
      discountApplied: b.discountApplied || 0,
      voucherCode:          b.voucherCode          || "",
      voucherAmount:        b.voucherAmount        || 0,
      packagePurchaseId:    b.packagePurchaseId    || "",
      memberSubscriptionId: b.memberSubscriptionId || "",
    };
    setPubData(d => ({ ...d, bookings: [next, ...d.bookings] }));
    sb.from("bookings").insert({
      id: bookId, user_id: pubData.userId,
      event_id: next.eventId, event_name: next.eventName,
      date: next.date, time: next.time,
      guest_name: next.guestName, guest_email: next.guestEmail, guest_phone: next.guestPhone,
      notes: next.notes, answers: next.answers, location: next.location,
      status: next.status, payment_status: next.paymentStatus,
      payment_provider: next.paymentProvider, payment_amount: next.paymentAmount, source: next.source,
      manage_token: manageToken,
      coupon_code:           next.couponCode  || null,
      discount_applied:      next.discountApplied || 0,
      voucher_code:          next.voucherCode || null,
      voucher_amount:        next.voucherAmount || 0,
      package_purchase_id:   next.packagePurchaseId || null,
      member_subscription_id: next.memberSubscriptionId || null,
      customer_id: guestUser?.id || null,
      staff_id:   b.staffId   || null,
      staff_name: b.staffName || null,
    });
    sendBookingEmail("guest_confirmation", next, pubData.profile);
    sendBookingEmail("owner_notification", next, pubData.profile);
    sendSmsNotification("confirmation", next, pubData.profile);
    if (b.couponId) incrementCouponUsage(b.couponId);
    // Redeem gift voucher
    if (b.voucherId) redeemGiftVoucher(b.voucherId, bookId);
    // Redeem package session
    if (b.packagePurchaseId) redeemPackageSession(b.packagePurchaseId, bookId);
    // Redeem membership session
    if (b.memberSubscriptionId) redeemMembershipSession(b.memberSubscriptionId, bookId);
    // Generate and email invoice if payment was made
    if (next.paymentAmount > 0) generateInvoice(next, pubData.profile);
    setBooking(next);
    setConfirmed(true);
  };

  // Guest bar button shown in BookingPage's public-bar
  const guestBarBtn = (
    <button
      className="btn ghost"
      style={{fontSize:12}}
      onClick={() => guestUser ? setShowGuestPanel(true) : setShowGuestAuth(true)}
    >
      {guestUser ? "My bookings" : "Sign in"}
    </button>
  );

  if (confirmed) return (
    <div style={getBrandStyle(pubData.profile)}>
      {showGuestAuth && <GuestAuthModal onSuccess={u => { setGuestUser(u); setShowGuestAuth(false); }} onClose={() => setShowGuestAuth(false)}/>}
      {showGuestPanel && guestUser && <GuestBookingsPanel guestUser={guestUser} onClose={() => setShowGuestPanel(false)} onSignOut={() => { sb.auth.signOut(); setGuestUser(null); setShowGuestPanel(false); }}/>}
      <Confirmation booking={booking} profile={pubData.profile}
        onBack={() => window.location.reload()}
        onAnother={() => { setConfirmed(false); setBooking(null); }}
        rightContent={guestBarBtn}/>
    </div>
  );

  return (
    <div style={getBrandStyle(pubData.profile)}>
      {showGuestAuth && <GuestAuthModal onSuccess={u => { setGuestUser(u); setShowGuestAuth(false); }} onClose={() => setShowGuestAuth(false)}/>}
      {showGuestPanel && guestUser && <GuestBookingsPanel guestUser={guestUser} onClose={() => setShowGuestPanel(false)} onSignOut={() => { sb.auth.signOut(); setGuestUser(null); setShowGuestPanel(false); }}/>}
      <BookingPage
        data={pubData}
        onBack={() => window.location.reload()}
        onConfirmed={handleConfirmed}
        rightContent={guestBarBtn}
        initialForm={{ email: guestUser?.email || "" }}
      />
    </div>
  );
}

// ── Loading screen ────────────────────────────────────────────
function LoadingShell() {
  return (
    <div className="loading-shell">
      <div className="loading-dots">
        <span/><span/><span/>
      </div>
    </div>
  );
}

// ── Main admin app (requires auth) ────────────────────────────
function App() {
  // ALL hooks must be at the top — no hooks after conditional returns
  const [t, setTweak]               = useTweaks(TWEAK_DEFAULTS);
  const { data, authUser, actions } = useAppData();
  const [view, setView]             = React.useState("dashboard");
  const [active, setActive]         = React.useState("overview");
  const [booking, setBooking]       = React.useState(null);
  const [copied, setCopied]         = React.useState(false);
  const [impersonated, setImpersonated] = React.useState(null); // { data } when viewing another account
  // On book.nexusbookings.app the slug comes from the pathname (e.g. /luminary → "luminary")
  // On app.nexusbookings.app (or localhost) it falls back to the legacy ?book= query param
  const isBookDomain = window.location.hostname === "book.nexusbookings.app";
  const bookSlug = React.useMemo(() => {
    if (isBookDomain) {
      const path = window.location.pathname.replace(/^\//, "").split("?")[0];
      return path || null;
    }
    return new URLSearchParams(window.location.search).get("book");
  }, []);
  const manageToken = React.useMemo(() => new URLSearchParams(window.location.search).get("manage"), []);
  const reviewToken = React.useMemo(() => new URLSearchParams(window.location.search).get("review"), []);

  // detect ?manage=token → customer manage their booking (no auth needed)
  if (manageToken) return <ManageBookingPage token={manageToken}/>;

  // detect ?review=token → review page (no auth needed)
  if (reviewToken) return <ReviewPage token={reviewToken}/>;

  // On book.nexusbookings.app with no slug → redirect to marketing site
  if (isBookDomain && !bookSlug) {
    window.location.replace("https://nexusbookings.app");
    return <LoadingShell/>;
  }

  // detect slug → show public booking page (no auth needed)
  if (bookSlug) return <PublicBookingApp slug={bookSlug}/>;

  // still checking auth state
  if (authUser === undefined) return <LoadingShell/>;

  // not logged in
  if (!authUser) return <LoginPage/>;

  // authenticated but data still loading from Supabase
  if (!data) return <LoadingShell/>;

  // guest account — show guest portal instead of owner dashboard
  if (data.profile.role === "guest") return <GuestPortal guestUser={authUser}/>;

  // account suspended by super admin
  if (data.profile.suspended) return (
    <div className="suspension-screen">
      <div className="suspension-card">
        <div className="sb-mark" style={{margin:"0 auto 16px",background:"var(--danger)"}}>!</div>
        <h2>Account suspended</h2>
        <p>This account has been suspended. Please contact <a href="mailto:hello@nexusbookings.app">hello@nexusbookings.app</a> for more information.</p>
        <button className="btn ghost" style={{marginTop:12}} onClick={() => sb.auth.signOut()}>Sign out</button>
      </div>
    </div>
  );

  const presetByBusiness = { classes: "classes", pool_hire: "pool", beauty: "beauty", nails: "nails" };
  const industryKey = presetByBusiness[data.profile.businessType] || t.industry;
  const industry    = PRESETS[industryKey] || PRESETS.generic;

  const onCopy = () => {
    const url = getBookingUrl(data.profile.bookingUrl);
    navigator.clipboard?.writeText(url).catch(()=>{});
    setCopied(true);
    setTimeout(() => setCopied(false), 1800);
  };

  const signOut = () => sb.auth.signOut();

  const onViewAccount = async (userId) => {
    const accountData = await fetchUserData(userId);
    if (accountData) { setImpersonated(accountData); setActive("overview"); }
  };

  if (impersonated) {
    const impIndustry = PRESETS[impersonated.profile?.businessType] || PRESETS.generic;
    return (
      <div className="workspace" style={getBrandStyle(impersonated.profile)}>
        <div className="impersonate-banner">
          <span style={{display:"inline-flex",alignItems:"center",gap:6}}><I.show size={14}/> Viewing <strong>{impersonated.profile.brandName || impersonated.profile.email || "account"}</strong> as super admin</span>
          <button onClick={() => { setImpersonated(null); setActive("platform"); }}>← Exit to Platform</button>
        </div>
        <Sidebar
          active={active} onNav={setActive}
          onOpenBooking={() => {}} onOpenAdmin={() => {}}
          profile={impersonated.profile} copied={false} onCopy={() => {}}
          onSignOut={() => { setImpersonated(null); setActive("platform"); }}
        />
        <main className="main" style={{paddingTop:40}}>
          <Dashboard active={active} industry={impIndustry} data={impersonated} actions={{
            addBooking:()=>{}, updateBookingStatus:()=>{}, rescheduleBooking:()=>{},
            saveEvent:()=>{}, toggleEvent:()=>{}, deleteEvent:()=>{},
            saveAvailability:()=>{}, addBlockedTime:()=>{}, removeBlockedTime:()=>{},
            connectIntegration:()=>{}, disconnectIntegration:()=>{},
            updateProfile:()=>{}, updateNotifications:()=>{},
          }} onOpenBooking={() => {}} onViewAccount={() => {}}/>
        </main>
      </div>
    );
  }

  if (view === "booking") {
    return (
      <div style={getBrandStyle(data.profile)}>
        <BookingPage
          data={data}
          onBack={() => setView("dashboard")}
          onConfirmed={(b) => { setBooking(actions.addBooking(b)); setView("confirmed"); }}
        />
        <TweaksUI t={t} setTweak={setTweak}/>
      </div>
    );
  }
  if (view === "confirmed") {
    return (
      <div style={getBrandStyle(data.profile)}>
        <Confirmation booking={booking} profile={data.profile}
          onBack={() => setView("dashboard")}
          onAnother={() => setView("booking")}/>
        <TweaksUI t={t} setTweak={setTweak}/>
      </div>
    );
  }
  if (view === "admin") {
    return <AdminShell data={data} actions={actions} onBack={() => setView("dashboard")}/>;
  }

  return (
    <div className="workspace" style={getBrandStyle(data.profile)}>
      <Sidebar
        active={active} onNav={setActive}
        onOpenBooking={() => setView("booking")}
        onOpenAdmin={() => setView("admin")}
        profile={data.profile} copied={copied} onCopy={onCopy}
        onSignOut={signOut}
      />
      <main className="main">
        <Dashboard
          active={active} industry={industry} data={data} actions={actions}
          onOpenBooking={() => setView("booking")}
          onViewAccount={onViewAccount}
          onSignOut={signOut}
          onNav={setActive}
          copied={copied} onCopy={onCopy}
        />
        <button onClick={() => setView("booking")} className="floating-preview"
          style={{ position:"fixed", bottom:20, zIndex:5, background:"var(--accent)", color:"var(--secondary)",
            border:0, borderRadius:10, padding:"10px 14px", fontSize:12.5, fontWeight:600,
            display:"inline-flex", alignItems:"center", gap:8, boxShadow:"0 4px 14px rgba(0,0,0,.15)" }}
          title="Preview the public booking page">
          <I.arrow size={14}/> View booking page
        </button>
      </main>
      {copied && <div className="toast"><I.check size={14}/> Booking link copied to clipboard</div>}
      <TweaksUI t={t} setTweak={setTweak}/>
    </div>
  );
}


function TweaksUI({ t, setTweak }) {
  return (
    <TweaksPanel>
      <TweakSection label="Industry preset"/>
      <TweakSelect
        label="Vertical"
        value={t.industry}
        options={INDUSTRY_OPTIONS.map(o => ({ value: o.id, label: o.label }))}
        onChange={(v) => setTweak('industry', v)}
      />
      <div style={{fontSize:11, color:"rgba(41,38,27,.55)", lineHeight:1.4, marginTop:2}}>
        Swaps services, demo bookings, and the public page's headline service.
      </div>
    </TweaksPanel>
  );
}

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