// Klant-dashboard "Mijn account" — profiel + wachtwoord + eigen bestellingen.

// Tijdlijn van status-events voor één order. Wordt zowel in /#account
// (klant ziet eigen geschiedenis) als /#admin (audit-trail) gebruikt.
const OrderHistory = ({ orderId, refreshKey }) => {
  const { useState, useEffect, useContext } = React;
  const langCtx = useContext(window.LangContext || React.createContext({ lang:"nl", t: (nl)=>nl }));
  const t = langCtx.t || ((nl) => nl);
  const [events, setEvents] = useState(null);
  useEffect(() => {
    let cancelled = false;
    if (!orderId || !window.zsb || !window.zsb.isConfigured) {
      setEvents([]);
      return () => { cancelled = true; };
    }
    setEvents(null);
    window.zsb.getOrderEvents(orderId).then(({ data }) => {
      if (cancelled) return;
      setEvents(data || []);
    });
    return () => { cancelled = true; };
  }, [orderId, refreshKey]);

  if (events === null) {
    return <div style={{fontSize:12, color:"var(--ink-mute)"}}>{t("Geschiedenis laden...","Loading history...")}</div>;
  }
  if (events.length === 0) {
    return <div style={{fontSize:12, color:"var(--ink-mute)"}}>{t("Nog geen statuswijzigingen geregistreerd.","No status changes recorded yet.")}</div>;
  }
  const label = (s) => (window.zsb && window.zsb.statusLabel && window.zsb.statusLabel(s, langCtx.lang)) || s;
  const noteText = (note) => {
    if (!note) return "";
    if (note === "order_created_by_customer" || note === "Aangemaakt door klant") return t("Aangemaakt door klant","Created by customer");
    if (note === "mollie_paid") return t("Betaling bevestigd door Mollie","Payment confirmed by Mollie");
    if (note === "mollie_pending_payment") return t("Betaling wordt gecontroleerd door Mollie","Payment is being verified by Mollie");
    if (note === "mollie_canceled") return t("Betaling geannuleerd bij Mollie","Payment canceled at Mollie");
    if (note === "mollie_expired") return t("Betaling verlopen bij Mollie","Payment expired at Mollie");
    if (note === "mollie_failed") return t("Betaling mislukt bij Mollie","Payment failed at Mollie");
    if (note.indexOf("Mollie webhook") === 0) return note.replace("Mollie webhook", t("Mollie-webhook","Mollie webhook"));
    return note;
  };
  return (
    <ol style={{listStyle:"none", padding:0, margin:0, display:"flex", flexDirection:"column", gap:8}}>
      {events.map(ev => (
        <li key={ev.id} style={{display:"grid", gridTemplateColumns:"10px 1fr auto", gap:10, alignItems:"flex-start", fontSize:12.5}}>
          <span style={{width:8, height:8, borderRadius:50, background:"var(--accent)", marginTop:5}}/>
          <div>
            <div style={{fontWeight:600}}>{label(ev.status)}</div>
            {ev.note && <div style={{color:"var(--ink-dim)", marginTop:2}}>{noteText(ev.note)}</div>}
          </div>
          <div className="mono" style={{fontSize:10.5, color:"var(--ink-mute)", letterSpacing:".05em", whiteSpace:"nowrap"}}>
            {new Date(ev.created_at).toLocaleString("nl-NL", { dateStyle:"short", timeStyle:"short" })}
          </div>
        </li>
      ))}
    </ol>
  );
};

const StatusBadge = ({ status }) => {
  const lang = (typeof window !== "undefined" && localStorage.getItem("zyro-lang")) || "nl";
  const label = (window.zsb && window.zsb.statusLabel)
    ? window.zsb.statusLabel(status, lang)
    : ((window.zsb && window.zsb.statusLabels[status]) || status || "—");
  const tone = (window.zsb && window.zsb.statusTone[status]) || "neutral";
  const palette = {
    neutral: { bg:"#eef0f3", fg:"#3b4658", bd:"#dfe3ea" },
    ok:      { bg:"#e7f4ec", fg:"#1f6b3a", bd:"#bfe0cb" },
    done:    { bg:"#e7eefc", fg:"#194a9a", bd:"#c5d4ee" },
    bad:     { bg:"#fbe9e9", fg:"#9a2222", bd:"#efc5c5" },
  }[tone];
  return (
    <span style={{
      display:"inline-flex", alignItems:"center", gap:6,
      padding:"4px 10px", borderRadius:999,
      background:palette.bg, color:palette.fg, border:`1px solid ${palette.bd}`,
      fontSize:11.5, fontWeight:600, fontFamily:"var(--f-mono)", letterSpacing:".04em", textTransform:"uppercase",
    }}>{label}</span>
  );
};

