const { useState: useS, useEffect: useE, useMemo: useM, useRef: useR } = React;

// ---------- Booking Modal ----------
function BookingModal({ t, onClose, lang, onLegal }) {
  const [step, setStep] = useS(0);
  // Default to today + 7 / +11 — never in the past
  const today = new Date();
  const fmtDate = (d) => d.toISOString().slice(0, 10);
  const initArrival = new Date(today.getTime() + 7 * 86400000);
  const initDeparture = new Date(today.getTime() + 11 * 86400000);
  const [arrival, setArrival] = useS(fmtDate(initArrival));
  const [departure, setDeparture] = useS(fmtDate(initDeparture));
  const [adults, setAdults] = useS(2);
  const [kids, setKids] = useS(1);
  const [pets, setPets] = useS(0);
  const [selectedPitch, setSelectedPitch] = useS(null);
  const [selectedType, setSelectedType] = useS("stellplatz");
  const [extras, setExtras] = useS({});
  const [name, setName] = useS("");
  const [email, setEmail] = useS("");
  const [phone, setPhone] = useS("");
  const [message, setMessage] = useS("");
  const [consent, setConsent] = useS(false);
  const [errors, setErrors] = useS({});
  const [submitted, setSubmitted] = useS(false);

  const nights = useM(() => {
    const a = new Date(arrival); const d = new Date(departure);
    return Math.max(1, Math.round((d - a) / 86400000));
  }, [arrival, departure]);

  const basePrice = useM(() => {
    const item = t.booking && t.places ? window.COPY[lang].places.items.find(i => i.id === selectedType) : null;
    if (!item) return 0;
    const num = parseInt(item.price.replace(/\D/g, ""), 10) || 0;
    return num;
  }, [selectedType, lang]);

  const extrasTotal = useM(() => {
    return t.booking.extras.reduce((sum, e) => {
      if (!extras[e.id]) return sum;
      if (e.per.includes("Nacht") || e.per.includes("night")) return sum + e.price * nights;
      if (e.per.includes("Person") || e.per.includes("person")) return sum + e.price * (adults + kids);
      return sum + e.price;
    }, 0);
  }, [extras, nights, adults, kids, t]);

  const subtotal = basePrice * nights + extrasTotal + pets * 4 * nights;

  const steps = [t.booking.step1, t.booking.step2, t.booking.step3, t.booking.step4];

  const validateConfirm = () => {
    const e = {};
    if (!name.trim()) e.name = t.booking.errors.name;
    if (!email.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) e.email = t.booking.errors.email;
    if (!phone.trim()) e.phone = t.booking.errors.phone;
    if (!consent) e.consent = t.booking.errors.consent;
    setErrors(e);
    return Object.keys(e).length === 0;
  };

  const handleSubmit = () => {
    if (!validateConfirm()) return;
    const typeName = window.COPY[lang].places.items.find(i => i.id === selectedType)?.name;
    const fmt = (d) => new Date(d).toLocaleDateString(lang === "de" ? "de-AT" : "en-GB", { day: "2-digit", month: "short", year: "numeric" });
    const extraLines = Object.entries(extras).filter(([, v]) => v).map(([id]) => {
      const ex = t.booking.extras.find(e => e.id === id);
      return ex ? `- ${ex.label} (${ex.per})` : null;
    }).filter(Boolean);
    const lines = [
      `Buchungsanfrage von ${name}`,
      "",
      `Anreise: ${fmt(arrival)}`,
      `Abreise: ${fmt(departure)} (${nights} ${nights === 1 ? "Nacht" : "Nächte"})`,
      `Unterkunft: ${typeName}${selectedPitch ? ` · Platz ${selectedPitch}` : ""}`,
      `Gäste: ${adults} Erwachsene, ${kids} Kinder${pets ? `, ${pets} Hund${pets>1?"e":""}` : ""}`,
      "",
      `Extras:${extraLines.length ? "\n" + extraLines.join("\n") : " keine"}`,
      "",
      `Zwischensumme: € ${subtotal}`,
      "",
      `Kontakt:`,
      `Name: ${name}`,
      `E-Mail: ${email}`,
      `Telefon: ${phone}`,
      message ? `Nachricht: ${message}` : "",
    ].filter(Boolean).join("\n");
    const subject = `Buchungsanfrage Seecamping Langau · ${fmt(arrival)} – ${fmt(departure)}`;
    window.location.href = `mailto:office@allram.co.at?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(lines)}`;
    setSubmitted(true);
  };

  if (submitted) {
    return (
      <div className="modal-backdrop" role="dialog" aria-modal="true" aria-label={t.booking.successTitle} onClick={(e) => e.target === e.currentTarget && onClose()}>
        <div className="sheet sheet-success" style={{ position: "relative" }}>
          <button className="modal-close unstyled" onClick={onClose} aria-label={t.a11y.close}>
            <Icon.close width="14" height="14"/>
          </button>
          <main className="modal-main">
            <div className="booking-success">
              <div className="check" aria-hidden="true">✓</div>
              <h3>{t.booking.successTitle}</h3>
              <p>{t.booking.successBody}</p>
              <button className="btn btn-primary" onClick={onClose} style={{ marginTop: 8 }}>{t.legal?.close || "OK"}</button>
            </div>
          </main>
        </div>
      </div>
    );
  }

  return (
    <div className="modal-backdrop" role="dialog" aria-modal="true" aria-label={t.booking.title} onClick={(e) => e.target === e.currentTarget && onClose()}>
      <div className="sheet" style={{ position: "relative" }}>
        <button className="modal-close unstyled" onClick={onClose} aria-label={t.a11y.close}>
          <Icon.close width="14" height="14"/>
        </button>
        <header className="modal-bar">
          <div className="title">{t.booking.title}</div>
          <nav className="modal-steps" aria-label={t.booking.title}>
            {steps.map((s, i) => (
              <button
                key={i}
                className={`modal-step unstyled ${i === step ? "active" : ""} ${i < step ? "done" : ""}`}
                onClick={() => i < step && setStep(i)}
                aria-current={i === step ? "step" : undefined}>
                <span className="s-num">{String(i+1).padStart(2,"0")}</span>
                <span className="s-label">{s}</span>
              </button>
            ))}
          </nav>
        </header>
        <main className="modal-main">
          {step === 0 && <StepDates t={t} {...{arrival,setArrival,departure,setDeparture,adults,setAdults,kids,setKids,pets,setPets,nights}}/>}
          {step === 1 && <StepMap t={t} lang={lang} selectedPitch={selectedPitch} setSelectedPitch={setSelectedPitch} selectedType={selectedType} setSelectedType={setSelectedType}/>}
          {step === 2 && <StepExtras t={t} extras={extras} setExtras={setExtras} nights={nights} guests={adults+kids}/>}
          {step === 3 && <StepConfirm t={t} lang={lang} {...{arrival,departure,adults,kids,pets,nights,selectedPitch,selectedType,extras,subtotal,basePrice,extrasTotal,name,setName,email,setEmail,phone,setPhone,message,setMessage,consent,setConsent,errors,onLegal}}/>}
        </main>
        <footer className="modal-foot">
          <div className="modal-summary" aria-live="polite">
            <span className="sum-item"><span className="k">{t.booking.nightsLabel}</span><span className="v">{nights}</span></span>
            <span className="sum-sep" aria-hidden="true">·</span>
            <span className="sum-item"><span className="k">{t.booking.guestsLabel}</span><span className="v">{adults + kids}{pets ? ` · ${pets} 🐕` : ""}</span></span>
            {selectedPitch && <><span className="sum-sep" aria-hidden="true">·</span><span className="sum-item"><span className="k">Platz</span><span className="v">{selectedPitch}</span></span></>}
            <span className="sum-total"><span className="k">{t.booking.totalLabel}</span><span className="v">€ {subtotal}</span></span>
          </div>
          <div className="modal-actions">
            <button className="btn btn-ghost" onClick={() => step === 0 ? onClose() : setStep(step-1)}>
              {step === 0 ? t.a11y.close : t.booking.back}
            </button>
            {step < 3 ? (
              <button className="btn btn-primary btn-arrow" onClick={() => setStep(step+1)}>{t.booking.next}</button>
            ) : (
              <button className="btn btn-primary btn-arrow" onClick={handleSubmit}>{t.booking.submit}</button>
            )}
          </div>
        </footer>
      </div>
    </div>
  );
}

