{{/* Drop-in shortcode: quote.html – offerteformulier met items, optional, quantities, en herhaalbare secties (Websites/Cloud/Netwerk) */}}

{{/* Bronproducten uit page front matter of fallback site data */}}
{{ $products := slice }}
{{ if .Page.Params.products }}
  {{ $products = .Page.Params.products }}
{{ else if site.Data.products }}
  {{ $products = site.Data.products }}
{{ end }}

{{/* Optioneel: filteren op categorie via page param `productFilter` (string of array) */}}
{{ $filter := .Page.Params.productFilter }}
{{ if $filter }}
  {{ $typeStr := printf "%T" $filter }}
  {{ $filters := cond (eq $typeStr "[]interface {}") $filter (slice $filter) }}
  {{ $products = where $products "categorie" "in" $filters }}
{{ end }}

<section class="section pt-0 mt-0">
  <div class="container col-lg-10 bg-light p-4 rounded-sm">
    <div class="row">
      <div class="col-lg-12 px-lg-6 px-md-5 px-sm-4 mx-auto">
        <form id="quote-form" class="row" novalidate>

          <!-- Product-secties -->
          <div class="col-lg-12 mb-3">
            <h2>Stel je diensten samen</h2>
            <p>Maak hieronder je keuze per dienst die wij aanbieden.</p>
            {{ range $i, $p := $products }}
              {{ $idx := printf "%d" $i }}
              {{ $items := cond (isset $p "items") $p.items (slice) }}
              {{ $optList := cond (isset $p "optional") $p.optional (slice) }}
              {{ $qtyList := cond (isset $p "quantity") $p.quantity (slice) }}

              <div class="product-wrap mb-4" data-wrap-idx="{{ $idx }}" data-key="{{ $p.key }}" data-base="{{ with $p.prijs }}{{ . }}{{ else }}0{{ end }}" data-categorie="{{ $p.categorie }}">
                <div class="d-flex align-items-center justify-content-between">
                  <div class="form-check">
                    <input class="form-check-input me-2 prod-checkbox" type="checkbox" id="prod-{{ $idx }}" name="prod-{{ $p.key }}" data-item="item-{{ $idx }}" data-base="{{ with $p.prijs }}{{ . }}{{ else }}0{{ end }}">
                    <label class="form-check-label" for="prod-{{ $idx }}"><b>{{ $p.naam }}</b></label>
                  </div>
                </div>
                
                <div class="product-sections d-none">
                  <div class="row g-3">
                    <div class="col-lg-8 pt-4">
                      
                      {{ if $p.omschrijving }}<p class="text-muted small mb-2">{{ $p.omschrijving | markdownify }}</p>{{ end }}

                      {{ if gt (len $items) 0 }}
                        <!-- <h4 class="form-label mt-1" for="item-{{ $idx }}">Stel je <span style="text-transform: lowercase;">{{ $p.naam }}</span> samen</h4> -->
                        <select id="item-{{ $idx }}" name="item-{{ $p.key }}" class="form-select mt-1 item-select" data-idx="{{ $idx }}">
                          <option class="text-light" value="" disabled selected>{{ i18n "form-select-option" }}</option>
                          {{ range $j, $d := $items }}
                            <option value="{{ with $d.prijs }}{{ . }}{{ else }}0{{ end }}"
                                    data-code="{{ $d.code }}"
                                    data-service="{{ with $d.prijsService }}{{ . }}{{ else }}0{{ end }}"
                                    data-periode="{{ with $d.prijsServicePeriode }}{{ . }}{{ else }}maand{{ end }}">
                              {{ if and (isset $d "prijs") (ne $d.prijs 0) }}€{{ $d.prijs }} — {{ end }}{{ $d.label }}
                            </option>

                          {{ end }}
                        </select>
                      {{ end }}

                      {{ if gt (len $optList) 0 }}
                        <div class="mt-3 optional-block">
                          <h6 class="d-block my-2">Optioneel:</h6>
                          {{ range $k, $opt := $optList }}
                            <div class="form-check">
                              <input class="form-check-input calc-extra optional-item" type="checkbox" id="opt-{{ $idx }}-{{ $k }}" name="opt-{{ $p.key }}-{{ $k }}" value="{{ with $opt.prijs }}{{ . }}{{ else }}0{{ end }}" data-service="{{ with $opt.prijsService }}{{ . }}{{ else }}0{{ end }}" data-periode="{{ with $opt.prijsServicePeriode }}{{ . }}{{ else }}maand{{ end }}" data-required-for='{{ if isset $opt "requiredFor" }}{{ $opt.requiredFor | jsonify }}{{ else }}[]{{ end }}'>
                              <input type="hidden" id="opt-{{ $idx }}-{{ $k }}-hidden" name="opt-{{ $p.key }}-{{ $k }}-hidden" value="0">
                              <label class="form-check-label pb-2" for="opt-{{ $idx }}-{{ $k }}"><b>{{ $opt.label }}</b> -  {{ if and (isset $opt "prijs") (ne $opt.prijs 0) }} €{{ $opt.prijs }}{{ end }}{{ if $opt.omschrijving }} <br><small class="text-muted">{{ $opt.omschrijving | markdownify }}</small>{{ end }}</label>
                            </div>
                          {{ end }}
                        </div>
                      {{ end }}

                      {{ if gt (len $qtyList) 0 }}
                        <div class="mt-3 qty-block" data-idx="{{ $idx }}">
                          {{ range $q, $qty := $qtyList }}
                            <label class="form-label d-block my-2" for="qty-{{ $idx }}-{{ $q }}">
                              <b>{{ $qty.label }} {{ if and (isset $qty "prijs") (ne $qty.prijs 0) }} €{{ $qty.prijs }}{{ end }}</b>{{ if $qty.omschrijving }} <br><small class="text-muted">{{ $qty.omschrijving | markdownify }}</small>{{ end }}
                            </label>
                              <input
                                type="number"
                                min="0"
                                step="1"
                                value="0"
                                class="form-control qty-item mb-2"
                                data-unit="{{ with $qty.prijs }}{{ . }}{{ else }}0{{ end }}"
                                data-unit-service="{{ with $qty.prijsService }}{{ . }}{{ else }}0{{ end }}"
                                data-periode="{{ with $qty.prijsServicePeriode }}{{ . }}{{ else }}maand{{ end }}"
                                data-idx="{{ $idx }}"
                                id="qty-{{ $idx }}-{{ $q }}"
                                name="qty-{{ $p.key }}-{{ $q }}"
                              >
                          {{ end }}
                        </div>
                      {{ end }}
                      <hr class="mt-4 mb-0">
                    </div>

                    <div class="col-lg-4">
                      <div class="card h-100">
                        <div class="card-body">
                          <h6 class="card-title mb-2">{{ or $p.infoTitle (printf "%s info" $p.naam) }}</h6>
                          {{ if isset $p "infobox" }}
                            <span class="text-muted small mb-0">{{ $p.infobox | markdownify }}</span>
                          {{ else if $p.omschrijving }}
                            <span class="text-muted small mb-0">{{ $p.omschrijving | markdownify }}</span>
                          {{ else }}
                            <span class="text-muted small mb-0">Selecteer opties en vul aantallen in.</span>
                          {{ end }}

                          <!-- SUBTOTAAL: sticky onderin de infobox -->
                          <div class="mt-3 pt-2 border-top d-flex justify-content-between align-items-center subtot-sticky">
                            <div class="w-100">
                              <div class="d-flex justify-content-between align-items-center">
                                <span class="text-muted small">Kosten eenmalig</span>
                                <strong>€<span class="product-subtotal-once" data-idx="{{ $idx }}">0</span></strong>
                              </div>
                              <div class="d-flex justify-content-between align-items-center">
                                <span class="text-muted small">Kosten per maand</span>
                                <strong>€<span class="product-subtotal-service" data-idx="{{ $idx }}">0</span></strong>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            {{ end }}
          </div>

          <div class="col-12 my-3 d-flex align-items-center">
            <p class="mb-0 h4">
              Totaal eenmalig: <strong>€<span id="total-once">0</span></strong><br>
              <small>Kosten per maand: <strong>€<span id="total-service">0</span></strong></small>
            </p>
          </div>
          
          <hr>
          <h4>Ontvang berekening en een persoonlijke offerte</h4>
          <p>Laat jouw gegevens achter om de berekening met aanvullende informatie te ontvangen per mail. Ook zullen wij in contact met je komen over jouw nieuwe IT project. Wij nemen binnen 3 werkdagen contact op om alles door te nemen en een offerte op maat te maken.</p>
          <p><b>In de tussentijd nog vragen?</b><br>Bel dan naar <a href="tel:+31657969491">+31 6 5796 9491</a> of stuur een email naar <a href="mailto:info@start-it.nl">info@start-it.nl</a></p>

          <input type="hidden" name="estimatedTotal" id="estimatedTotal" value="0">

          <!-- Honeypot tegen bots -->
          <input type="text" id="company" name="company" class="d-none" tabindex="-1" autocomplete="off">

          <!-- Contact -->
          <div class="col-lg-6"><input type="text" name="firstName" class="form-control mb-4" placeholder="Voornaam"></div>
          <div class="col-lg-6"><input type="text" name="lastName" class="form-control mb-4" placeholder="Achternaam *" required></div>
          <div class="col-lg-6"><input type="email" name="email" class="form-control mb-4" placeholder="E-mail" required></div>
          <div class="col-lg-6"><input type="tel" name="phone" class="form-control mb-4" placeholder="Telefoon *" required></div>
          <div class="col-lg-12"><textarea name="description" class="form-control mb-4" placeholder="Aanvullende informatie over jouw project..."></textarea></div>
          <div class="col-lg-12"><input type="checkbox" name="agree"><label style="padding-left: 4px;" for="agree" required>Akkoord met voorwaarden & privacybeleid</label></div>

          <div class="col-12 mt-4"><button type="submit" class="btn btn-primary">Ontvang offerte</button></div>
        </form>
      </div>
    </div>
  </div>