// ── Reviews (customer side) ───────────────────────────────────────────────
// Interactive 1–5 star picker (no hardcoded counts/names anywhere).
const ReviewStarsInput = ({ value, onChange }) => (
  <div style={{display:"inline-flex", gap:4}}>
    {[1,2,3,4,5].map(n => (
      <button key={n} type="button" onClick={()=>onChange(n)} aria-label={n + " sterren"}
        style={{background:"none", border:0, padding:2, cursor:"pointer", lineHeight:0, color:"var(--accent)"}}>
        <Icon name="star" size={26} fill={n <= value ? "var(--accent)" : "transparent"}/>
      </button>
    ))}
  </div>
);

// Read-only star row.
const ReviewStars = ({ value, size = 14 }) => (
  <span style={{display:"inline-flex", gap:2, color:"var(--accent)"}}>
    {[1,2,3,4,5].map(n => <Icon key={n} name="star" size={size} fill={n <= value ? "var(--accent)" : "transparent"}/>)}
  </span>
);

// Inline review form for ONE (order, product). After submit it can't be edited.
const ReviewForm = ({ orderId, productSlug, productName, onSubmitted }) => {
  const { useState, useContext } = React;
  const langCtx = useContext(window.LangContext || React.createContext({ lang:"nl", t:(nl)=>nl }));
  const t = langCtx.t || ((nl)=>nl);
  const [rating, setRating] = useState(0);
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState(null);
  const [done, setDone] = useState(false);

  if (done) {
    return (
      <div style={{padding:"12px 14px", borderRadius:8, background:"#e7f4ec", border:"1px solid #bfe0cb", color:"#1f6b3a", fontSize:13.5, marginTop:8}}>
        {t("Bedankt voor je review.","Thanks for your review.")}
      </div>
    );
  }

  const submit = async () => {
    setErr(null);
    if (!(rating >= 1 && rating <= 5)) { setErr(t("Kies 1 tot 5 sterren.","Pick 1 to 5 stars.")); return; }
    setBusy(true);
    const r = await window.zsb.submitReview({ order_id: orderId, product_slug: productSlug, rating, title, body });
    setBusy(false);
    if (r.error) { setErr(r.error); return; }
    if (r.data && r.data.status === "duplicate") { setErr(t("Je hebt dit product al gereviewd.","You've already reviewed this product.")); return; }
    setDone(true);
    onSubmitted && onSubmitted();
  };

  return (
    <div style={{padding:14, borderRadius:8, background:"var(--bg)", border:"1px solid var(--line)", marginTop:8}}>
      <div style={{fontWeight:600, fontSize:13.5, marginBottom:8}}>{t("Review schrijven voor","Write a review for")} {productName || productSlug}</div>
      <div style={{marginBottom:10}}><ReviewStarsInput value={rating} onChange={setRating}/></div>
      <input className="input" value={title} onChange={e=>setTitle(e.target.value)} maxLength={120}
        placeholder={t("Titel (optioneel)","Title (optional)")} style={{marginBottom:8}}/>
      <textarea className="textarea" rows={3} value={body} onChange={e=>setBody(e.target.value)} maxLength={4000}
        placeholder={t("Vertel kort over je ervaring (optioneel)","Tell us briefly about your experience (optional)")} style={{marginBottom:8}}/>
      <div style={{fontSize:12, color:"var(--ink-dim)", marginBottom:10}}>
        {t("Controleer je review goed. Na versturen kun je deze niet meer aanpassen.","Check your review carefully. You can't edit it after submitting.")}
      </div>
      {err && <div style={{color:"#ef4444", fontSize:12.5, marginBottom:8}}>{err}</div>}
      <button className="btn btn-primary btn-sm" onClick={submit} disabled={busy}>
        {busy ? t("Versturen…","Submitting…") : t("Review versturen","Submit review")}
      </button>
    </div>
  );
};

