// Klantportaal — voertuigen, afspraken, APK-reminder, facturen, profiel
function Portaal({ user, onNav, onLogout }) {
  const [tab, setTab] = React.useState("overzicht");
  const [me, setMe] = React.useState(user);
  const [vehicles, setVehicles] = React.useState([]);
  const [appointments, setAppointments] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [toast, setToast] = React.useState(null); // { type, msg }
  const [showAddVehicle, setShowAddVehicle] = React.useState(false);
  const [editVehicle, setEditVehicle] = React.useState(null); // vehicle obj
  const [editProfile, setEditProfile] = React.useState(false);

  const showToast = (msg, type = "success") => {
    setToast({ msg, type });
    setTimeout(() => setToast(null), 4000);
  };

  // Refresh helpers
  const refreshAll = React.useCallback(async () => {
    setLoading(true);
    try {
      const [meData, apptsData] = await Promise.all([
        window.api.auth.me().catch(() => ({ user: null, vehicles: [] })),
        window.api.appointments.list().catch(() => ({ appointments: [] })),
      ]);
      if (meData.user) setMe(meData.user);
      setVehicles(meData.vehicles || []);
      setAppointments(apptsData.appointments || []);
    } finally {
      setLoading(false);
    }
  }, []);

  React.useEffect(() => {
    if (!window.api) return;
    refreshAll();
  }, [refreshAll]);

  // Voertuig-CRUD callbacks
  const onVehicleAdded = () => {
    setShowAddVehicle(false);
    refreshAll();
    showToast("Voertuig toegevoegd");
  };
  const onVehicleUpdated = () => {
    setEditVehicle(null);
    refreshAll();
    showToast("Wijzigingen opgeslagen");
  };
  const onVehicleDeleted = async (id) => {
    if (!confirm("Voertuig verwijderen uit uw account?")) return;
    try {
      await window.api.vehicles.remove(id);
      refreshAll();
      showToast("Voertuig verwijderd");
    } catch (e) {
      showToast(e.message || "Kon voertuig niet verwijderen", "error");
    }
  };

  // Afspraken acties
  const onCancelAppointment = async (id) => {
    if (!confirm("Afspraak annuleren? Dit kan niet ongedaan gemaakt worden.")) return;
    try {
      await window.api.appointments.cancel(id, "klant geannuleerd via portaal");
      refreshAll();
      showToast("Afspraak geannuleerd");
    } catch (e) {
      showToast(e.message || "Kon afspraak niet annuleren", "error");
    }
  };

  // Helpers
  const fmtDate = (iso) => new Date(iso).toLocaleDateString("nl-NL", { day: "numeric", month: "long", year: "numeric" });
  const fmtTime = (iso) => new Date(iso).toLocaleTimeString("nl-NL", { hour: "2-digit", minute: "2-digit" });
  const today = new Date();

  // Voertuigen normaliseren met APK-info
  const normalizedVehicles = vehicles.map((v, i) => {
    const apkDate = v.apk_expiry ? new Date(v.apk_expiry) : null;
    const apkDays = apkDate ? Math.ceil((apkDate - today) / (1000 * 60 * 60 * 24)) : null;
    return {
      id: v.id,
      plate: v.license_plate,
      merk: [v.make, v.model].filter(Boolean).join(" ") || "Onbekend",
      jaar: v.year,
      mileage: v.mileage,
      km: v.mileage ? new Intl.NumberFormat("nl-NL").format(v.mileage) : "—",
      fuel: v.fuel_type,
      apk: apkDate ? apkDate.toLocaleDateString("nl-NL") : "—",
      apkDays,
      apkExpiry: v.apk_expiry,
      primary: i === 0,
    };
  });

  const upcoming = appointments
    .filter(a => ["booked", "arrived", "in_progress"].includes(a.status))
    .filter(a => new Date(a.start_at) >= new Date(new Date().toDateString()))
    .sort((a, b) => new Date(a.start_at) - new Date(b.start_at))
    .map(a => ({
      id: a.id,
      raw_start: a.start_at,
      date: fmtDate(a.start_at),
      time: fmtTime(a.start_at),
      service_id: a.service_id,
      service: a.service_name,
      service_slug: a.service_slug,
      plate: a.license_plate,
      vehicle: a.vehicle,
      status: a.status,
    }));

  const history = appointments
    .filter(a => ["done", "picked", "cancelled"].includes(a.status))
    .map(a => ({
      id: a.id,
      raw_start: a.start_at,
      date: fmtDate(a.start_at),
      service: a.service_name,
      service_slug: a.service_slug,
      plate: a.license_plate,
      total: a.price !== null ? `€ ${a.price.toFixed(2).replace(".", ",")}` : "op offerte",
      status: a.status,
      invoice: `${new Date(a.start_at).getFullYear()}-${String(a.id).padStart(4, "0")}`,
    }));

  const apkSoon = normalizedVehicles
    .filter(v => v.apkDays !== null && v.apkDays < 60)
    .sort((a, b) => a.apkDays - b.apkDays)[0];

  if (loading) {
    return (
      <div style={{ background: "var(--bg)", minHeight: "calc(100vh - 73px)", display: "flex", alignItems: "center", justifyContent: "center" }}>
        <div style={{ textAlign: "center", color: "var(--text-muted)" }}>
          <div style={{ width: 32, height: 32, border: "3px solid var(--border)", borderTopColor: "var(--accent)", borderRadius: "50%", animation: "spin 0.8s linear infinite", margin: "0 auto 12px" }}/>
          <div style={{ fontSize: 13 }}>Bezig met laden…</div>
        </div>
      </div>
    );
  }

  return (
    <div style={{ background: "var(--bg)", minHeight: "calc(100vh - 73px)" }}>
      {/* Toast */}
      {toast && (
        <div style={{
          position: "fixed", top: 90, right: 24, zIndex: 100,
          background: toast.type === "error" ? "var(--danger)" : "var(--success, #10b981)",
          color: "#fff", padding: "12px 20px", borderRadius: 10, fontWeight: 600, fontSize: 14,
          boxShadow: "0 8px 24px rgba(0,0,0,0.18)",
        }}>
          {toast.msg}
        </div>
      )}

      {/* Header band */}
      <section style={{ borderBottom: "1px solid var(--border)", background: "var(--surface)" }}>
        <div style={{ maxWidth: 1280, margin: "0 auto", padding: "48px 32px" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", flexWrap: "wrap", gap: 24 }}>
            <div>
              <div className="eyebrow" style={{ marginBottom: 10 }}>Klantportaal</div>
              <h1 className="headline" style={{ fontSize: 44 }}>Welkom terug, {me.name.split(" ")[0]}.</h1>
              <p className="text-muted" style={{ fontSize: 15, marginTop: 8 }}>
                {normalizedVehicles.length} voertuig{normalizedVehicles.length === 1 ? "" : "en"} · {upcoming.length} aankomende afspra{upcoming.length === 1 ? "ak" : "ken"}
              </p>
            </div>
            <div style={{ display: "flex", gap: 10 }}>
              <button className="btn btn-ghost btn-sm" onClick={onLogout}>Uitloggen</button>
              <button className="btn btn-primary" onClick={() => onNav("boeking")}>
                <I.Plus size={14}/> Nieuwe afspraak
              </button>
            </div>
          </div>

          {/* Tabs */}
          <div style={{ display: "flex", gap: 4, marginTop: 32, borderBottom: "1px solid var(--border)", marginBottom: -1, overflowX: "auto" }}>
            {[
              { id: "overzicht", label: "Overzicht" },
              { id: "voertuigen", label: "Mijn voertuigen" },
              { id: "afspraken", label: "Afspraken" },
              { id: "facturen", label: "Facturen" },
              { id: "profiel", label: "Profiel" },
            ].map(t => (
              <button key={t.id} onClick={() => setTab(t.id)} style={{
                background: "none", border: 0, padding: "12px 16px", cursor: "pointer",
                color: tab === t.id ? "var(--text)" : "var(--text-muted)",
                fontWeight: tab === t.id ? 700 : 500, fontSize: 14, whiteSpace: "nowrap",
                borderBottom: "2px solid " + (tab === t.id ? "var(--accent)" : "transparent"),
                marginBottom: -1,
              }}>
                {t.label}
              </button>
            ))}
          </div>
        </div>
      </section>

      <section style={{ maxWidth: 1280, margin: "0 auto", padding: "48px 32px" }}>
        {/* Empty state — geen voertuigen, hard pushen om er een toe te voegen */}
        {normalizedVehicles.length === 0 && tab !== "profiel" ? (
          <EmptyState onAdd={() => setShowAddVehicle(true)} onNav={onNav}/>
        ) : (
          <>
            {tab === "overzicht" && <Overzicht
              vehicles={normalizedVehicles}
              upcoming={upcoming}
              history={history}
              apkSoon={apkSoon}
              onNav={onNav}
              onAddVehicle={() => setShowAddVehicle(true)}
              onEditVehicle={setEditVehicle}
              onCancel={onCancelAppointment}
            />}
            {tab === "voertuigen" && <Voertuigen
              vehicles={normalizedVehicles}
              onAdd={() => setShowAddVehicle(true)}
              onEdit={setEditVehicle}
              onDelete={onVehicleDeleted}
              onNav={onNav}
            />}
            {tab === "afspraken" && <Afspraken
              upcoming={upcoming}
              history={history}
              onNav={onNav}
              onCancel={onCancelAppointment}
            />}
            {tab === "facturen" && <Facturen history={history.filter(h => h.status === "done" || h.status === "picked")}/>}
          </>
        )}
        {tab === "profiel" && <Profiel user={me} onUpdated={(u) => { setMe(u); showToast("Profiel bijgewerkt"); }} showToast={showToast}/>}
      </section>

      {/* Modals */}
      {showAddVehicle && <AddVehicleModal onClose={() => setShowAddVehicle(false)} onAdded={onVehicleAdded}/>}
      {editVehicle && <EditVehicleModal vehicle={editVehicle} onClose={() => setEditVehicle(null)} onSaved={onVehicleUpdated}/>}
    </div>
  );
}

// ============================================================
// Empty state — eerste-bezoek welkomstkaart
// ============================================================
function EmptyState({ onAdd, onNav }) {
  return (
    <div className="card" style={{ padding: 48, textAlign: "center", maxWidth: 640, margin: "32px auto" }}>
      <div style={{ width: 72, height: 72, margin: "0 auto 24px", borderRadius: "50%", background: "color-mix(in oklab, var(--accent) 15%, var(--surface))",
                     display: "flex", alignItems: "center", justifyContent: "center", color: "var(--accent)" }}>
        <I.Car size={32}/>
      </div>
      <h2 style={{ fontSize: 26, fontWeight: 700, letterSpacing: "-0.02em", marginBottom: 12 }}>Welkom bij Garage DéDé</h2>
      <p className="text-muted" style={{ fontSize: 15, lineHeight: 1.6, marginBottom: 28, maxWidth: 460, marginLeft: "auto", marginRight: "auto" }}>
        Voeg uw eerste voertuig toe — wij halen merk, model en APK-vervaldatum automatisch op via uw kenteken.
      </p>
      <div style={{ display: "flex", gap: 10, justifyContent: "center", flexWrap: "wrap" }}>
        <button className="btn btn-primary" onClick={onAdd}>
          <I.Plus size={14}/> Voertuig toevoegen
        </button>
        <button className="btn btn-ghost" onClick={() => onNav("boeking")}>Direct afspraak maken</button>
      </div>
    </div>
  );
}

// ============================================================
// Overzicht-tab — APK banner, volgende afspraak, recente bezoeken
// ============================================================
function Overzicht({ vehicles, upcoming, history, apkSoon, onNav, onAddVehicle, onEditVehicle, onCancel }) {
  const next = upcoming[0];
  return (
    <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 24 }}>
      <div style={{ display: "flex", flexDirection: "column", gap: 24 }}>
        {/* APK-reminder card */}
        {apkSoon && (
          <div className="card" style={{ padding: 28,
            background: "linear-gradient(135deg, var(--surface), color-mix(in oklab, var(--accent) 8%, var(--surface)))",
            border: "1px solid color-mix(in oklab, var(--accent) 30%, var(--border))" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 16 }}>
              <div style={{ flex: 1 }}>
                <div className="eyebrow" style={{ marginBottom: 10, display: "inline-flex", alignItems: "center", gap: 8 }}>
                  <I.Calendar size={13}/> APK herinnering
                </div>
                <h2 style={{ fontSize: 26, fontWeight: 700, letterSpacing: "-0.02em", marginBottom: 8 }}>
                  {apkSoon.apkDays < 0
                    ? <>Uw APK is <span style={{ color: "var(--danger)" }}>{Math.abs(apkSoon.apkDays)} dagen verlopen</span>.</>
                    : apkSoon.apkDays === 0
                    ? <>Uw APK verloopt <span style={{ color: "var(--accent)" }}>vandaag</span>.</>
                    : <>Uw APK verloopt over <span style={{ color: "var(--accent)" }}>{apkSoon.apkDays} dagen</span>.</>
                  }
                </h2>
                <p className="text-muted" style={{ fontSize: 14, lineHeight: 1.6, margin: 0, maxWidth: 460 }}>
                  Plan nu in zodat u kunt kiezen wanneer het u uitkomt — een APK twee maanden vooraf laten doen
                  betekent géén verlies van keuringsdagen.
                </p>
                <div style={{ display: "flex", alignItems: "center", gap: 12, marginTop: 16 }}>
                  <Plate value={apkSoon.plate} size="sm"/>
                  <span className="text-muted" style={{ fontSize: 13 }}>{apkSoon.merk} · APK tot {apkSoon.apk}</span>
                </div>
              </div>
              <button className="btn btn-primary" onClick={() => onNav("boeking")}>
                Plan APK <I.ArrowRight size={14}/>
              </button>
            </div>
          </div>
        )}

        {/* Volgende afspraak */}
        <div className="card" style={{ padding: 28 }}>
          <div className="eyebrow" style={{ marginBottom: 14 }}>Volgende afspraak</div>
          {next ? (
            <NextAppointmentCard appt={next} onCancel={() => onCancel(next.id)}/>
          ) : (
            <div style={{ textAlign: "center", padding: "16px 0" }}>
              <p className="text-muted" style={{ marginBottom: 16 }}>Geen aankomende afspraken.</p>
              <button className="btn btn-primary btn-sm" onClick={() => onNav("boeking")}>
                <I.Plus size={14}/> Afspraak inplannen
              </button>
            </div>
          )}
        </div>

        {/* Recente bezoeken */}
        {history.length > 0 && (
          <div className="card" style={{ padding: 28 }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 18 }}>
              <div className="eyebrow">Recente bezoeken</div>
            </div>
            <div style={{ display: "flex", flexDirection: "column" }}>
              {history.slice(0, 3).map((h, i) => (
                <div key={h.id} style={{ display: "grid", gridTemplateColumns: "120px 1fr auto auto", gap: 16, alignItems: "center",
                                       padding: "14px 0", borderBottom: i < Math.min(2, history.length - 1) ? "1px dashed var(--border)" : "none" }}>
                  <span className="text-mono text-muted" style={{ fontSize: 13 }}>{h.date}</span>
                  <div>
                    <div style={{ fontWeight: 600, fontSize: 14 }}>{h.service}</div>
                    <div className="text-muted" style={{ fontSize: 12 }}>{h.plate}</div>
                  </div>
                  <span className="text-mono" style={{ fontWeight: 700, fontSize: 14 }}>{h.total}</span>
                  <StatusPill status={h.status}/>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>

      {/* Rechter kolom: voertuigen + tip */}
      <div style={{ display: "flex", flexDirection: "column", gap: 24 }}>
        <div className="card" style={{ padding: 28 }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 18 }}>
            <div className="eyebrow">Mijn voertuigen</div>
            <button className="btn btn-ghost btn-sm" onClick={onAddVehicle}><I.Plus size={12}/></button>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
            {vehicles.map((v) => (
              <button key={v.id} onClick={() => onEditVehicle({ id: v.id, mileage: v.mileage, plate: v.plate, merk: v.merk, apkExpiry: v.apkExpiry })}
                      className="card lift" style={{ padding: 18, background: "var(--surface-2)", textAlign: "left", border: 0, cursor: "pointer", width: "100%" }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 12 }}>
                  <Plate value={v.plate} size="sm"/>
                  {v.primary && <span className="pill accent" style={{ fontSize: 10 }}><span className="dot"/> Primair</span>}
                </div>
                <div style={{ fontWeight: 600, fontSize: 15 }}>{v.merk}</div>
                <div className="text-muted" style={{ fontSize: 12, marginBottom: 12 }}>{v.jaar || "?"} · {v.km} km</div>
                <hr className="div"/>
                <div style={{ display: "flex", justifyContent: "space-between", paddingTop: 10, fontSize: 12 }}>
                  <span className="text-muted">APK verloopt</span>
                  <span className="text-mono" style={{ color: v.apkDays !== null && v.apkDays < 60 ? "var(--accent)" : "var(--text)", fontWeight: 600 }}>
                    {v.apk}
                  </span>
                </div>
              </button>
            ))}
          </div>
        </div>

        <div className="card" style={{ padding: 24, background: "var(--surface)" }}>
          <div className="eyebrow" style={{ marginBottom: 12 }}>💡 Wist u dat</div>
          <p style={{ fontSize: 14, lineHeight: 1.6, margin: 0 }}>
            U mag uw APK twee maanden voor de vervaldatum laten doen — zonder dat u dagen verliest.
            De nieuwe vervaldatum blijft hetzelfde.
          </p>
        </div>
      </div>
    </div>
  );
}

function NextAppointmentCard({ appt, onCancel }) {
  const d = new Date(appt.raw_start);
  const months = ["JAN","FEB","MRT","APR","MEI","JUN","JUL","AUG","SEP","OKT","NOV","DEC"];
  const days = ["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"];
  return (
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 16 }}>
      <div style={{ display: "flex", gap: 20 }}>
        <div style={{ width: 64, padding: "12px 0", background: "var(--surface-2)", border: "1px solid var(--border)",
                     borderRadius: 12, textAlign: "center" }}>
          <div className="text-mono text-muted" style={{ fontSize: 11, fontWeight: 600 }}>{months[d.getMonth()]}</div>
          <div style={{ fontFamily: "var(--font-display)", fontSize: 32, fontWeight: 800, color: "var(--accent)", lineHeight: 1 }}>
            {d.getDate()}
          </div>
          <div className="text-muted" style={{ fontSize: 11 }}>{days[d.getDay()]}</div>
        </div>
        <div>
          <div style={{ fontSize: 20, fontWeight: 700, marginBottom: 4 }}>{appt.service}</div>
          <div className="text-muted" style={{ fontSize: 14, marginBottom: 10 }}>
            {appt.time} · Achterasweg 10-A, Vijfhuizen
          </div>
          <Plate value={appt.plate} size="sm"/>
        </div>
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        <StatusPill status={appt.status}/>
        <button className="btn btn-ghost btn-sm" style={{ color: "var(--danger)" }} onClick={onCancel}>Annuleren</button>
      </div>
    </div>
  );
}