function Counter({ label, value, setValue, min = 0, max = 10 }) {
  return (
    <div>
      <label style={{ fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--fg-3)", display: "block", marginBottom: 6 }}>{label}</label>
      <div className="counter">
        <button className="cnt-btn unstyled" onClick={() => setValue(Math.max(min, value-1))}>−</button>
        <span className="cnt-val">{value}</span>
        <button className="cnt-btn unstyled" onClick={() => setValue(Math.min(max, value+1))}>+</button>
      </div>
    </div>
  );
}

function StepDates({ t, arrival, setArrival, departure, setDeparture, adults, setAdults, kids, setKids, pets, setPets, nights }) {
  const today = new Date().toISOString().slice(0, 10);
  const minDeparture = (() => {
    const a = new Date(arrival);
    a.setDate(a.getDate() + 1);
    return a.toISOString().slice(0, 10);
  })();
  const onArrivalChange = (val) => {
    setArrival(val);
    if (val >= departure) {
      const d = new Date(val); d.setDate(d.getDate() + 1);
      setDeparture(d.toISOString().slice(0, 10));
    }
  };
  return (
    <>
      <div className="step-head">
        <h3>{t.booking.step1}</h3>
        <div className="meta">{nights} {nights === 1 ? "Nacht" : "Nächte"}</div>
      </div>
      <div className="fields-grid">
        <div className="field">
          <label htmlFor="bk-arrival">{t.booking.arrival}</label>
          <input id="bk-arrival" type="date" min={today} value={arrival} onChange={e => onArrivalChange(e.target.value)}/>
        </div>
        <div className="field">
          <label htmlFor="bk-departure">{t.booking.departure}</label>
          <input id="bk-departure" type="date" min={minDeparture} value={departure} onChange={e => setDeparture(e.target.value)}/>
        </div>
        <Counter label={t.booking.adults} value={adults} setValue={setAdults} min={1}/>
        <Counter label={t.booking.kids} value={kids} setValue={setKids}/>
        <Counter label={t.booking.pets} value={pets} setValue={setPets} max={3}/>
      </div>
      <div style={{ marginTop: 32, padding: 20, background: "var(--bg-2)", display: "flex", gap: 16, alignItems: "flex-start" }}>
        <div style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 20, lineHeight: 1.3, flex: 1 }}>
          „Am schönsten ist es Anfang Juli — das Wasser ist warm, die Abende lang, der Platz noch nicht voll."
        </div>
        <div style={{ fontFamily: "var(--mono)", fontSize: 10.5, letterSpacing: "0.12em", color: "var(--fg-3)", whiteSpace: "nowrap", paddingTop: 6 }}>
          — Fam. Allram
        </div>
      </div>
    </>
  );
}