// Per-order review block — only for afgeronde orders. Lists each line item with
// either its existing review status, or a toggle to write a review.
const OrderReviewBlock = ({ order, reviews, defaultOpen, onReviewed }) => {
  const { useState, useEffect, useRef, useContext } = React;
  const langCtx = useContext(window.LangContext || React.createContext({ lang:"nl", t:(nl)=>nl }));
  const t = langCtx.t || ((nl)=>nl);
  const lang = langCtx.lang || "nl";
  const LP = window.LP || ((o,f)=>o && o[f]);
  const [openSlug, setOpenSlug] = useState(null);
  const blockRef = useRef(null);
  const items = Array.isArray(order.products) ? order.products : [];
  const byKey = {};
  (reviews || []).forEach(rv => { byKey[rv.order_id + "|" + rv.product_slug] = rv; });
  const firstUnreviewed = items.find(it => !byKey[order.id + "|" + it.id]);

  useEffect(() => {
    if (defaultOpen) {
      if (firstUnreviewed) setOpenSlug(firstUnreviewed.id);
      try { blockRef.current && blockRef.current.scrollIntoView({ behavior:"smooth", block:"center" }); } catch(_){}
    }
    // eslint-disable-next-line
  }, [defaultOpen]);

  // NOTE: the moderation status (pending/approved/rejected) is intentionally NOT
  // shown to the customer. get_my_reviews() still returns it, but the customer
  // view stays neutral — only admin (owner_list_reviews) surfaces status.
  const locale = langCtx.lang === "en" ? "en-GB" : "nl-NL";

  if (items.length === 0) return null;
  return (
    <div ref={blockRef} style={{marginTop:14, paddingTop:14, borderTop:"1px dashed var(--line)"}}>
      <div className="mono" style={{fontSize:10.5, color:"var(--ink-mute)", letterSpacing:".1em", textTransform:"uppercase", marginBottom:10}}>{t("Reviews","Reviews")}</div>
      {items.map((it, i) => {
        const existing = byKey[order.id + "|" + it.id];
        const name = (ALL_ITEMS[it.id] ? (LP(ALL_ITEMS[it.id],"name",lang) || ALL_ITEMS[it.id].name) : it.name) || it.id;

        // Already reviewed → neutral "Jouw review" card. NO moderation status,
        // no "in afwachting"/"goedgekeurd"/"afgewezen". The button is gone.
        if (existing) {
          return (
            <div key={it.id || i} style={{marginBottom:10, padding:14, borderRadius:8, background:"var(--bg)", border:"1px solid var(--line)"}}>
              <div style={{display:"flex", justifyContent:"space-between", alignItems:"center", gap:10, flexWrap:"wrap", marginBottom:6}}>
                <span style={{fontWeight:600, fontSize:13.5}}>{t("Jouw review","Your review")}{name ? " — " + name : ""}</span>
                {existing.created_at && <span style={{fontSize:11, color:"var(--ink-mute)"}}>{new Date(existing.created_at).toLocaleDateString(locale, { dateStyle:"medium" })}</span>}
              </div>
              <div style={{marginBottom:(existing.title || existing.body) ? 6 : 0}}><ReviewStars value={existing.rating}/></div>
              {existing.title && <div style={{fontWeight:600, fontSize:13.5, marginBottom:4}}>{existing.title}</div>}
              {existing.body && <div style={{fontSize:13, color:"var(--ink-dim)", whiteSpace:"pre-wrap", marginBottom:6}}>{existing.body}</div>}
              <div style={{fontSize:12, color:"var(--ink-mute)", marginTop:6}}>{t("Bedankt voor je review.","Thanks for your review.")}</div>
            </div>
          );
        }

        // Not yet reviewed → product + "Review plaatsen" button (+ inline form).
        return (
          <div key={it.id || i} style={{marginBottom:10}}>
            <div style={{display:"flex", justifyContent:"space-between", alignItems:"center", gap:10, flexWrap:"wrap"}}>
              <span style={{fontSize:13.5}}>{name}</span>
              <button className="btn btn-ghost btn-sm" onClick={()=>setOpenSlug(openSlug === it.id ? null : it.id)}>
                {openSlug === it.id ? t("Sluiten","Close") : t("Review plaatsen","Write a review")}
              </button>
            </div>
            {openSlug === it.id && (
              <ReviewForm orderId={order.id} productSlug={it.id} productName={name} onSubmitted={onReviewed}/>
            )}
          </div>
        );
      })}
    </div>
  );
};