function StatusPill({ status }) {
  const map = {
    booked:      { label: "Gepland",        color: "var(--accent)" },
    arrived:     { label: "Aangekomen",     color: "var(--accent)" },
    in_progress: { label: "In behandeling", color: "var(--accent)" },
    done:        { label: "Klaar",          color: "var(--success, #10b981)" },
    picked:      { label: "Opgehaald",      color: "var(--success, #10b981)" },
    cancelled:   { label: "Geannuleerd",    color: "var(--text-muted)" },
  };
  const s = map[status] || { label: status, color: "var(--text-muted)" };
  return (
    <span className="pill" style={{ fontSize: 11 }}>
      <span className="dot" style={{ background: s.color }}/> {s.label}
    </span>
  );
}

// ============================================================
// Voertuigen-tab
// ============================================================
function Voertuigen({ vehicles, onAdd, onEdit, onDelete, onNav }) {
  return (
    <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(360px, 1fr))", gap: 20 }}>
      {vehicles.map((v) => (
        <div key={v.id} className="card" style={{ padding: 28 }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 20 }}>
            <Plate value={v.plate}/>
            {v.primary && <span className="pill accent"><span className="dot"/> Primair</span>}
          </div>
          <div style={{ fontFamily: "var(--font-display)", fontSize: 24, fontWeight: 700, letterSpacing: "-0.02em" }}>{v.merk}</div>
          <div className="text-muted" style={{ fontSize: 13, marginBottom: 20 }}>
            {v.jaar ? `Bouwjaar ${v.jaar}` : "Bouwjaar onbekend"}{v.fuel ? ` · ${v.fuel}` : ""}
          </div>
          <hr className="div"/>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, paddingTop: 18 }}>
            <Spec label="Kilometers" value={v.km}/>
            <Spec label="APK verloopt" value={v.apk} accent={v.apkDays !== null && v.apkDays < 60}/>
          </div>
          <div style={{ display: "flex", gap: 8, marginTop: 20 }}>
            <button className="btn btn-ghost btn-sm" style={{ flex: 1 }} onClick={() => onEdit({ id: v.id, mileage: v.mileage, plate: v.plate, merk: v.merk, apkExpiry: v.apkExpiry })}>
              Bewerken
            </button>
            <button className="btn btn-primary btn-sm" style={{ flex: 1 }} onClick={() => onNav("boeking")}>
              Plan onderhoud
            </button>
          </div>
          <button onClick={() => onDelete(v.id)} className="text-muted"
                  style={{ marginTop: 12, background: "none", border: 0, fontSize: 12, cursor: "pointer", padding: 4, width: "100%" }}>
            Voertuig verwijderen
          </button>
        </div>
      ))}
      <button onClick={onAdd} className="card lift" style={{ padding: 28, background: "transparent", border: "1.5px dashed var(--border)",
                                              cursor: "pointer", color: "var(--text-muted)",
                                              display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 10, minHeight: 200 }}>
        <I.Plus size={28}/>
        <span style={{ fontWeight: 600 }}>Voertuig toevoegen</span>
      </button>
    </div>
  );
}