function StepMap({ t, lang, selectedPitch, setSelectedPitch, selectedType, setSelectedType }) {
  const [hover, setHover] = useS(null);
  const pitches = useM(() => generatePitches(), []);
  const typeItems = window.COPY[lang].places.items;
  const typeColor = (type) => ({
    stellplatz: "#7a9464", zelt: "#3c6a6a", chalet: "#b58a48", safari: "#a65a2a", seehuette: "#5c4f3a"
  }[type]);
  return (
    <>
      <div className="step-head">
        <h3>{t.booking.step2}</h3>
        <div className="meta">{selectedPitch ? `${selectedPitch} ausgewählt` : t.booking.pickPlace}</div>
      </div>
      <div style={{ display: "flex", gap: 14, marginBottom: 14, flexWrap: "wrap" }}>
        {typeItems.map(ti => (
          <button key={ti.id}
            onClick={() => setSelectedType(ti.id)}
            className="unstyled"
            style={{
              padding: "8px 14px",
              border: "1px solid var(--line)",
              borderRadius: 99,
              fontSize: 12.5,
              fontFamily: "var(--sans)",
              background: selectedType === ti.id ? "var(--forest)" : "transparent",
              color: selectedType === ti.id ? "var(--paper)" : "var(--fg)",
              display: "inline-flex", alignItems: "center", gap: 8,
            }}>
            <span style={{ width: 8, height: 8, borderRadius: "50%", background: typeColor(ti.id), display: "inline-block" }}/>
            {ti.name} <span style={{ opacity: 0.6, marginLeft: 4 }}>{ti.price}</span>
          </button>
        ))}
      </div>
      <div className="map-wrap" style={{ position: "relative" }}>
        <CampMap pitches={pitches} selectedType={selectedType} selectedPitch={selectedPitch} setSelectedPitch={setSelectedPitch} hover={hover} setHover={setHover} typeColor={typeColor}/>
        {hover && (
          <div className="map-tooltip" style={{ left: hover.tx, top: hover.ty }}>
            <div className="code">Platz {hover.id}</div>
            <div className="name">{typeItems.find(i => i.id === hover.type)?.name}</div>
            <div style={{ fontSize: 11, opacity: 0.7, marginTop: 2 }}>{typeItems.find(i => i.id === hover.type)?.price}</div>
          </div>
        )}
        <div className="map-legend">
          {typeItems.map(ti => (
            <span className="swatch" key={ti.id}>
              <span className="sw" style={{ background: typeColor(ti.id) }}/>
              {ti.name}
            </span>
          ))}
        </div>
      </div>
    </>
  );
}