</section>


<script>
(function () {
  // === ESPOCRM LeadCapture endpoint ===
  const ESPO_ENDPOINT = 'https://crm.start-it.nl/api/v1/LeadCapture/231344ae2852d65f41e98d99da418af8';

  // --- ELEMENTS ---
  const totalEl = document.getElementById('total');                  // bestaand totaal (blijft bestaan)
  const hiddenTotalEl = document.getElementById('estimatedTotal');
  const calculateBtn = document.getElementById('calculate');
  const form = document.getElementById('quote-form');
  const prodCheckboxes = document.querySelectorAll('.prod-checkbox');
  const extrasEls   = document.querySelectorAll('.calc-extra:not(.optional-item)');
  const optionalEls = document.querySelectorAll('.optional-item');

  // === DECIMAAL-VEILIG PARSEN ===
  function toNumberSafe(value) {
    if (typeof value === 'number') return Number.isFinite(value) ? value : 0;
    let s = String(value || '').trim();
    if (!s) return 0;
    s = s.replace(/\s/g, '');
    const hasComma = s.includes(',');
    const hasDot = s.includes('.');
    if (hasComma && hasDot) {
      const lastComma = s.lastIndexOf(',');
      const lastDot = s.lastIndexOf('.');
      if (lastComma > lastDot) { s = s.replace(/\./g, ''); s = s.replace(',', '.'); }
      else { s = s.replace(/,/g, ''); }
    } else if (hasComma) { s = s.replace(/\./g, ''); s = s.replace(',', '.'); }
    else { s = s.replace(/,/g, ''); }
    const n = Number(s);
    return Number.isFinite(n) ? n : 0;
  }
  function toQtySafe(value) { return Math.max(0, Math.floor(toNumberSafe(value))); }

  // === HELPERS ===
  function toIntSafe(value) { const s = String(value).replace(/[^\d\-]/g, ''); const n = parseInt(s, 10); return Number.isNaN(n) ? 0 : n; }
  function getIdxFromCb(cb) { const id = cb.dataset.item; if (!id) return null; const m = id.match(/^item-(\d+)$/); return m ? m[1] : null; }

  // === UI UPGRADE: voeg service-totaal bovenaan toe als die ontbreekt ===
  // Bestaand totaal (id="total") blijft de "eenmalig" tonen; we voegen "per maand" eronder.
  (function ensureHeaderTotals(){
    if (!totalEl) return;
    const parent = totalEl.closest('p') || totalEl.parentElement;
    if (!parent) return;
    if (!document.getElementById('total-once')) {
      // Wrap het bestaande getal in een ID 'total-once' zonder de layout te breken
      totalEl.id = 'total-once';
    }
    if (!document.getElementById('total-service')) {
      const small = document.createElement('small');
      small.innerHTML = 'Kosten per maand: <strong>€<span id="total-service">0</span></strong>';
      parent.appendChild(document.createElement('br'));
      parent.appendChild(small);
    }
  })();

  const totalOnceEl = document.getElementById('total-once');
  const totalServiceEl = document.getElementById('total-service');

  // === UI UPGRADE: vervang subtotaalblok in infobox ON-THE-FLY (niet in template) ===
  // We laten de bestaande container staan, maar tonen daarbinnen 2 regels.
  function upgradeSubtotalsDOM() {
    document.querySelectorAll('.subtot-sticky').forEach(box => {
      // al geüpgraded?
      if (box.querySelector('.product-subtotal-once') || box.querySelector('.product-subtotal-service')) return;

      // Haal idx via een van de bestaande elementen in de buurt
      const idxEl = box.closest('.product-wrap');
      const idx = idxEl ? idxEl.getAttribute('data-wrap-idx') : null;
      if (!idx) return;

      // Maak twee regels (eenmalig + per maand)
      const wrapper = document.createElement('div');
      wrapper.className = 'w-100';

      const row1 = document.createElement('div');
      row1.className = 'd-flex justify-content-between align-items-center';
      row1.innerHTML = '<span class="text-muted small">Kosten eenmalig</span><strong>€<span class="product-subtotal-once" data-idx="'+idx+'">0</span></strong>';

      const row2 = document.createElement('div');
      row2.className = 'd-flex justify-content-between align-items-center';
      row2.innerHTML = '<span class="text-muted small">Kosten per maand</span><strong>€<span class="product-subtotal-service" data-idx="'+idx+'">0</span></strong>';

      // Opruimen oude single-subtotal, maar laat de rest van de layout intact
      box.innerHTML = '';
      box.appendChild(wrapper);
      wrapper.appendChild(row1);
      wrapper.appendChild(row2);
    });
  }
  upgradeSubtotalsDOM();

  // === COLLAPSIBLE ANIMATIE: zonder d-none races ===
  function prepareCollapsibles() {
    document.querySelectorAll('.product-sections').forEach(sec => {
      sec.classList.remove('d-none');   // niet met display:none werken
      sec.classList.remove('open');     // start dicht
      sec.style.maxHeight = '0px';
      sec.dataset.animating = '0';
    });
  }
  prepareCollapsibles();

  function toggleSection(checkbox) {
    const idx = getIdxFromCb(checkbox);
    if (!idx) return;

    const wrap = document.querySelector(`.product-wrap[data-wrap-idx="${idx}"]`);
    const sections = wrap ? wrap.querySelector('.product-sections') : null;
    const selectEl = document.getElementById(`item-${idx}`);
    const qtyInputs = wrap ? wrap.querySelectorAll('.qty-item') : [];
    const optChecks = wrap ? wrap.querySelectorAll('.optional-item') : [];
    if (!sections) return;

    if (sections.dataset.animating === '1') return;
    const forceReflow = el => el.offsetHeight;

    if (checkbox.checked) {
      if (sections.classList.contains('open')) return;
      sections.dataset.animating = '1';

      sections.style.maxHeight = '0px';
      sections.style.removeProperty('opacity');
      forceReflow(sections);

      const target = sections.scrollHeight;
      sections.classList.add('open');             // opacity -> 1 via CSS
      sections.style.maxHeight = target + 'px';

      const onEndOpen = (e) => {
        if (e.propertyName !== 'max-height') return;
        sections.style.maxHeight = 'auto';
        sections.dataset.animating = '0';
        sections.removeEventListener('transitionend', onEndOpen);
      };
      sections.addEventListener('transitionend', onEndOpen);

    } else {
      const isClosedNow = (!sections.classList.contains('open') && (sections.style.maxHeight === '0px' || !sections.style.maxHeight));
      if (isClosedNow) return;

      sections.dataset.animating = '1';

      const current = sections.scrollHeight;
      sections.style.maxHeight = current + 'px';
      sections.style.removeProperty('opacity');
      forceReflow(sections);

      sections.classList.remove('open');
      sections.style.maxHeight = '0px';

      const onEndClose = (e) => {
        if (e.propertyName !== 'max-height') return;
        sections.dataset.animating = '0';
        sections.removeEventListener('transitionend', onEndClose);
        sections.style.maxHeight = '0px';
        // Reset velden
        if (selectEl) selectEl.value = '0';
        qtyInputs.forEach(inp => inp.value = '0');
        optChecks.forEach(opt => {
          opt.checked = false;
          const hidden = document.getElementById(opt.id + '-hidden');
          if (hidden) hidden.value = '0';
        });
        updateUI(); // na reset opnieuw rekenen
      };
      sections.addEventListener('transitionend', onEndClose);
    }
  }

  function computeTotals() {
    let once = 0;       // eenmalig
    let service = 0;    // per maand

    // extras (globaal) → eenmalig
    extrasEls.forEach(el => {
      if (!el.checked) return;
      // globale extras tellen we als eenmalig (pas aan als je hier ook service wilt)
      once += toNumberSafe(el.value);
    });

    // producten
    prodCheckboxes.forEach(cb => {
      if (!cb.checked) return;

      const idx = getIdxFromCb(cb);
      const baseVal = toNumberSafe(cb.dataset.base || 0);

      let itemOnce = 0;
      let itemSvc  = 0;

      if (idx) {
        const selectEl = document.getElementById(`item-${idx}`);
        if (selectEl) {
          const sel = selectEl.options[selectEl.selectedIndex];
          itemOnce = toNumberSafe(selectEl.value || 0);
          itemSvc  = sel ? toNumberSafe(sel.dataset.service || 0) : 0;
        }

        // Base en item zijn *alternatief*: als er een itemprijs is, laat base weg.
        once += (itemOnce > 0 ? itemOnce : baseVal);
        service += itemSvc;

        const wrap = document.querySelector(`.product-wrap[data-wrap-idx="${idx}"]`);
        if (wrap) {
          // quantities → eenmalig + (optioneel) per maand
          wrap.querySelectorAll('.qty-item').forEach(inp => {
            const qty = toQtySafe(inp.value);
            if (!qty) return;
            const unitOnce = toNumberSafe(inp.dataset.unit || 0);
            const unitSvc  = toNumberSafe(inp.dataset.unitService || 0);
            once    += qty * unitOnce;
            service += qty * unitSvc;
          });

          // optionals → eenmalig (uitgezonderd inbegrepen)
          // optionals (eenmalig + service)
          wrap.querySelectorAll('.optional-item').forEach(opt => {
            if (!opt.checked) return;

            const sel = selectEl ? selectEl.options[selectEl.selectedIndex] : null;
            const selectedCode = sel ? sel.dataset.code : '';
            let requiredFor = [];
            try { requiredFor = JSON.parse(opt.dataset.requiredFor || '[]'); } catch (e) { requiredFor = []; }

            if (requiredFor.indexOf(selectedCode) !== -1) return; // inbegrepen → niet rekenen

            const onceVal = toNumberSafe(opt.value || 0);
            const svcVal  = toNumberSafe(opt.dataset.service || 0);

            once    += onceVal;
            service += svcVal;
          });

        }
      } else {
        // Geen idx/select → alleen base
        once += baseVal;
      }
    });

    return { once, service };
  }


  function computeProductSubtotalPair(idx) {
    let once = 0;
    let service = 0;

    const wrap = document.querySelector(`.product-wrap[data-wrap-idx="${idx}"]`);
    if (!wrap) return { once: 0, service: 0 };

    const cb = wrap.querySelector(`#prod-${idx}`);
    if (!cb || !cb.checked) return { once: 0, service: 0 };

    const baseVal = toNumberSafe(cb.dataset.base || 0);

    // item-select
    const selectEl = document.getElementById(`item-${idx}`);
    let itemOnce = 0;
    let itemSvc  = 0;
    if (selectEl) {
      const sel = selectEl.options[selectEl.selectedIndex];
      itemOnce = toNumberSafe(selectEl.value || 0);
      itemSvc  = sel ? toNumberSafe(sel.dataset.service || 0) : 0;
    }

    // Base en item zijn *alternatief*: als er een itemprijs is, geen base tellen.
    once += (itemOnce > 0 ? itemOnce : baseVal);
    service += itemSvc;

    // optionals (eenmalig, behalve inbegrepen)
    // optionals (eenmalig + service)
    wrap.querySelectorAll('.optional-item').forEach(opt => {
      if (!opt.checked) return;

      const sel = selectEl ? selectEl.options[selectEl.selectedIndex] : null;
      const selectedCode = sel ? sel.dataset.code : '';
      let requiredFor = [];
      try { requiredFor = JSON.parse(opt.dataset.requiredFor || '[]'); } catch (e) { requiredFor = []; }

      if (requiredFor.indexOf(selectedCode) !== -1) return; // inbegrepen → niet rekenen

      const onceVal = toNumberSafe(opt.value || 0);
      const svcVal  = toNumberSafe(opt.dataset.service || 0);

      once    += onceVal;
      service += svcVal;
    });


    // quantities (eenmalig + periodiek)
    wrap.querySelectorAll('.qty-item').forEach(inp => {
      const qty = toQtySafe(inp.value);
      if (!qty) return;
      const unitOnce = toNumberSafe(inp.dataset.unit || 0);
      const unitSvc  = toNumberSafe(inp.dataset.unitService || 0);
      once    += qty * unitOnce;
      service += qty * unitSvc;
    });

    return { once, service };
  }


  function updateProductSubtotals(idx) {
    const pair = computeProductSubtotalPair(idx);
    const onceSpan = document.querySelector(`.product-subtotal-once[data-idx="${idx}"]`);
    const svcSpan  = document.querySelector(`.product-subtotal-service[data-idx="${idx}"]`);
    if (onceSpan) onceSpan.textContent = pair.once.toLocaleString('nl-NL');
    if (svcSpan)  svcSpan.textContent  = pair.service.toLocaleString('nl-NL');
  }

  function updateAllProductSubtotals() {
    document.querySelectorAll('.product-subtotal-once').forEach(span => {
      const idx = span.getAttribute('data-idx');
      updateProductSubtotals(idx);
    });
  }

  // === UI UPDATE ===
  function updateUI() {
    // header totals
    const { once, service } = computeTotals();
    if (totalOnceEl)    totalOnceEl.textContent    = once.toLocaleString('nl-NL');
    if (totalServiceEl) totalServiceEl.textContent = service.toLocaleString('nl-NL');
    if (hiddenTotalEl)  hiddenTotalEl.value = once; // hidden bewaart eenmalig (compatibel met bestaande verwerkingen)

    // per product
    updateAllProductSubtotals();
  }

  // === BINDINGS ===
  prodCheckboxes.forEach(cb => {
    toggleSection(cb); // initial state
    cb.addEventListener('change', () => { toggleSection(cb); updateUI(); });
    const idx = getIdxFromCb(cb);
    if (idx) {
      const selectEl = document.getElementById(`item-${idx}`);
      if (selectEl) selectEl.addEventListener('change', () => updateUI());
    }
  });

  extrasEls.forEach(el => {
    const hidden = document.getElementById(el.id + '-hidden');
    const sync = () => {
      if (hidden) hidden.value = el.checked ? el.value : '0';
      updateUI();
    };
    el.addEventListener('change', sync);
    sync(); // init
  });

  optionalEls.forEach(el => {
    const hidden = document.getElementById(el.id + '-hidden');
    const sync = () => {
      if (hidden) hidden.value = el.checked ? el.value : '0';
      updateUI(); // triggert totals + subtotals
    };
    el.addEventListener('change', sync);
    sync(); // init
  });

  document.querySelectorAll('.qty-item').forEach(inp => {
    inp.addEventListener('input', () => {
      updateUI();
      const w = inp.closest('.product-wrap');
      if (w) updateProductSubtotals(w.getAttribute('data-wrap-idx'));
    });
  });

  if (calculateBtn) calculateBtn.addEventListener('click', () => updateUI());

  document.querySelectorAll('.item-select').forEach(select => {
    const idx = select.dataset.idx || (select.id.match(/^item-(\d+)$/) || [])[1];
    if (!idx) return;
    const wrap = document.querySelector(`.product-wrap[data-wrap-idx="${idx}"]`);
    const optionals = wrap ? Array.from(wrap.querySelectorAll('.optional-item')) : [];
    const applyState = () => {
      const selectedOption = select.options[select.selectedIndex];
      const selectedCode = selectedOption ? selectedOption.dataset.code : '';
      optionals.forEach(opt => {
        const raw = opt.dataset.requiredFor || '[]'; let requiredFor = [];
        try { requiredFor = JSON.parse(raw); } catch (e) { requiredFor = []; }
        const must = requiredFor.indexOf(selectedCode) !== -1;
        const hidden = document.getElementById(opt.id + '-hidden');
        if (must) { opt.checked = true; opt.disabled = true; if (hidden) hidden.value = '0'; }
        else { opt.disabled = false; if (hidden) hidden.value = opt.checked ? opt.value : '0'; }
      });
      updateUI();
    };
    select.addEventListener('change', applyState);
    applyState();
  });

  // Init (UI + subtotals)
  updateUI();

  // === SUBMIT ===
  form.addEventListener('submit', async function (ev) {
    ev.preventDefault();
    ev.stopPropagation();
    if (typeof ev.stopImmediatePropagation === 'function') ev.stopImmediatePropagation();

    if (!form.checkValidity()) { form.reportValidity(); return; }

    const honeypot = document.getElementById('company');
    if (honeypot && honeypot.value && honeypot.value.trim() !== '') { alert('Bot detectie: formulier niet verzonden.'); return; }

    const totals = computeTotals();
    hiddenTotalEl.value = totals.once; // compatibel

    const firstName = (form.querySelector('[name="firstName"]')?.value || '').trim();
    const lastName  = (form.querySelector('[name="lastName"]')?.value || '').trim();
    const email     = (form.querySelector('[name="email"]')?.value || '').trim();
    const phone     = (form.querySelector('[name="phone"]')?.value || '').trim();
    const descFree  = (form.querySelector('[name="description"]')?.value || '').trim();

    const emailOk = /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email);
    if (!emailOk) {
      const emailEl = form.querySelector('[name="email"]');
      if (emailEl) { emailEl.setCustomValidity('Vul een geldig e-mailadres in.'); form.reportValidity(); emailEl.setCustomValidity(''); }
      return;
    }

    // Beschrijving multiline
    const lines = [];
    lines.push('Ingediend via offerteformulier');
    lines.push('Voornaam: ' + firstName);
    lines.push('Achternaam: ' + lastName);
    lines.push('E-mail: ' + email);
    lines.push('Telefoon: ' + phone);
    if (descFree) lines.push('Aanvullende info: ' + descFree);

    document.querySelectorAll('.product-wrap').forEach(wrap => {
      const idx = wrap.getAttribute('data-wrap-idx');
      const cb  = wrap.querySelector('#prod-' + idx);
      if (!cb || !cb.checked) return;

      const titleLabel = wrap.querySelector('label[for="prod-' + idx + '"]');
      const title = titleLabel ? titleLabel.textContent.trim() : ('Onderdeel #' + idx);

      lines.push('');
      lines.push('[' + title + ']');

      // basis (eenmalig)
      const base = toNumberSafe(cb.dataset.base || 0);
      if (base) lines.push('  Basis: €' + base.toLocaleString('nl-NL'));

      // gekozen item: toon label + service
      const selectEl = document.getElementById('item-' + idx);
      let serviceForThis = 0;
      if (selectEl && selectEl.options && selectEl.selectedIndex >= 0) {
        const opt = selectEl.options[selectEl.selectedIndex];
        const txt = (opt && opt.textContent ? opt.textContent : '').trim();
        if (txt) lines.push('  Keuze: ' + txt);
        serviceForThis = toNumberSafe(opt?.dataset?.service || 0);
      }

      // optionals (eenmalig; inbegrepen overslaan)
      wrap.querySelectorAll('.optional-item').forEach(optEl => {
        if (!optEl.checked) return;
        const lbl = wrap.querySelector('label[for="' + optEl.id + '"]');
        const optTxt = lbl ? lbl.textContent.replace(/\s+/g,' ').trim() : 'Optie';

        const sel = (selectEl && selectEl.options && selectEl.selectedIndex >= 0) ? selectEl.options[selectEl.selectedIndex] : null;
        const selectedCode = sel && sel.dataset ? sel.dataset.code : '';

        let requiredFor = [];
        try { requiredFor = JSON.parse(optEl.dataset.requiredFor || '[]'); } catch(e) { requiredFor = []; }
        const isIncluded = requiredFor.indexOf(selectedCode) !== -1;

        const priceShown = toNumberSafe(optEl.value || 0);
        lines.push('  Optioneel: ' + optTxt + (isIncluded ? ' (inbegrepen)' : (priceShown ? ' (€' + priceShown.toLocaleString('nl-NL') + ')' : '')));
      });

      // quantities (eenmalig)
      wrap.querySelectorAll('.qty-item').forEach(q => {
        const qty = toQtySafe(q.value);
        if (!qty) return;
        const qLab = wrap.querySelector('label[for="' + q.id + '"]');
        const qTxt = qLab ? qLab.textContent.replace(/\s+/g,' ').trim() : 'Aantal-item';
        const unit = toNumberSafe(q.dataset.unit || 0);
        lines.push('  ' + qTxt + ': ' + qty + ' × €' + unit.toLocaleString('nl-NL') + ' = €' + (qty * unit).toLocaleString('nl-NL'));
      });

      // per-onderdeel subtotals
      const pair = computeProductSubtotalPair(idx);
      lines.push('  Kosten eenmalig: €' + pair.once.toLocaleString('nl-NL'));
      lines.push('  Kosten per maand: €' + pair.service.toLocaleString('nl-NL'));
    });

    lines.push('');
    lines.push('Totaal eenmalig: €' + totals.once.toLocaleString('nl-NL'));
    lines.push('Totaal per maand: €' + totals.service.toLocaleString('nl-NL'));

    const payload = {
      salutationName: '',
      firstName,
      lastName,
      middleName: '',
      emailAddress: email,
      phoneNumber: phone,
      description: lines.join('\n')
    };

    try {
      const res = await fetch(ESPO_ENDPOINT, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
        body: JSON.stringify(payload)
      });

      const text = await res.text().catch(() => '');
      if (!res.ok) {
        if (res.status === 409 || res.status === 422 || /duplicate/i.test(text)) {
          alert('We hebben dit e-mailadres al in het systeem. We koppelen je inzending aan het bestaande contact en nemen contact op.');
          return;
        }
        throw new Error(`LeadCapture HTTP ${res.status} ${res.statusText} — ${text}`);
      }

      alert('Bedankt! Je aanvraag is ontvangen. We nemen zo spoedig mogelijk contact op.');
      form.reset();
      updateUI();
    } catch (e) {
      console.error('[LeadCapture] Fout:', e);
      alert('Er ging iets mis bij het versturen. Probeer het later opnieuw of neem contact op.');
    }
  });

})();
</script>