// ============================================================
// Afspraken-tab
// ============================================================
function Afspraken({ upcoming, history, onNav, onCancel }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 32 }}>
      <div>
        <h3 style={{ fontSize: 18, fontWeight: 700, marginBottom: 16 }}>Aankomend</h3>
        {upcoming.length === 0 && (
          <div className="card" style={{ padding: 24, textAlign: "center" }}>
            <p className="text-muted" style={{ marginBottom: 12 }}>U heeft geen aankomende afspraken.</p>
            <button className="btn btn-primary btn-sm" onClick={() => onNav("boeking")}>
              <I.Plus size={14}/> Afspraak inplannen
            </button>
          </div>
        )}
        {upcoming.map((a) => (
          <div key={a.id} className="card" style={{ padding: 24, marginBottom: 12, display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 12 }}>
            <div style={{ display: "flex", gap: 20, alignItems: "center" }}>
              <I.Calendar size={24} style={{ color: "var(--accent)" }}/>
              <div>
                <div style={{ fontWeight: 600 }}>{a.service} · {a.date} {a.time}</div>
                <div className="text-muted" style={{ fontSize: 13 }}>{a.plate} · Achterasweg 10-A, Vijfhuizen</div>
              </div>
            </div>
            <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
              <StatusPill status={a.status}/>
              <button className="btn btn-ghost btn-sm" style={{ color: "var(--danger)" }} onClick={() => onCancel(a.id)}>Annuleren</button>
            </div>
          </div>
        ))}
      </div>

      <div>
        <h3 style={{ fontSize: 18, fontWeight: 700, marginBottom: 16 }}>Historie</h3>
        {history.length === 0 ? (
          <div className="card" style={{ padding: 24 }}><p className="text-muted">Nog geen afspraken in uw historie.</p></div>
        ) : (
          <div className="card" style={{ padding: 0 }}>
            {history.map((h, i) => (
              <div key={h.id} style={{ display: "grid", gridTemplateColumns: "120px 1fr 120px 120px 120px", gap: 16, alignItems: "center",
                                     padding: "16px 24px", borderBottom: i < history.length - 1 ? "1px solid var(--border)" : "none" }}>
                <span className="text-mono text-muted" style={{ fontSize: 13 }}>{h.date}</span>
                <span style={{ fontWeight: 500 }}>{h.service}</span>
                <Plate value={h.plate} size="sm"/>
                <span className="text-mono" style={{ fontWeight: 700 }}>{h.total}</span>
                {h.status !== "cancelled" ? (
                  <button className="btn btn-ghost btn-sm" onClick={() => onNav("boeking")}>Boek opnieuw</button>
                ) : (
                  <span className="text-muted" style={{ fontSize: 12 }}>Geannuleerd</span>
                )}
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

// ============================================================
// Facturen-tab
// ============================================================
function Facturen({ history }) {
  if (history.length === 0) {
    return (
      <div className="card" style={{ padding: 32, textAlign: "center" }}>
        <p className="text-muted">Nog geen facturen — uw facturen verschijnen hier zodra een afspraak is afgerond.</p>
      </div>
    );
  }
  return (
    <div className="card" style={{ padding: 0 }}>
      <div style={{ display: "grid", gridTemplateColumns: "140px 140px 1fr 120px 120px 100px", gap: 16, padding: "14px 24px",
                     borderBottom: "1px solid var(--border)", background: "var(--surface)" }}>
        {["Factuurnr.", "Datum", "Omschrijving", "Voertuig", "Bedrag", ""].map((h, i) => (
          <span key={i} className="eyebrow" style={{ fontSize: 11 }}>{h}</span>
        ))}
      </div>
      {history.map((h, i) => (
        <div key={h.id} style={{ display: "grid", gridTemplateColumns: "140px 140px 1fr 120px 120px 100px", gap: 16,
                               padding: "16px 24px", alignItems: "center",
                               borderBottom: i < history.length - 1 ? "1px solid var(--border)" : "none" }}>
          <span className="text-mono" style={{ fontSize: 13, color: "var(--accent)", fontWeight: 600 }}>{h.invoice}</span>
          <span className="text-mono text-muted" style={{ fontSize: 13 }}>{h.date}</span>
          <span style={{ fontWeight: 500 }}>{h.service}</span>
          <Plate value={h.plate} size="sm"/>
          <span className="text-mono" style={{ fontWeight: 700 }}>{h.total}</span>
          <button className="btn btn-ghost btn-sm" disabled style={{ opacity: 0.5, cursor: "not-allowed" }} title="PDF binnenkort beschikbaar">PDF</button>
        </div>
      ))}
    </div>
  );
}

// ============================================================
// Profiel-tab
// ============================================================
function Profiel({ user, onUpdated, showToast }) {
  const [form, setForm] = React.useState({
    name: user.name || "",
    phone: user.phone || "",
    address: user.address || "",
    postcode: user.postcode || "",
    city: user.city || "",
  });
  const [saving, setSaving] = React.useState(false);
  const [pwForm, setPwForm] = React.useState({ current: "", next: "", confirm: "" });
  const [pwSaving, setPwSaving] = React.useState(false);

  const submitProfile = async (e) => {
    e.preventDefault();
    setSaving(true);
    try {
      await window.api.auth.updateMe(form);
      const fresh = await window.api.auth.me();
      onUpdated(fresh.user);
    } catch (err) {
      showToast(err.message || "Kon profiel niet opslaan", "error");
    } finally { setSaving(false); }
  };

  const submitPassword = async (e) => {
    e.preventDefault();
    if (pwForm.next !== pwForm.confirm) {
      showToast("Nieuwe wachtwoorden komen niet overeen", "error");
      return;
    }
    if (pwForm.next.length < 8) {
      showToast("Wachtwoord moet minimaal 8 tekens zijn", "error");
      return;
    }
    setPwSaving(true);
    try {
      await window.api.auth.changePassword(pwForm.current, pwForm.next);
      setPwForm({ current: "", next: "", confirm: "" });
      showToast("Wachtwoord gewijzigd");
    } catch (err) {
      showToast(err.message || "Kon wachtwoord niet wijzigen", "error");
    } finally { setPwSaving(false); }
  };

  return (
    <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 24 }}>
      <form onSubmit={submitProfile} className="card" style={{ padding: 28 }}>
        <div className="eyebrow" style={{ marginBottom: 18 }}>Persoonsgegevens</div>
        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <Field label="Naam" value={form.name} onChange={v => setForm(f => ({ ...f, name: v }))} required/>
          <Field label="E-mail" value={user.email} disabled hint="E-mail wijzigen kan niet via het portaal — bel ons."/>
          <Field label="Telefoon" value={form.phone} onChange={v => setForm(f => ({ ...f, phone: v }))} type="tel"/>
          <Field label="Adres" value={form.address} onChange={v => setForm(f => ({ ...f, address: v }))}/>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 2fr", gap: 12 }}>
            <Field label="Postcode" value={form.postcode} onChange={v => setForm(f => ({ ...f, postcode: v }))}/>
            <Field label="Plaats" value={form.city} onChange={v => setForm(f => ({ ...f, city: v }))}/>
          </div>
        </div>
        <button type="submit" className="btn btn-primary" disabled={saving} style={{ marginTop: 20 }}>
          {saving ? "Opslaan…" : "Opslaan"}
        </button>
      </form>

      <form onSubmit={submitPassword} className="card" style={{ padding: 28 }}>
        <div className="eyebrow" style={{ marginBottom: 18 }}>Wachtwoord wijzigen</div>
        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <Field label="Huidig wachtwoord" type="password" value={pwForm.current} onChange={v => setPwForm(f => ({ ...f, current: v }))} required/>
          <Field label="Nieuw wachtwoord" type="password" value={pwForm.next} onChange={v => setPwForm(f => ({ ...f, next: v }))} required hint="Minimaal 8 tekens"/>
          <Field label="Bevestig nieuw wachtwoord" type="password" value={pwForm.confirm} onChange={v => setPwForm(f => ({ ...f, confirm: v }))} required/>
        </div>
        <button type="submit" className="btn btn-primary" disabled={pwSaving} style={{ marginTop: 20 }}>
          {pwSaving ? "Bezig…" : "Wachtwoord wijzigen"}
        </button>
      </form>
    </div>
  );
}

function Field({ label, value, onChange, type = "text", required, disabled, hint }) {
  return (
    <label style={{ display: "block" }}>
      <div className="eyebrow" style={{ fontSize: 11, marginBottom: 6 }}>{label}</div>
      <input
        type={type}
        value={value || ""}
        onChange={e => onChange && onChange(e.target.value)}
        required={required}
        disabled={disabled}
        style={{
          width: "100%", padding: "10px 12px", borderRadius: 8,
          border: "1px solid var(--border)", background: disabled ? "var(--surface)" : "var(--bg)",
          color: "var(--text)", fontSize: 14, fontFamily: "inherit",
          opacity: disabled ? 0.6 : 1,
        }}
      />
      {hint && <div className="text-muted" style={{ fontSize: 11, marginTop: 4 }}>{hint}</div>}
    </label>
  );
}

function Spec({ label, value, accent }) {
  return (
    <div>
      <div className="text-muted" style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", marginBottom: 4 }}>{label}</div>
      <div className="text-mono" style={{ fontSize: 14, fontWeight: 700, color: accent ? "var(--accent)" : "var(--text)" }}>{value}</div>
    </div>
  );
}

// ============================================================
// Voertuig toevoegen — kenteken lookup + RDW data preview
// ============================================================
function AddVehicleModal({ onClose, onAdded }) {
  const [plate, setPlate] = React.useState("");
  const [data, setData] = React.useState(null); // RDW result
  const [mileage, setMileage] = React.useState("");
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [saving, setSaving] = React.useState(false);

  const formatPlate = (raw) => raw.toUpperCase().replace(/[^A-Z0-9]/g, "");

  const lookup = async (e) => {
    e.preventDefault();
    setError(null);
    setData(null);
    const clean = formatPlate(plate);
    if (clean.length < 5) { setError("Vul een geldig kenteken in"); return; }
    setLoading(true);
    try {
      const r = await window.api.kenteken.lookup(clean);
      setData(r);
    } catch (err) {
      setError(err.message || "Kenteken niet gevonden");
    } finally { setLoading(false); }
  };

  const save = async () => {
    if (!data) return;
    setSaving(true);
    try {
      await window.api.vehicles.create({
        license_plate: data.plate,
        make: data.make,
        model: data.model,
        year: data.year,
        fuel_type: data.fuel_type,
        apk_expiry: data.apk_expiry,
        mileage: mileage ? Number(mileage) : null,
      });
      onAdded();
    } catch (err) {
      setError(err.message || "Kon voertuig niet opslaan");
      setSaving(false);
    }
  };

  return (
    <Modal title="Voertuig toevoegen" onClose={onClose}>
      {!data ? (
        <form onSubmit={lookup}>
          <p className="text-muted" style={{ fontSize: 14, lineHeight: 1.6, marginBottom: 18 }}>
            Vul uw kenteken in. Wij halen merk, model, brandstof en APK-vervaldatum automatisch op uit het RDW.
          </p>
          <Field label="Kenteken" value={plate} onChange={setPlate} required/>
          {error && <div style={{ color: "var(--danger)", fontSize: 13, marginTop: 10 }}>{error}</div>}
          <div style={{ display: "flex", gap: 10, marginTop: 22 }}>
            <button type="button" className="btn btn-ghost" onClick={onClose}>Annuleren</button>
            <button type="submit" className="btn btn-primary" disabled={loading} style={{ flex: 1 }}>
              {loading ? "Bezig met zoeken…" : "Zoek voertuig"}
            </button>
          </div>
        </form>
      ) : (
        <div>
          <div style={{ background: "var(--surface-2)", borderRadius: 10, padding: 20, marginBottom: 18 }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 14 }}>
              <Plate value={data.plate}/>
              <button className="text-muted" onClick={() => setData(null)} style={{ background: "none", border: 0, fontSize: 12, cursor: "pointer" }}>Wijzig</button>
            </div>
            <div style={{ fontWeight: 700, fontSize: 18, marginBottom: 4 }}>
              {[data.make, data.model].filter(Boolean).join(" ") || "Onbekend"}
            </div>
            <div className="text-muted" style={{ fontSize: 13, marginBottom: 12 }}>
              {data.year && `Bouwjaar ${data.year}`}
              {data.fuel_type && ` · ${data.fuel_type}`}
              {data.color && ` · ${data.color}`}
            </div>
            {data.apk_expiry && (
              <div style={{ fontSize: 13 }}>
                <span className="text-muted">APK tot: </span>
                <span className="text-mono" style={{ fontWeight: 600 }}>{new Date(data.apk_expiry).toLocaleDateString("nl-NL")}</span>
              </div>
            )}
          </div>
          <Field label="Kilometerstand (optioneel)" type="number" value={mileage} onChange={setMileage} hint="Helpt ons bij onderhoudsadvies"/>
          {error && <div style={{ color: "var(--danger)", fontSize: 13, marginTop: 10 }}>{error}</div>}
          <div style={{ display: "flex", gap: 10, marginTop: 22 }}>
            <button type="button" className="btn btn-ghost" onClick={onClose}>Annuleren</button>
            <button type="button" className="btn btn-primary" onClick={save} disabled={saving} style={{ flex: 1 }}>
              {saving ? "Opslaan…" : "Voertuig toevoegen"}
            </button>
          </div>
        </div>
      )}
    </Modal>
  );
}

// ============================================================
// Voertuig bewerken — km-stand bijwerken
// ============================================================
function EditVehicleModal({ vehicle, onClose, onSaved }) {
  const [mileage, setMileage] = React.useState(vehicle.mileage || "");
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState(null);

  const save = async (e) => {
    e.preventDefault();
    setSaving(true);
    setError(null);
    try {
      await window.api.vehicles.update(vehicle.id, {
        mileage: mileage === "" ? null : Number(mileage),
      });
      onSaved();
    } catch (err) {
      setError(err.message || "Kon niet opslaan");
      setSaving(false);
    }
  };

  return (
    <Modal title="Voertuig bewerken" onClose={onClose}>
      <form onSubmit={save}>
        <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 20 }}>
          <Plate value={vehicle.plate} size="sm"/>
          <div>
            <div style={{ fontWeight: 600 }}>{vehicle.merk}</div>
          </div>
        </div>
        <Field label="Kilometerstand" type="number" value={mileage} onChange={setMileage} hint="Werkt u uw km-stand bij, dan weten wij wanneer welk onderhoud aan de beurt is."/>
        {error && <div style={{ color: "var(--danger)", fontSize: 13, marginTop: 10 }}>{error}</div>}
        <div style={{ display: "flex", gap: 10, marginTop: 22 }}>
          <button type="button" className="btn btn-ghost" onClick={onClose}>Annuleren</button>
          <button type="submit" className="btn btn-primary" disabled={saving} style={{ flex: 1 }}>
            {saving ? "Opslaan…" : "Opslaan"}
          </button>
        </div>
      </form>
    </Modal>
  );
}

// ============================================================
// Modal helper
// ============================================================
function Modal({ title, onClose, children }) {
  React.useEffect(() => {
    const onEsc = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onEsc);
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onEsc);
      document.body.style.overflow = "";
    };
  }, [onClose]);

  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, zIndex: 200,
      background: "rgba(0,0,0,0.55)", backdropFilter: "blur(4px)",
      display: "flex", alignItems: "center", justifyContent: "center", padding: 24,
    }}>
      <div onClick={e => e.stopPropagation()} className="card" style={{
        background: "var(--surface)", padding: 28, maxWidth: 480, width: "100%",
        maxHeight: "90vh", overflowY: "auto",
      }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
          <h2 style={{ fontSize: 20, fontWeight: 700, letterSpacing: "-0.02em", margin: 0 }}>{title}</h2>
          <button onClick={onClose} className="btn btn-ghost btn-sm" style={{ padding: 8 }}><I.X size={16}/></button>
        </div>
        {children}
      </div>
    </div>
  );
}

window.Portaal = Portaal;