function generatePitches() {
  const arr = [];
  // Stellplätze: 3 Reihen à 10 im Osten
  for (let r = 0; r < 3; r++) {
    for (let c = 0; c < 10; c++) {
      arr.push({
        id: `A${String(r*10+c+1).padStart(2,"0")}`,
        type: "stellplatz",
        x: 560 + c * 32, y: 140 + r * 44,
        taken: Math.random() < 0.32,
      });
    }
  }
  // Zeltplätze: Cluster im Norden
  for (let i = 0; i < 14; i++) {
    arr.push({
      id: `B${String(i+1).padStart(2,"0")}`,
      type: "zelt",
      x: 240 + (i % 7) * 36 + (i > 6 ? 10 : 0),
      y: 80 + Math.floor(i / 7) * 36,
      taken: Math.random() < 0.2,
    });
  }
  // Chalets: 4 im Südosten
  for (let i = 0; i < 4; i++) {
    arr.push({
      id: `C0${i+1}`, type: "chalet",
      x: 680 + i * 42, y: 340,
      taken: Math.random() < 0.5,
    });
  }
  // Safari: 3 am Waldrand
  for (let i = 0; i < 3; i++) {
    arr.push({
      id: `D0${i+1}`, type: "safari",
      x: 160 + i * 48, y: 340,
      taken: Math.random() < 0.4,
    });
  }
  // Seehütte
  arr.push({ id: "E01", type: "seehuette", x: 360, y: 280, taken: false });
  arr.push({ id: "E02", type: "seehuette", x: 420, y: 260, taken: true });
  return arr;
}