const OrderCard = ({ order, reviews, highlightReview, onReviewed }) => {
  const { useState, useContext } = React;
  const langCtx = useContext(window.LangContext || React.createContext({ lang:"nl", t: (nl)=>nl }));
  const t = langCtx.t || ((nl) => nl);
  const lang = langCtx.lang || "nl";
  const LP = window.LP || ((o, f) => o && o[f]);
  const products = Array.isArray(order.products) ? order.products : [];
  const locale = langCtx.lang === "en" ? "en-GB" : "nl-NL";
  const dt = order.created_at ? new Date(order.created_at).toLocaleString(locale, { dateStyle:"medium", timeStyle:"short" }) : "";
  const paidAt = order.paid_at ? new Date(order.paid_at).toLocaleString(locale, { dateStyle:"medium", timeStyle:"short" }) : null;
  const confirmationSentAt = order.confirmation_sent_at ? new Date(order.confirmation_sent_at).toLocaleString(locale, { dateStyle:"medium", timeStyle:"short" }) : null;
  const paymentStatus = (window.zsb && window.zsb.paymentStatusLabel)
    ? window.zsb.paymentStatusLabel(order.payment_status, lang)
    : (order.payment_status || "pending_payment");
  const [showHistory, setShowHistory] = useState(false);
  const [invoiceBusy, setInvoiceBusy] = useState(false);
  const [invoiceErr, setInvoiceErr] = useState(null);

  // Dutch comma date/time notation: "30 mei 2026, 17:36".
  const fmtNl = (iso) => {
    if (!iso) return null;
    const d = new Date(iso);
    if (isNaN(d.getTime())) return null;
    return d.toLocaleDateString(locale, { day:"numeric", month:"long", year:"numeric" })
      + ", " + d.toLocaleTimeString(locale, { hour:"2-digit", minute:"2-digit" });
  };
  const isCash = order.payment_method === "cash";
  const isPaid = order.payment_status === "paid" || order.status === "paid";
  const isAfgerond = order.status === "afgerond";
  const cashReceivedAt = fmtNl(order.cash_received_at);
  const cashEmailSentAt = fmtNl(order.cash_payment_email_sent_at);
  const completedEmailSentAt = fmtNl(order.completed_email_sent_at);

  const handleInvoice = async () => {
    setInvoiceBusy(true); setInvoiceErr(null);
    const r = await window.zsb.downloadCustomerInvoice(order.id);
    setInvoiceBusy(false);
    if (r && r.error) setInvoiceErr(r.error);
  };

  return (
    <div className="card" style={{padding:22, marginBottom:14}}>
      <div style={{display:"flex", justifyContent:"space-between", alignItems:"flex-start", gap:14, flexWrap:"wrap"}}>
        <div>
          <div className="mono" style={{fontSize:11, color:"var(--ink-mute)", letterSpacing:".1em", textTransform:"uppercase"}}>
            {order.order_type === "reservering" ? t("Reservering","Reservation") : t("Bestelling","Order")} · {order.id.slice(0,8).toUpperCase()}
          </div>
          <div style={{fontFamily:"var(--f-display)", fontSize:20, fontWeight:700, marginTop:4}}>
            {formatEUR(Number(order.total) || 0)}
          </div>
          <div style={{fontSize:12.5, color:"var(--ink-dim)", marginTop:4}}>{dt}</div>
        </div>
        <StatusBadge status={order.status}/>
      </div>

      <hr style={{border:0, borderTop:"1px solid var(--line)", margin:"14px 0"}}/>

      <div style={{display:"flex", flexDirection:"column", gap:8, fontSize:13.5}}>
        {products.map((p, i) => (
          <div key={i} style={{display:"flex", justifyContent:"space-between"}}>
            <span>{p.qty}× {ALL_ITEMS[p.id] ? (LP(ALL_ITEMS[p.id],"name",lang) || LP(ALL_ITEMS[p.id],"short",lang) || p.name) : p.name}</span>
            <span className="mono">{formatEUR((Number(p.price)||0) * (Number(p.qty)||1))}</span>
          </div>
        ))}
        {Number(order.assembly_fee) > 0 && (
          <div style={{display:"flex", justifyContent:"space-between"}}>
            <span>{t("Montage door Zyro","Assembly by Zyro")}</span>
            <span className="mono">{formatEUR(Number(order.assembly_fee))}</span>
          </div>
        )}
      </div>

      <hr style={{border:0, borderTop:"1px solid var(--line)", margin:"14px 0"}}/>

      <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:14, fontSize:13}}>
        <div style={{order:1}}>
          <div className="mono" style={{fontSize:10.5, color:"var(--ink-mute)", letterSpacing:".1em", textTransform:"uppercase", marginBottom:4}}>{t("Levering","Delivery")}</div>
          {order.fulfillment_method === "ophalen" ? (
            <div>
              <div style={{fontWeight:600}}>{t("Ophalen","Pickup")}</div>
              <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Ophalen in showroom","Pickup at showroom")}</div>
            </div>
          ) : (
            <div>
              <div style={{fontWeight:600}}>{t("Bezorgadres","Delivery address")}</div>
              <div style={{color:"var(--ink-dim)", marginTop:2}}>
                {order.delivery_name ? <>{order.delivery_name}<br/></> : null}
                {order.delivery_formatted_address
                  ? order.delivery_formatted_address
                  : <>{order.delivery_street}<br/>{order.delivery_postcode} {order.delivery_city}</>}
              </div>
            </div>
          )}
        </div>
        <div style={{order:3, gridColumn:"1 / -1", marginTop:4, padding:"14px 16px", border:"1px solid var(--line)", borderRadius:10, background:"var(--bg)"}}>
          <div className="mono" style={{fontSize:11, color:"var(--ink-mute)", letterSpacing:".1em", textTransform:"uppercase", marginBottom:8, fontWeight:700}}>{t("Betaling","Payment")}</div>
          {isCash ? (
            <>
              <div style={{fontWeight:600}}>{t("Contant bij ophalen","Cash on pickup")}</div>
              <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Betaalstatus","Payment status")}: {paymentStatus}</div>
              {isPaid && order.cash_amount_received != null && <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Contant ontvangen","Cash received")}: {formatEUR(Number(order.cash_amount_received)||0)}</div>}
              {isPaid && order.cash_change_given != null && <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Wisselgeld gegeven","Change given")}: {formatEUR(Number(order.cash_change_given)||0)}</div>}
              {isPaid && cashReceivedAt && <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Contant ontvangen op","Cash received at")}: {cashReceivedAt}</div>}
              {isPaid && order.invoice_number && <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Factuurnummer","Invoice number")}: {order.invoice_number}</div>}
              {isPaid && completedEmailSentAt && <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Factuur verzonden op","Invoice sent at")}: {completedEmailSentAt}</div>}
            </>
          ) : (
            <>
              <div style={{fontWeight:600}}>{t("Online betaald","Paid online")}</div>
              <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Betaalstatus","Payment status")}: {paymentStatus}</div>
              {paidAt && <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Betaald op","Paid at")}: {paidAt}</div>}
            </>
          )}
          {order.confirmation_number && <div style={{color:"var(--ink-dim)", marginTop:2}}>{t("Bevestiging","Confirmation")}: {order.confirmation_number}</div>}

          {isAfgerond ? (
            <div style={{marginTop:10}}>
              <button onClick={handleInvoice} disabled={invoiceBusy} className="btn btn-primary btn-sm" style={{display:"inline-flex"}}>
                <Icon name="download" size={14}/> {invoiceBusy ? t("Laden…","Loading…") : t("Bekijk factuur","View invoice")}
              </button>
              {!isCash && <div style={{color:"var(--ink-dim)", marginTop:8, fontSize:12.5}}>{t("Factuurnummer","Invoice number")}: {order.invoice_number || t("Factuur wordt verwerkt","Invoice is being processed")}</div>}
              {!isCash && <div style={{color:"var(--ink-dim)", marginTop:2, fontSize:12.5}}>{t("Factuur verzonden op","Invoice sent at")}: {completedEmailSentAt || t("Factuurmail nog niet verzonden","Invoice email not sent yet")}</div>}
              {invoiceErr && <div style={{color:"var(--bad)", marginTop:6, fontSize:12.5}}>{invoiceErr}</div>}
              <div style={{marginTop:8}}>
                <a href={`#payment-success?order_id=${encodeURIComponent(order.id)}`} className="btn btn-ghost btn-sm" style={{display:"inline-flex"}}>
                  {t("Bekijk koopbevestiging","View order confirmation")}
                </a>
              </div>
            </div>
          ) : (
            <a href={`#payment-success?order_id=${encodeURIComponent(order.id)}`} className="btn btn-ghost btn-sm" style={{display:"inline-flex", marginTop:10}}>
              {t("Bekijk koopbevestiging","View order confirmation")}
            </a>
          )}
        </div>
        <div style={{order:2}}>
          <div className="mono" style={{fontSize:10.5, color:"var(--ink-mute)", letterSpacing:".1em", textTransform:"uppercase", marginBottom:4}}>{t("Aankoopbewijs","Receipt")}</div>
          {order.proof_url ? (
            <a href={order.proof_url} target="_blank" rel="noopener" className="btn btn-ghost btn-sm" style={{display:"inline-flex"}}>
              <Icon name="download" size={14}/> {t("Aankoopbewijs downloaden","Download receipt")}
            </a>
          ) : (
            <div style={{color:"var(--ink-dim)", fontSize:12.5}}>{t("Aankoopbewijs wordt toegevoegd zodra je bestelling is verwerkt.","The receipt is added once your order is processed.")}</div>
          )}
        </div>
      </div>

      <div style={{marginTop:14, paddingTop:12, borderTop:"1px dashed var(--line)"}}>
        <button onClick={()=>setShowHistory(s=>!s)} style={{
          background:"none", border:0, padding:0, cursor:"pointer", fontSize:12,
          color:"var(--ink-dim)", textTransform:"uppercase", letterSpacing:".08em", fontFamily:"var(--f-mono)",
        }}>
          {showHistory ? "▾ " + t("Verberg geschiedenis","Hide history") : "▸ " + t("Geschiedenis","History")}
        </button>
        {showHistory && (
          <div style={{marginTop:12, paddingLeft:4}}>
            <OrderHistory orderId={order.id}/>
          </div>
        )}
      </div>

      {/* Reviews — only once the order is afgerond (matches the email's review link). */}
      {order.status === "afgerond" && (
        <OrderReviewBlock order={order} reviews={reviews} defaultOpen={!!highlightReview} onReviewed={onReviewed}/>
      )}
    </div>
  );
};

const ProfileCard = ({ user, profile, onSave }) => {
  const { useState, useEffect, useContext } = React;
  const langCtx = useContext(window.LangContext || React.createContext({ lang:"nl", t: (nl)=>nl }));
  const t = langCtx.t || ((nl) => nl);
  const [fullName, setFullName] = useState("");
  const [phone, setPhone] = useState("");
  const [busy, setBusy] = useState(false);
  const [savedAt, setSavedAt] = useState(null);
  const [err, setErr] = useState(null);

  useEffect(() => {
    setFullName((profile && profile.full_name) || "");
    setPhone((profile && profile.phone) || "");
  }, [profile && profile.full_name, profile && profile.phone]);

  const save = async (e) => {
    e.preventDefault();
    setBusy(true); setErr(null);
    const r = await window.zsb.upsertProfile({ id: user.id, full_name: fullName, phone });
    setBusy(false);
    if (r.error) setErr(r.error);
    else { setSavedAt(Date.now()); onSave && onSave(); }
  };

  return (
    <div className="card" style={{padding:24, marginBottom:14}}>
      <h2 className="h-display" style={{fontSize:20, marginBottom:14}}>{t("Profiel","Profile")}</h2>
      <form onSubmit={save}>
        <div className="grid-2" style={{marginBottom:14}}>
          <div className="field">
            <label className="field-label">{t("Volledige naam","Full name")}</label>
            <input className="input" value={fullName} onChange={e=>setFullName(e.target.value)} placeholder={t("Jan de Vries","John Doe")}/>
          </div>
          <div className="field">
            <label className="field-label">{t("Telefoonnummer","Phone number")}</label>
            <input className="input" type="tel" value={phone} onChange={e=>setPhone(e.target.value)} placeholder="+31 6 ..."/>
          </div>
        </div>
        <div className="field" style={{marginBottom:14}}>
          <label className="field-label">{t("E-mail","Email")}</label>
          <input className="input" type="email" value={user.email || ""} disabled style={{opacity:.7}}/>
        </div>
        {err && <div style={{color:"var(--bad)", fontSize:13, marginBottom:10}}>{err}</div>}
        <div className="gap-12">
          <button type="submit" className="btn btn-primary" disabled={busy}>{busy ? t("Opslaan…","Saving…") : t("Profiel opslaan","Save profile")}</button>
          {savedAt && <span style={{fontSize:12.5, color:"var(--ok)"}}>✓ {t("Opgeslagen","Saved")}</span>}
        </div>
      </form>
    </div>
  );
};

const PasswordCard = () => {
  const { useState, useContext } = React;
  const langCtx = useContext(window.LangContext || React.createContext({ lang:"nl", t: (nl)=>nl }));
  const t = langCtx.t || ((nl) => nl);
  const [open, setOpen] = useState(false);
  const [pw1, setPw1] = useState("");
  const [pw2, setPw2] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState(null);
  const [ok, setOk] = useState(false);

  const submit = async (e) => {
    e.preventDefault();
    setErr(null); setOk(false);
    if (pw1.length < 8) { setErr(t("Wachtwoord moet minimaal 8 tekens zijn.","Password must be at least 8 characters.")); return; }
    if (pw1 !== pw2) { setErr(t("Wachtwoorden komen niet overeen.","Passwords do not match.")); return; }
    setBusy(true);
    const r = await window.zsb.updatePassword(pw1);
    setBusy(false);
    if (r.error) { setErr(r.error); return; }
    setOk(true);
    setPw1(""); setPw2("");
  };

  return (
    <div className="card" style={{padding:24, marginBottom:14}}>
      <div style={{display:"flex", justifyContent:"space-between", alignItems:"center"}}>
        <h2 className="h-display" style={{fontSize:20, margin:0}}>{t("Wachtwoord wijzigen","Change password")}</h2>
        <button onClick={()=>{ setOpen(o=>!o); setErr(null); setOk(false); }} className="btn btn-ghost btn-sm">
          {open ? t("Sluiten","Close") : t("Wijzigen","Change")}
        </button>
      </div>
      {open && (
        <form onSubmit={submit} style={{marginTop:14}}>
          <div className="field" style={{marginBottom:12}}>
            <label className="field-label">{t("Nieuw wachtwoord","New password")}</label>
            <input className="input" type="password" value={pw1} onChange={e=>setPw1(e.target.value)} placeholder="••••••••" minLength={8} required autoComplete="new-password"/>
          </div>
          <div className="field" style={{marginBottom:12}}>
            <label className="field-label">{t("Herhaal wachtwoord","Repeat password")}</label>
            <input className="input" type="password" value={pw2} onChange={e=>setPw2(e.target.value)} placeholder="••••••••" minLength={8} required autoComplete="new-password"/>
          </div>
          {err && <div style={{color:"var(--bad)", fontSize:13, marginBottom:10}}>{err}</div>}
          {ok && <div style={{color:"var(--ok)", fontSize:13, marginBottom:10}}>✓ {t("Je wachtwoord is aangepast. Je kunt nu inloggen met je nieuwe wachtwoord.","Your password has been changed. You can sign in with the new password.")}</div>}
          <button type="submit" className="btn btn-primary" disabled={busy}>{busy ? t("Bezig…","Working…") : t("Wachtwoord opslaan","Save password")}</button>
        </form>
      )}
    </div>
  );
};

const PageAccount = ({ setPage }) => {
  const { useState, useEffect, useContext } = React;
  const auth = useContext(window.AuthContext);
  const langCtx = useContext(window.LangContext || React.createContext({ lang:"nl", t: (nl)=>nl }));
  const t = langCtx.t || ((nl) => nl);
  const [orders, setOrders] = useState([]);
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState(null);
  const [tab, setTab] = useState("all");
  const [myReviews, setMyReviews] = useState([]);
  // review_order_id from #account?review_order_id=… (the completed-order email link).
  const [reviewOrderId] = useState(() => {
    try {
      const h = window.location.hash || "";
      const q = h.indexOf("?") >= 0 ? h.slice(h.indexOf("?") + 1) : "";
      return new URLSearchParams(q).get("review_order_id") || null;
    } catch (_) { return null; }
  });
  const loadMyReviews = () => {
    if (!window.zsb || !window.zsb.isConfigured || !auth || !auth.user) return;
    window.zsb.getMyReviews().then(r => setMyReviews((r && r.data) || []));
  };

  useEffect(() => {
    if (!auth || !auth.ready) return;
    if (!auth.user) { setPage("login"); return; }
    if (!window.zsb || !window.zsb.isConfigured) {
      setLoading(false);
      setLoadError(t("Supabase is nog niet geconfigureerd. Je profiel en bestellingen kunnen nog niet geladen worden.","Supabase is not configured yet. Your profile and orders cannot be loaded."));
      return;
    }
    setLoading(true);
    setLoadError(null);
    window.zsb.getMyOrders(auth.user.id).then(({ data, error }) => {
      setLoading(false);
      if (error) setLoadError(error);
      setOrders(data || []);
    });
    // eslint-disable-next-line
  }, [auth && auth.ready, auth && auth.user && auth.user.id]);

  // Load the customer's own reviews (status + which (order,product) are reviewed).
  useEffect(() => {
    loadMyReviews();
    // eslint-disable-next-line
  }, [auth && auth.user && auth.user.id]);

  if (!auth || !auth.ready) {
    return <div className="page section"><div className="wrap"><p>{t("Laden...","Loading...")}</p></div></div>;
  }
  if (!auth.user) {
    return <div className="page section"><div className="wrap"><p>{t("Je wordt doorgestuurd naar inloggen...","Redirecting to sign in...")}</p></div></div>;
  }

  const bestellingen = orders.filter(o => o.order_type !== "reservering");
  const reserveringen = orders.filter(o => o.order_type === "reservering");
  const list = tab === "bestellingen" ? bestellingen : tab === "reserveringen" ? reserveringen : orders;

  const onSignOut = async () => {
    await window.zsb.signOut();
    setPage("home");
  };

  return (
    <div className="page">
      <section style={{padding:"40px 0 16px", borderBottom:"1px solid var(--line)"}}>
        <div className="wrap" style={{display:"flex", justifyContent:"space-between", alignItems:"flex-end", flexWrap:"wrap", gap:14}}>
          <div>
            <div className="eyebrow" style={{marginBottom:10}}>Account</div>
            <h1 className="h-display" style={{fontSize:"clamp(34px,5vw,52px)"}}>{t("Mijn account","My account")}</h1>
            <p style={{color:"var(--ink-dim)", marginTop:6}}>{t("Welkom","Welcome")} {(auth.profile && auth.profile.full_name) || auth.user.email}.</p>
          </div>
          <div className="gap-8">
            {/* Active staff (owner OR medewerker) get a clear admin entry. Driven by
                getCurrentAdmin()/get_my_admin_row() via auth.isStaff — NOT the owner
                email check — so e.g. snellecall@gmail.com sees it too. Plain customers
                (no admin_users row) get isStaff=false and never see this. */}
            {(auth.isStaff || auth.isAdmin) && <button className="btn btn-primary btn-sm" onClick={()=>setPage("admin")}>{t("Naar adminpaneel","To admin panel")}</button>}
            <button className="btn btn-ghost btn-sm" onClick={onSignOut}>{t("Uitloggen","Sign out")}</button>
          </div>
        </div>
      </section>

      <section className="section-sm">
        <div className="wrap" style={{display:"grid", gridTemplateColumns:"1fr 2fr", gap:28}} className="acc-grid">
          <div>
            <ProfileCard user={auth.user} profile={auth.profile} onSave={auth.refreshProfile}/>
            <PasswordCard/>
            <div className="card" style={{padding:20, fontSize:13, color:"var(--ink-dim)"}}>
              <strong style={{color:"var(--ink)"}}>{t("Showroom","Showroom")}</strong>
              <div style={{marginTop:8, lineHeight:1.6}}>
                Paranadreef 257<br/>
                3563 WK Utrecht<br/>
                {t("Nederland","Netherlands")}
              </div>
            </div>
          </div>

          <div>
            <div style={{display:"flex", gap:6, marginBottom:16, background:"var(--bg)", padding:4, borderRadius:10, width:"fit-content", flexWrap:"wrap"}}>
              {[
                {id:"all", label:`${t("Alles","All")} · ${orders.length}`},
                {id:"bestellingen", label:`${t("Bestellingen","Orders")} · ${bestellingen.length}`},
                {id:"reserveringen", label:`${t("Reserveringen","Reservations")} · ${reserveringen.length}`},
              ].map(tb => (
                <button key={tb.id} onClick={()=>setTab(tb.id)} style={{
                  padding:"8px 14px", borderRadius:8, fontSize:12.5, fontWeight:600,
                  background: tab === tb.id ? "#fff" : "transparent",
                  color: tab === tb.id ? "var(--ink)" : "var(--ink-dim)",
                }}>{tb.label}</button>
              ))}
            </div>

            {loadError && (
              <div className="card" style={{padding:18, marginBottom:14, background:"#fff8e6", border:"1px solid #f0d985", fontSize:13}}>
                {loadError}
              </div>
            )}

            {loading ? (
              <div className="card" style={{padding:36, textAlign:"center", color:"var(--ink-dim)"}}>{t("Laden...","Loading...")}</div>
            ) : list.length === 0 ? (
              <div className="card" style={{padding:36, textAlign:"center"}}>
                <div style={{fontFamily:"var(--f-display)", fontSize:18, marginBottom:8}}>{t("Nog geen bestellingen","No orders yet")}</div>
                <p style={{color:"var(--ink-dim)", fontSize:13.5, marginBottom:18}}>{t("Zodra je een bestelling plaatst zie je hem hier verschijnen.","As soon as you place an order it will appear here.")}</p>
                <button className="btn btn-primary btn-sm" onClick={()=>setPage("shop")}>{t("Naar de webshop","To the shop")}</button>
              </div>
            ) : (
              list.map(o => <OrderCard key={o.id} order={o} reviews={myReviews} highlightReview={reviewOrderId === o.id} onReviewed={loadMyReviews}/>)
            )}
          </div>

          <style>{`@media (max-width:900px){.acc-grid{grid-template-columns:1fr !important}}`}</style>
        </div>
      </section>
    </div>
  );
};

window.PageAccount = PageAccount;
window.StatusBadge = StatusBadge;
window.OrderHistory = OrderHistory;
