/* BoatsFun — Faire une offre (Phase 3).
   Catégorie → Date → Prix → Contact.
   Dépôt = 25 % du total 4h. Toujours "plus taxes".
   Speedboat : prix sur demande.
*/

(function () {
  const { useState, useMemo } = React;

  const NAVY   = "#002244";
  const TEAL   = "#00B5E2";
  const ORANGE = "#FF8200";
  const MIST   = "#F0F8FF";

  // ─────────────────────────────────────────────
  // DATA — catégories & options de prix
  // ─────────────────────────────────────────────
  const CATEGORIES = [
    {
      id: "speedboat",
      label: "Speedboat",
      icon: "⚡",
      desc: "Sortie rapide et excitante pour petits groupes en quête de sensations.",
      image: "assets/boats/categories/category-speedboat.png",
      // Pas d'options de prix — prix sur demande
    },
    {
      id: "ponton",
      label: "Ponton",
      icon: "⛵",
      desc: "Stabilité et espace. Idéal pour familles et grands groupes.",
      image: "assets/boats/categories/category-ponton.png",
      weekday: [
        { priceH: 140, label: "Très bonne chance" },
        { priceH: 130, label: "Bonne chance"       },
        { priceH: 125, label: "Chance moyenne"     },
        { priceH: 120, label: "Offre agressive"    },
      ],
      weekend: [
        { priceH: 170, label: "Très bonne chance" },
        { priceH: 160, label: "Bonne chance"       },
        { priceH: 150, label: "Chance moyenne"     },
        { priceH: 140, label: "Offre agressive"    },
      ],
    },
    {
      id: "cruiser",
      label: "Cruiser",
      icon: "🚤",
      desc: "Polyvalent et confortable pour une sortie en groupe.",
      image: "assets/boats/categories/category-cruiser.png",
      options: [
        { priceH: 360, label: "Bonne chance"    },
        { priceH: 345, label: "Chance correcte" },
        { priceH: 330, label: "Chance moyenne"  },
        { priceH: 320, label: "Offre agressive" },
      ],
    },
    {
      id: "yacht",
      label: "Yacht",
      icon: "🛥️",
      desc: "Expérience premium. Espace et équipements haut de gamme.",
      image: "assets/boats/categories/category-yacht.png",
      options: [
        { priceH: 450, label: "Très bonne chance" },
        { priceH: 440, label: "Bonne chance"       },
        { priceH: 430, label: "Chance moyenne"     },
        { priceH: 425, label: "Offre limite"       },
      ],
    },
  ];

  const TIME_SLOTS = ["Matin : 9h à 13h", "Après-midi : 14h à 18h", "Soir : 19h à 23h"];

  // ─────────────────────────────────────────────
  // HELPERS
  // ─────────────────────────────────────────────
  function todayISO() {
    const d = new Date();
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
  }

  function isWeekendDate(iso) {
    if (!iso) return false;
    const day = new Date(iso + "T00:00:00").getDay();
    return day === 5 || day === 6 || day === 0; // ven/sam/dim
  }

  // Retourne un tableau d'options, ou null (speedboat = prix sur demande)
  function getPriceOptions(cat, date) {
    if (!cat || cat.id === "speedboat") return null;
    if (cat.id === "ponton") return isWeekendDate(date) ? cat.weekend : cat.weekday;
    return cat.options || null;
  }

  // ─────────────────────────────────────────────
  // CSS
  // ─────────────────────────────────────────────
  const styles = `
.bf .offer-page { padding-block: clamp(24px, 4vw, 48px) clamp(56px, 7vw, 96px); }
.bf .offer-back { display:inline-flex; align-items:center; gap:8px; color:${NAVY}; opacity:.7; font-weight:500; font-size:14px; text-decoration:none; margin-bottom:20px; }
.bf .offer-back:hover { opacity:1; }

.bf .offer-head { max-width:720px; margin-bottom:32px; }
.bf .offer-eyebrow { display:inline-block; background:${MIST}; color:${TEAL}; font-weight:700; font-size:12px; letter-spacing:.08em; text-transform:uppercase; padding:6px 12px; border-radius:999px; margin-bottom:14px; }
.bf .offer-head h1 { font-family:'Poppins',sans-serif; color:${NAVY}; font-size:clamp(28px,3.6vw,40px); margin:0 0 10px; line-height:1.15; }
.bf .offer-head p { color:${NAVY}; opacity:.8; font-size:15px; line-height:1.6; margin:0; }

.bf .offer-grid { display:grid; grid-template-columns:minmax(0,1fr) 360px; gap:40px; align-items:start; }

/* Left column — carousel + form card empilés */
.bf .offer-main-col { display:flex; flex-direction:column; gap:24px; min-width:0; }

/* Carousel section header (hors carte blanche) */
.bf .offer-carousel-section { display:flex; flex-direction:column; }
.bf .offer-carousel-section .offer-step-label { margin-bottom:6px; }
.bf .offer-carousel-section .offer-step-sub { margin-bottom:12px; }

/* Form card */
.bf .offer-card { background:#fff; border:1px solid rgba(0,34,68,.08); border-radius:20px; padding:28px; box-shadow:0 8px 24px rgba(0,34,68,.06); }

/* Steps */
.bf .offer-step { margin-bottom:28px; padding-bottom:28px; border-bottom:1px solid rgba(0,34,68,.07); }
.bf .offer-step:last-of-type { border-bottom:none; margin-bottom:0; padding-bottom:0; }
.bf .offer-step-label { font-family:'Poppins',sans-serif; font-weight:700; color:${NAVY}; font-size:15px; margin-bottom:6px; letter-spacing:-.2px; }
.bf .offer-step-sub { font-size:13px; color:${TEAL}; margin-bottom:14px; display:block; }
.bf .offer-step-day { font-weight:400; font-size:13px; color:${TEAL}; }

/* ── Carousel hero ── */
.bf .offer-carousel { border-radius:20px; overflow:hidden; box-shadow:0 8px 32px rgba(0,34,68,.16); }

/* Zone image : bateau centré, respire, fond navy */
.bf .offer-hero-img-wrap {
  position:relative; height:300px;
  background:#001535;
  display:flex; align-items:center; justify-content:center;
  overflow:hidden;
}
.bf .offer-hero-img {
  max-width: calc(100% - 80px);
  max-height: calc(100% - 24px);
  width:auto; height:auto;
  object-fit:contain;
  display:block;
}

/* Zone info : séparée, fond navy foncé, texte blanc */
.bf .offer-hero-info {
  background:#002244;
  padding:14px 20px;
  display:flex; align-items:center; justify-content:space-between; gap:14px;
}
.bf .offer-hero-text { flex:1; min-width:0; }
.bf .offer-hero-name { font-family:'Poppins',sans-serif; font-size:17px; font-weight:800; color:#fff; margin:0 0 2px; line-height:1.2; }
.bf .offer-hero-desc { font-size:12px; color:rgba(255,255,255,.72); margin:0; line-height:1.4; }
.bf .offer-hero-cta {
  flex-shrink:0; padding:10px 22px;
  background:${ORANGE}; color:#fff;
  font-weight:700; font-size:13px;
  border:none; border-radius:999px; cursor:pointer;
  transition:filter .15s, transform .15s; white-space:nowrap;
}
.bf .offer-hero-cta:hover { filter:brightness(1.08); transform:translateY(-1px); }
.bf .offer-hero-cta.is-selected { background:${TEAL}; }

/* Flèches sur la zone image */
.bf .offer-arrow {
  position:absolute; top:50%; transform:translateY(-50%);
  width:38px; height:38px; border:none; border-radius:50%;
  background:rgba(0,0,0,.42); color:#fff; font-size:20px;
  display:flex; align-items:center; justify-content:center;
  cursor:pointer; transition:background .15s; z-index:2; line-height:1;
}
.bf .offer-arrow:hover { background:rgba(0,0,0,.68); }
.bf .offer-prev { left:12px; }
.bf .offer-next { right:12px; }

/* Miniatures */
.bf .offer-thumbs { display:flex; justify-content:center; gap:14px; margin:16px 20px 14px; }
.bf .offer-thumb {
  flex:0 0 auto; width:104px; border-radius:12px; overflow:hidden;
  border:2.5px solid transparent; background:#001535; cursor:pointer;
  box-shadow:0 4px 12px rgba(0,34,68,.12); padding:0;
  transition:border-color .2s, box-shadow .2s, transform .15s; display:flex; flex-direction:column;
}
.bf .offer-thumb:hover { transform:translateY(-2px); }
.bf .offer-thumb.is-active { border-color:${ORANGE}; box-shadow:0 6px 20px rgba(255,130,0,.3); }
.bf .offer-thumb-img {
  width:100%; height:66px;
  object-fit:contain; background:#001535;
  display:block; padding:6px; box-sizing:border-box;
}
.bf .offer-thumb-label { font-size:11px; font-weight:700; color:${NAVY}; text-align:center; padding:4px 4px; background:${MIST}; }

@media (max-width:1060px) {
  .bf .offer-hero-img-wrap { height:260px; }
  .bf .offer-hero-name { font-size:16px; }
}
@media (max-width:860px) {
  .bf .offer-hero-img-wrap { height:230px; }
  .bf .offer-thumbs { gap:10px; margin:14px 14px 10px; }
  .bf .offer-thumb { width:88px; }
  .bf .offer-thumb-img { height:56px; }
}
@media (max-width:640px) {
  .bf .offer-hero-img-wrap { height:190px; }
  .bf .offer-hero-info { flex-direction:column; align-items:flex-start; gap:10px; }
  .bf .offer-hero-cta { padding:8px 18px; }
  .bf .offer-thumbs { gap:8px; margin:12px 10px 8px; }
  .bf .offer-thumb { width:72px; }
  .bf .offer-thumb-img { height:46px; }
  .bf .offer-thumb-label { font-size:10px; }
}

/* Price section — intro, note, notice */
.bf .oprice-intro { font-size:14px; font-weight:700; color:${NAVY}; margin:0 0 6px; }
.bf .oprice-note { font-size:13px; color:${NAVY}; opacity:.72; line-height:1.55; margin:0 0 12px; }
.bf .oprice-notice {
  background:rgba(0,181,226,.07); border:1.5px solid rgba(0,181,226,.2);
  border-radius:12px; padding:12px 14px;
  font-size:12.5px; color:${NAVY}; line-height:1.6;
  margin-bottom:16px;
}

/* Form fields */
.bf .offer-field { margin-bottom:16px; }
.bf .offer-field label { display:block; font-size:13px; font-weight:600; color:${NAVY}; margin-bottom:6px; }
.bf .offer-field .req { color:${ORANGE}; }
.bf .offer-input, .bf .offer-select {
  width:100%; box-sizing:border-box; min-height:48px; padding:0 14px;
  border:1.5px solid rgba(0,34,68,.12); border-radius:12px;
  font-family:'Inter',sans-serif; font-size:15px; color:${NAVY}; background:#fff;
  transition:border-color .15s, box-shadow .15s;
}
.bf .offer-input:focus, .bf .offer-select:focus {
  outline:none; border-color:${TEAL}; box-shadow:0 0 0 3px rgba(0,181,226,.18);
}
.bf .offer-input.has-error, .bf .offer-select.has-error { border-color:#d33; }
.bf .offer-error { color:#d33; font-size:12px; margin-top:6px; }
.bf .offer-hint { color:${NAVY}; opacity:.6; font-size:12px; margin-top:6px; }
.bf .offer-row { display:grid; grid-template-columns:1fr 1fr; gap:14px; }

/* Price option cards */
.bf .oprice-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:12px; }
.bf .oprice-card {
  background:#fff; border:1.5px solid rgba(0,34,68,.1); border-radius:14px;
  padding:16px 14px; cursor:pointer; text-align:left;
  transition:border-color .2s, background .2s, box-shadow .2s;
  width:100%; box-sizing:border-box;
}
.bf .oprice-card:hover { border-color:${TEAL}; box-shadow:0 4px 14px rgba(0,181,226,.1); }
.bf .oprice-card.is-active { border-color:${ORANGE}; background:rgba(255,130,0,.04); }
.bf .oprice-top { display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:10px; gap:6px; }
.bf .oprice-ph { font-family:'Poppins',sans-serif; font-size:22px; font-weight:800; color:${NAVY}; white-space:nowrap; }
.bf .oprice-ph small { font-size:13px; font-weight:400; opacity:.65; }
.bf .oprice-savings { font-size:11px; font-weight:700; color:#1a8f4a; background:rgba(26,143,74,.1); padding:3px 8px; border-radius:999px; white-space:nowrap; flex-shrink:0; margin-top:4px; }
.bf .oprice-rows { margin-bottom:10px; }
.bf .oprice-row { display:flex; justify-content:space-between; font-size:13px; color:${NAVY}; opacity:.8; padding:2px 0; }
.bf .oprice-row b { font-weight:700; opacity:1; }
.bf .oprice-label { font-size:11.5px; font-weight:700; color:${NAVY}; background:${MIST}; display:inline-block; padding:4px 10px; border-radius:999px; margin-bottom:10px; }
.bf .oprice-cta { width:100%; min-height:36px; background:${NAVY}; color:#fff; border-radius:9px; font-weight:700; font-size:13px; display:flex; align-items:center; justify-content:center; transition:background .15s; }
.bf .oprice-card.is-active .oprice-cta { background:${ORANGE}; }
.bf .oprice-placeholder { color:${NAVY}; opacity:.45; font-size:14px; padding:20px 0; font-style:italic; }

/* Speedboat — sur demande */
.bf .oprice-onrequest { background:${MIST}; border:1.5px solid rgba(0,181,226,.22); border-radius:16px; padding:24px 20px; text-align:center; }
.bf .oprice-onrequest-icon { font-size:30px; margin-bottom:10px; }
.bf .oprice-onrequest-title { font-family:'Poppins',sans-serif; font-size:15px; font-weight:700; color:${NAVY}; margin-bottom:8px; }
.bf .oprice-onrequest-sub { font-size:13px; color:${NAVY}; opacity:.7; line-height:1.55; }

/* Sidebar summary */
.bf .offer-summary { background:#fff; border:1px solid rgba(0,34,68,.08); border-radius:18px; padding:20px 22px; }
.bf .offer-summary h3 { font-family:'Poppins',sans-serif; color:${NAVY}; font-size:17px; margin:0 0 12px; }
.bf .offer-sumrow { display:flex; justify-content:space-between; padding:7px 0; border-bottom:1px dashed rgba(0,34,68,.08); font-size:14px; color:${NAVY}; }
.bf .offer-sumrow:last-child { border-bottom:none; }
.bf .offer-sumrow b { font-weight:700; }
.bf .offer-sumrow.is-big { font-family:'Poppins',sans-serif; font-size:16px; font-weight:700; }
.bf .offer-sumrow.is-big b { color:${ORANGE}; }

/* Submit */
.bf .offer-submit { width:100%; min-height:54px; background:${ORANGE}; color:#fff; border:0; border-radius:14px; font-weight:700; font-size:16px; cursor:pointer; box-shadow:0 8px 20px rgba(255,130,0,.28); transition:transform .15s, box-shadow .15s; margin-top:8px; }
.bf .offer-submit:hover { transform:translateY(-1px); box-shadow:0 12px 26px rgba(255,130,0,.36); }
.bf .offer-submit:disabled { opacity:.5; cursor:not-allowed; transform:none; box-shadow:none; }

/* Sidebar */
.bf .offer-aside { position:sticky; top:96px; display:flex; flex-direction:column; gap:16px; }
.bf .offer-info { background:${NAVY}; color:#fff; border-radius:18px; padding:22px; }
.bf .offer-info h3 { font-family:'Poppins',sans-serif; margin:0 0 12px; font-size:18px; }
.bf .offer-info ul { list-style:none; padding:0; margin:0; }
.bf .offer-info li { display:flex; gap:10px; padding:8px 0; font-size:14px; opacity:.92; line-height:1.5; }
.bf .offer-info li::before { content:""; flex-shrink:0; width:6px; height:6px; border-radius:50%; background:${TEAL}; margin-top:8px; }
.bf .offer-refund { background:#fff; border:1.5px solid ${ORANGE}; border-radius:18px; padding:20px; display:flex; gap:12px; align-items:flex-start; }
.bf .offer-refund .badge { background:${ORANGE}; color:#fff; font-size:11px; font-weight:800; letter-spacing:.06em; padding:5px 9px; border-radius:6px; flex-shrink:0; }
.bf .offer-refund p { margin:0; font-size:13px; color:${NAVY}; line-height:1.5; }
.bf .offer-refund p strong { font-weight:700; }

/* Responsive */
@media (max-width:1060px) {
  .bf .offer-grid { gap:28px; }
}
@media (max-width:860px) {
  .bf .offer-grid { grid-template-columns:1fr; gap:24px; }
  .bf .offer-aside { position:static; }
}
@media (max-width: 600px) {
  .bf .oprice-grid { grid-template-columns:1fr; }
}
@media (max-width: 500px) {
  .bf .offer-card { padding:20px; }
  .bf .offer-row { grid-template-columns:1fr; }
}
`;

  // ─────────────────────────────────────────────
  // COMPONENTS
  // ─────────────────────────────────────────────
  function PriceCard({ opt, selected, onSelect, maxPriceH }) {
    const total   = opt.priceH * 4;
    const deposit = Math.round(total * 0.25);
    const savings = (maxPriceH && maxPriceH > opt.priceH) ? (maxPriceH - opt.priceH) * 4 : 0;
    return (
      <button
        type="button"
        className={"oprice-card" + (selected ? " is-active" : "")}
        onClick={() => onSelect(opt.priceH)}
      >
        <div className="oprice-top">
          <span className="oprice-ph">{opt.priceH} $<small> /h</small></span>
          {savings > 0 && <span className="oprice-savings">Économisez {savings} $</span>}
        </div>
        <div className="oprice-rows">
          <div className="oprice-row"><span>Total 4h</span><b>{total.toLocaleString("fr-CA")} $</b></div>
          <div className="oprice-row"><span>Dépôt (25 %)</span><b>{deposit.toLocaleString("fr-CA")} $</b></div>
        </div>
        <div className="oprice-label">{opt.label}</div>
        <div className="oprice-cta">{selected ? "✓ Sélectionnée" : "Choisir cette offre"}</div>
      </button>
    );
  }

  // ─────────────────────────────────────────────
  // MAIN PAGE
  // ─────────────────────────────────────────────
  function BFPageOffer() {
    const [catId,         setCatId]         = useState(null);
    const [carouselIndex, setCarouselIndex] = useState(0);
    const category = useMemo(() => CATEGORIES.find(c => c.id === catId) || null, [catId]);

    const [form, setForm] = useState({
      date: "", slot: "", persons: "",
      priceH: null,
      name: "", email: "", phone: ""
    });
    const [errors,     setErrors]     = useState({});
    const [submitting, setSubmitting] = useState(false);

    const weekend      = useMemo(() => isWeekendDate(form.date), [form.date]);
    const priceOptions = useMemo(() => getPriceOptions(category, form.date), [category, form.date]);
    const maxPriceH    = useMemo(
      () => priceOptions ? Math.max(...priceOptions.map(o => o.priceH)) : 0,
      [priceOptions]
    );

    const total4h = form.priceH ? form.priceH * 4 : null;
    const deposit = total4h ? Math.round(total4h * 0.25) : null;

    const dayLabel = form.date
      ? (weekend ? "Weekend (ven – dim)" : "Semaine (lun – jeu)")
      : null;

    // Sélectionne une catégorie ET synchronise le carousel
    const handleCat = (id) => {
      setCatId(id);
      setCarouselIndex(CATEGORIES.findIndex(c => c.id === id));
      setForm(f => ({ ...f, priceH: null }));
      setErrors(e => ({ ...e, cat: null, price: null }));
    };

    const prevSlide = () => setCarouselIndex(i => (i + CATEGORIES.length - 1) % CATEGORIES.length);
    const nextSlide = () => setCarouselIndex(i => (i + 1) % CATEGORIES.length);

    const handleField = (key) => (e) => {
      const val = e.target.value;
      setForm(f => {
        const next = { ...f, [key]: val };
        if (key === "date") next.priceH = null;
        return next;
      });
      setErrors(e => ({ ...e, [key]: null }));
    };

    const handlePrice = (priceH) => {
      setForm(f => ({ ...f, priceH }));
      setErrors(e => ({ ...e, price: null }));
    };

    const validate = () => {
      const errs = {};
      if (!catId)            errs.cat     = "Choisissez une catégorie.";
      if (!form.date)        errs.date    = "Date requise.";
      if (!form.slot)        errs.slot    = "Choisissez une plage horaire.";
      if (!form.persons)     errs.persons = "Indiquez le nombre de personnes.";
      // Speedboat : pas de sélection de prix requise (sur demande)
      if (catId !== "speedboat" && !form.priceH) errs.price = "Choisissez une option de prix.";
      if (!form.name.trim()) errs.name    = "Nom requis.";
      if (!form.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email))
                             errs.email   = "Email invalide.";
      if (!form.phone.trim()) errs.phone  = "Téléphone requis.";
      return errs;
    };

    const handleSubmit = (e) => {
      e.preventDefault();
      const errs = validate();
      setErrors(errs);
      if (Object.keys(errs).length > 0) return;
      setSubmitting(true);
      const payload = {
        category: category.label,
        date:    form.date,
        slot:    form.slot,
        persons: form.persons,
        priceH:  form.priceH,
        total4h, deposit,
        contact: { name: form.name, email: form.email, phone: form.phone },
        submittedAt: new Date().toISOString()
      };
      console.log("[BoatsFun] Offre soumise :", payload);
      setTimeout(() => {
        alert(
          `Offre envoyée — ${category.label} · ` +
          `${form.priceH ? form.priceH + " $/h" : "prix sur demande"} · ` +
          `${form.date} (${form.slot})\n` +
          `${total4h ? "Total 4h : " + total4h + " $ · Dépôt : " + deposit + " $\n" : ""}` +
          `${form.persons} pers.\n\n` +
          `Le propriétaire a 24h pour accepter. Si refusée, dépôt remboursé à 100 %.\n(HubSpot à brancher en V1+.)`
        );
        setSubmitting(false);
      }, 200);
    };

    const currentCat = CATEGORIES[carouselIndex];

    return (
      <div className="bf" data-screen-label="Faire une offre">
        <style>{styles}</style>
        <window.BFHeader />

        <main className="container offer-page">
          <a className="offer-back" href="/bateaux">← Retour au catalogue</a>

          <div className="offer-head">
            <span className="offer-eyebrow">Proposez votre prix</span>
            <h1>Faire une offre</h1>
            <p>
              Choisissez la catégorie qui vous convient, sélectionnez vos dates et votre option
              de prix parmi nos choix prédéfinis.{" "}
              <strong>Les offres plus élevées ont plus de chances d'être acceptées rapidement par un propriétaire.</strong>
            </p>
          </div>

          <div className="offer-grid">

            {/* ── COLONNE PRINCIPALE ── */}
            <div className="offer-main-col">

              {/* ── ÉTAPE 1 : CAROUSEL (hors carte blanche) ── */}
              <div className="offer-carousel-section">
                <div className="offer-step-label">1 — Catégorie de bateau</div>
                <span className="offer-step-sub">Naviguez avec les flèches ou les miniatures, puis cliquez "Choisir".</span>

                <div className="offer-carousel">

                  {/* Zone image — bateau centré, respire */}
                  <div className="offer-hero-img-wrap">
                    <img
                      className="offer-hero-img"
                      src={currentCat.image}
                      alt={currentCat.label}
                      key={currentCat.id}
                    />
                    <button type="button" className="offer-arrow offer-prev" onClick={prevSlide} aria-label="Précédent">‹</button>
                    <button type="button" className="offer-arrow offer-next" onClick={nextSlide} aria-label="Suivant">›</button>
                  </div>

                  {/* Zone info — séparée de l'image, texte toujours lisible */}
                  <div className="offer-hero-info">
                    <div className="offer-hero-text">
                      <div className="offer-hero-name">{currentCat.label}</div>
                      <div className="offer-hero-desc">{currentCat.desc}</div>
                    </div>
                    <button
                      type="button"
                      className={"offer-hero-cta" + (catId === currentCat.id ? " is-selected" : "")}
                      onClick={() => handleCat(currentCat.id)}
                    >
                      {catId === currentCat.id ? "✓ Sélectionnée" : "Choisir"}
                    </button>
                  </div>

                  {/* Miniatures */}
                  <div className="offer-thumbs">
                    {CATEGORIES.map((c, idx) => (
                      <button
                        type="button"
                        key={c.id}
                        className={"offer-thumb" + (carouselIndex === idx ? " is-active" : "")}
                        onClick={() => setCarouselIndex(idx)}
                        aria-label={c.label}
                      >
                        <img className="offer-thumb-img" src={c.image} alt={c.label} />
                        <span className="offer-thumb-label">{c.label}</span>
                      </button>
                    ))}
                  </div>

                </div>
                {errors.cat && <div className="offer-error">{errors.cat}</div>}
              </div>

              {/* ── FORM (étapes 2-4) ── */}
              <form className="offer-card" onSubmit={handleSubmit} noValidate>

              {/* ÉTAPE 2 — Date, horaire, personnes */}
              <div className="offer-step">
                <div className="offer-step-label">2 — Date & horaire</div>
                <div className="offer-row">
                  <div className="offer-field">
                    <label htmlFor="date">Date souhaitée <span className="req">*</span></label>
                    <input
                      id="date" type="date"
                      className={"offer-input" + (errors.date ? " has-error" : "")}
                      value={form.date} min={todayISO()}
                      onChange={handleField("date")}
                    />
                    {dayLabel && <div className="offer-hint">{dayLabel}</div>}
                    {errors.date && <div className="offer-error">{errors.date}</div>}
                  </div>
                  <div className="offer-field">
                    <label htmlFor="slot">Plage horaire <span className="req">*</span></label>
                    <select
                      id="slot"
                      className={"offer-select" + (errors.slot ? " has-error" : "")}
                      value={form.slot} onChange={handleField("slot")}
                    >
                      <option value="">— Choisir —</option>
                      {TIME_SLOTS.map(s => <option key={s} value={s}>{s}</option>)}
                    </select>
                    {errors.slot && <div className="offer-error">{errors.slot}</div>}
                  </div>
                </div>
                <div className="offer-field">
                  <label htmlFor="persons">Nombre de personnes <span className="req">*</span></label>
                  <select
                    id="persons"
                    className={"offer-select" + (errors.persons ? " has-error" : "")}
                    value={form.persons} onChange={handleField("persons")}
                  >
                    <option value="">— Choisir —</option>
                    {Array.from({ length: 29 }, (_, i) => i + 2).map(n => (
                      <option key={n} value={n}>{n} personnes</option>
                    ))}
                  </select>
                  {errors.persons && <div className="offer-error">{errors.persons}</div>}
                </div>
              </div>

              {/* ÉTAPE 3 — Option de prix */}
              <div className="offer-step">
                <div className="offer-step-label">
                  {"3 — Option de prix"}
                  {catId === "ponton" && dayLabel && (
                    <span className="offer-step-day"> · {dayLabel}</span>
                  )}
                </div>

                {catId === "speedboat" ? (
                  /* Speedboat : prix sur demande */
                  <div className="oprice-onrequest">
                    <div className="oprice-onrequest-icon">💬</div>
                    <div className="oprice-onrequest-title">Options de prix à confirmer pour cette catégorie.</div>
                    <div className="oprice-onrequest-sub">
                      Notre équipe vous contactera après soumission pour définir le tarif adapté à votre sortie en Speedboat.
                    </div>
                  </div>
                ) : catId && priceOptions ? (
                  /* Ponton / Cruiser / Yacht : intro + notice + grille de prix */
                  <React.Fragment>
                    <p className="oprice-intro">Choisissez un prix de rabais.</p>
                    <p className="oprice-note">
                      Plus votre offre est basse, plus vos chances d'acceptation diminuent. Les offres plus élevées sont généralement acceptées plus rapidement par les propriétaires.
                    </p>
                    <div className="oprice-notice">
                      À titre indicatif, les offres tournent généralement entre 150&nbsp;$/h et 200&nbsp;$/h en semaine, et entre 150&nbsp;$/h et 250&nbsp;$/h en fin de semaine, selon la catégorie de bateau et le niveau d'offre choisi.
                    </div>
                    <div className="oprice-grid">
                      {priceOptions.map(opt => (
                        <PriceCard
                          key={opt.priceH}
                          opt={opt}
                          selected={form.priceH === opt.priceH}
                          onSelect={handlePrice}
                          maxPriceH={maxPriceH}
                        />
                      ))}
                    </div>
                  </React.Fragment>
                ) : (
                  /* Aucune catégorie sélectionnée */
                  <div className="oprice-placeholder">
                    Choisissez une catégorie pour voir les options de prix.
                  </div>
                )}

                {errors.price && <div className="offer-error">{errors.price}</div>}
              </div>

              {/* ÉTAPE 4 — Coordonnées */}
              <div className="offer-step">
                <div className="offer-step-label">4 — Vos coordonnées</div>
                <div className="offer-row">
                  <div className="offer-field">
                    <label htmlFor="name">Nom complet <span className="req">*</span></label>
                    <input
                      id="name" type="text"
                      className={"offer-input" + (errors.name ? " has-error" : "")}
                      value={form.name} onChange={handleField("name")}
                      placeholder="Jean Tremblay"
                    />
                    {errors.name && <div className="offer-error">{errors.name}</div>}
                  </div>
                  <div className="offer-field">
                    <label htmlFor="phone">Téléphone <span className="req">*</span></label>
                    <input
                      id="phone" type="tel"
                      className={"offer-input" + (errors.phone ? " has-error" : "")}
                      value={form.phone} onChange={handleField("phone")}
                      placeholder="514 555-1234"
                    />
                    {errors.phone && <div className="offer-error">{errors.phone}</div>}
                  </div>
                </div>
                <div className="offer-field">
                  <label htmlFor="email">Email <span className="req">*</span></label>
                  <input
                    id="email" type="email"
                    className={"offer-input" + (errors.email ? " has-error" : "")}
                    value={form.email} onChange={handleField("email")}
                    placeholder="vous@exemple.com"
                  />
                  {errors.email && <div className="offer-error">{errors.email}</div>}
                </div>
              </div>

              <button type="submit" className="offer-submit" disabled={submitting}>
                {submitting ? "Envoi…" : "Envoyer mon offre"}
              </button>
              </form>

            </div>{/* /offer-main-col */}

            {/* ── SIDEBAR ── */}
            <aside className="offer-aside">

              {(catId || form.priceH) && (
                <div className="offer-summary">
                  <h3>Récapitulatif</h3>
                  {category && (
                    <div className="offer-sumrow"><span>Catégorie</span><b>{category.label}</b></div>
                  )}
                  {form.date && (
                    <div className="offer-sumrow"><span>Date</span><b>{form.date}</b></div>
                  )}
                  {form.slot && (
                    <div className="offer-sumrow"><span>Horaire</span><b>{form.slot}</b></div>
                  )}
                  {form.persons && (
                    <div className="offer-sumrow"><span>Personnes</span><b>{form.persons}</b></div>
                  )}
                  {form.priceH ? (
                    <React.Fragment>
                      <div className="offer-sumrow"><span>Prix /h</span><b>{form.priceH} $</b></div>
                      <div className="offer-sumrow"><span>Total 4h</span><b>{total4h.toLocaleString("fr-CA")} $</b></div>
                      <div className="offer-sumrow is-big">
                        <span>Dépôt à payer</span>
                        <b>{deposit.toLocaleString("fr-CA")} $ CAD</b>
                      </div>
                    </React.Fragment>
                  ) : catId === "speedboat" ? (
                    <div className="offer-sumrow"><span>Prix</span><b>Sur demande</b></div>
                  ) : null}
                </div>
              )}

              <div className="offer-refund">
                <span className="badge">100 %</span>
                <p>
                  <strong>Dépôt remboursé intégralement</strong> si votre offre est refusée.
                  Si aucune offre n'est acceptée, votre dépôt est remboursé. Aucun frais caché.
                </p>
              </div>

              <div className="offer-info">
                <h3>Comment ça marche</h3>
                <ul>
                  <li>Choisissez une catégorie, vos dates et une option de prix.</li>
                  <li>Les offres plus élevées sont acceptées plus rapidement.</li>
                  <li>Le propriétaire a 24 h pour accepter ou refuser.</li>
                  <li>Si acceptée : le dépôt est prélevé, solde à bord. Si refusée : remboursement instantané.</li>
                </ul>
              </div>

            </aside>
          </div>
        </main>

        <window.BFFooter />
      </div>
    );
  }

  window.BFPageOffer = BFPageOffer;
})();