function CampMap({ pitches, selectedType, selectedPitch, setSelectedPitch, hover, setHover, typeColor }) {
  const wrapRef = useR(null);
  return (
    <svg className="map-svg" viewBox="0 0 900 440" preserveAspectRatio="xMidYMid meet" ref={wrapRef}>
      {/* Forest */}
      <rect x="0" y="0" width="900" height="440" fill="#c5cdb4"/>
      <path d="M0,0 L900,0 L900,60 Q700,50 500,75 Q300,95 100,70 L0,80 Z" fill="#8ca07a" opacity="0.6"/>
      <path d="M0,360 Q200,380 450,370 Q700,355 900,380 L900,440 L0,440 Z" fill="#8ca07a" opacity="0.6"/>
      {/* Lake */}
      <path d="M60,140 Q80,100 220,110 Q420,90 520,130 Q540,210 480,280 Q360,340 200,310 Q80,280 60,220 Z" fill="#7ba0a8" />
      <path d="M60,140 Q80,100 220,110 Q420,90 520,130 Q540,210 480,280 Q360,340 200,310 Q80,280 60,220 Z" fill="none" stroke="#5a8088" strokeWidth="1" strokeDasharray="3 4"/>
      <text x="260" y="210" fontFamily="JetBrains Mono" fontSize="9" letterSpacing="3" fill="#fff" opacity="0.7" textAnchor="middle">BERGWERKSEE</text>
      <text x="260" y="224" fontFamily="JetBrains Mono" fontSize="7" letterSpacing="3" fill="#fff" opacity="0.6" textAnchor="middle">48 HA · 21 M TIEF</text>

      {/* Dock */}
      <rect x="340" y="228" width="36" height="4" fill="#8a6a42"/>
      <rect x="356" y="232" width="4" height="28" fill="#8a6a42"/>
      {/* Beach */}
      <path d="M360,280 Q450,295 500,285" stroke="#d4c68a" strokeWidth="6" fill="none" opacity="0.9"/>

      {/* Roads */}
      <path d="M870,440 L870,120 L800,120 L720,160 L560,180" stroke="#e8e3d5" strokeWidth="7" fill="none"/>
      <path d="M720,160 L720,340" stroke="#e8e3d5" strokeWidth="5" fill="none"/>
      <path d="M560,180 L560,280" stroke="#e8e3d5" strokeWidth="5" fill="none"/>

      {/* Buildings */}
      <g>
        <rect x="790" y="110" width="40" height="20" fill="#4a3c2a" rx="1"/>
        <text x="810" y="106" fontFamily="JetBrains Mono" fontSize="7" letterSpacing="1.5" fill="#2a2a20" textAnchor="middle">REZEPTION</text>
        <rect x="680" y="200" width="28" height="18" fill="#4a3c2a" rx="1"/>
        <text x="694" y="196" fontFamily="JetBrains Mono" fontSize="6" letterSpacing="1" fill="#2a2a20" textAnchor="middle">SANITÄR</text>
        <rect x="300" y="260" width="32" height="22" fill="#5c4a30" rx="1"/>
        <text x="316" y="256" fontFamily="JetBrains Mono" fontSize="6" letterSpacing="1" fill="#2a2a20" textAnchor="middle">FREIZEITHAUS</text>
      </g>

      {/* Pitches */}
      {pitches.map(p => {
        const isSelected = selectedPitch === p.id;
        const isType = p.type === selectedType;
        const isRect = p.type === "chalet" || p.type === "safari" || p.type === "seehuette";
        return (
          <g key={p.id}
            className={`pitch ${p.taken ? "taken" : ""} ${isSelected ? "selected" : ""}`}
            onClick={() => !p.taken && isType && setSelectedPitch(p.id)}
            onMouseEnter={(e) => {
              if (p.taken || !isType) return;
              const svg = wrapRef.current; if (!svg) return;
              const rect = svg.getBoundingClientRect();
              const parentRect = svg.parentElement.getBoundingClientRect();
              const scale = rect.width / 900;
              setHover({ ...p, tx: p.x * scale + (rect.left - parentRect.left), ty: p.y * scale + (rect.top - parentRect.top) });
            }}
            onMouseLeave={() => setHover(null)}
            style={{ pointerEvents: isType ? "auto" : "none", opacity: isType ? 1 : 0.25 }}
          >
            {isRect ? (
              <rect x={p.x-10} y={p.y-8} width="20" height="16" rx="2" fill={typeColor(p.type)}/>
            ) : (
              <circle cx={p.x} cy={p.y} r={p.type === "zelt" ? 6 : 8} fill={typeColor(p.type)}/>
            )}
            {isType && !p.taken && <text x={p.x} y={p.y+2.5} fontFamily="JetBrains Mono" fontSize="6" fill="#fff" textAnchor="middle" style={{ pointerEvents: "none" }}>{p.id.slice(1)}</text>}
          </g>
        );
      })}
    </svg>
  );
}

function StepExtras({ t, extras, setExtras, nights, guests }) {
  const toggle = (id) => setExtras({ ...extras, [id]: !extras[id] });
  return (
    <>
      <div className="step-head">
        <h3>{t.booking.extrasTitle}</h3>
        <div className="meta">{Object.values(extras).filter(Boolean).length} / {t.booking.extras.length}</div>
      </div>
      <div className="extras-list">
        {t.booking.extras.map(e => (
          <button key={e.id} className={`extra-item unstyled ${extras[e.id] ? "on" : ""}`} onClick={() => toggle(e.id)}>
            <span className="extra-check"/>
            <span className="extra-label">{e.label}</span>
            <span className="extra-per">{e.per}</span>
            <span className="extra-price">€ {e.price}</span>
          </button>
        ))}
      </div>
    </>
  );
}

function StepConfirm({ t, lang, arrival, departure, adults, kids, pets, nights, selectedPitch, selectedType, extras, subtotal, basePrice, extrasTotal, name, setName, email, setEmail, phone, setPhone, message, setMessage, consent, setConsent, errors, onLegal }) {
  const typeName = window.COPY[lang].places.items.find(i => i.id === selectedType)?.name;
  const fmt = (d) => new Date(d).toLocaleDateString(lang === "de" ? "de-AT" : "en-GB", { day: "2-digit", month: "short", year: "numeric" });
  return (
    <>
      <div className="step-head">
        <h3>{t.booking.confirmTitle}</h3>
        <div className="meta">{nights} × {typeName}</div>
      </div>
      <div className="step-confirm-grid">
        <div className="confirm-form">
          <p className="confirm-intro">{t.booking.confirmBody}</p>
          <div className="required-hint" aria-live="polite">{t.booking.requiredHint}</div>
          <div className="fields-grid confirm-fields">
            <div className="field">
              <label htmlFor="bk-name">{lang === "de" ? "Name" : "Name"} <span aria-hidden="true">*</span><span className="sr-only">{lang === "de" ? " (Pflichtfeld)" : " (required)"}</span></label>
              <input id="bk-name" type="text"
                placeholder={lang === "de" ? "Max Mustermann" : "Jane Doe"}
                value={name} onChange={e => setName(e.target.value)}
                className={errors.name ? "invalid" : ""}
                required autoComplete="name"
                aria-invalid={!!errors.name}
                aria-describedby={errors.name ? "bk-name-err" : undefined}/>
              {errors.name && <div id="bk-name-err" className="field-error" role="alert">{errors.name}</div>}
            </div>
            <div className="field">
              <label htmlFor="bk-email">{lang === "de" ? "E-Mail" : "Email"} <span aria-hidden="true">*</span><span className="sr-only">{lang === "de" ? " (Pflichtfeld)" : " (required)"}</span></label>
              <input id="bk-email" type="email"
                placeholder={lang === "de" ? "name@beispiel.at" : "name@example.com"}
                value={email} onChange={e => setEmail(e.target.value)}
                className={errors.email ? "invalid" : ""}
                required autoComplete="email"
                aria-invalid={!!errors.email}
                aria-describedby={errors.email ? "bk-email-err" : undefined}/>
              {errors.email && <div id="bk-email-err" className="field-error" role="alert">{errors.email}</div>}
            </div>
            <div className="field">
              <label htmlFor="bk-phone">{lang === "de" ? "Telefon" : "Phone"} <span aria-hidden="true">*</span><span className="sr-only">{lang === "de" ? " (Pflichtfeld)" : " (required)"}</span></label>
              <input id="bk-phone" type="tel"
                placeholder="+43 …" value={phone} onChange={e => setPhone(e.target.value)}
                className={errors.phone ? "invalid" : ""}
                required autoComplete="tel"
                aria-invalid={!!errors.phone}
                aria-describedby={errors.phone ? "bk-phone-err" : undefined}/>
              {errors.phone && <div id="bk-phone-err" className="field-error" role="alert">{errors.phone}</div>}
            </div>
            <div className="field">
              <label htmlFor="bk-msg">{lang === "de" ? "Nachricht (optional)" : "Message (optional)"}</label>
              <input id="bk-msg" type="text" placeholder={lang === "de" ? "Besondere Wünsche?" : "Anything special?"} value={message} onChange={e => setMessage(e.target.value)}/>
            </div>
          </div>
          <div className={`consent-row ${errors.consent ? "invalid" : ""}`}>
            <input type="checkbox" id="bk-consent" checked={consent} onChange={e => setConsent(e.target.checked)} aria-invalid={!!errors.consent}/>
            <label htmlFor="bk-consent">
              {t.booking.consent.split("Datenschutzerklärung").map((part, i, arr) => (
                <React.Fragment key={i}>
                  {part}
                  {i < arr.length - 1 && (
                    <button type="button" className="link" onClick={(e) => { e.preventDefault(); onLegal && onLegal("datenschutz"); }}>
                      {lang === "de" ? "Datenschutzerklärung" : "privacy policy"}
                    </button>
                  )}
                </React.Fragment>
              ))}
              {errors.consent && <div className="field-error" role="alert" style={{ marginTop: 6 }}>{errors.consent}</div>}
            </label>
          </div>
        </div>
        <aside className="confirm-summary" aria-label={t.booking.totalLabel}>
          <div className="confirm-box">
            <div className="row-line"><span className="k">{t.booking.arrival}</span><span className="v">{fmt(arrival)}</span></div>
            <div className="row-line"><span className="k">{t.booking.departure}</span><span className="v">{fmt(departure)}</span></div>
            <div className="row-line"><span className="k">{lang === "de" ? "Unterkunft" : "Stay"}</span><span className="v">{typeName}{selectedPitch ? ` · ${lang === "de" ? "Platz" : "Pitch"} ${selectedPitch}` : ""}</span></div>
            <div className="row-line"><span className="k">{lang === "de" ? "Gäste" : "Guests"}</span><span className="v">{adults} + {kids}{pets ? `, ${pets} ${lang === "de" ? `Hund${pets>1?"e":""}` : `dog${pets>1?"s":""}`}`:""}</span></div>
            <div className="row-line"><span className="k">{lang === "de" ? "Grundpreis" : "Base"} · {nights} × €{basePrice}</span><span className="v">€ {basePrice*nights}</span></div>
            {extrasTotal > 0 && <div className="row-line"><span className="k">{lang === "de" ? "Extras" : "Extras"}</span><span className="v">€ {extrasTotal}</span></div>}
            {pets > 0 && <div className="row-line"><span className="k">{lang === "de" ? "Hunde" : "Dogs"} · {pets} × €4 × {nights}</span><span className="v">€ {pets*4*nights}</span></div>}
            <div className="big-total">
              <span className="label">{t.booking.totalLabel}</span>
              <span className="val">€ {subtotal}</span>
            </div>
          </div>
        </aside>
      </div>
    </>
  );
}

Object.assign(window, { BookingModal });
