@php
  use Illuminate\Support\Facades\Route;
  use App\Models\Attivita;
  use App\Models\Saltacoda;

  /** @var \App\Models\Attivita|null $attivita */
  $accent = $attivita?->colore ?: '#f58220';
  $festLogoLarge = asset('assets/img/logo_fest_L.png');
  $festLogoFallback = Attivita::defaultLogoUrl();
  $backUrl = $attivita
    ? route('cliente.attivita.show', ['attivita_id' => $attivita->id])
    : (Route::has('welcome') ? route('welcome') : url('/'));
  $istruzioni = Saltacoda::find($saltacoda_id ?? null)?->getIstruzioni() ?? Saltacoda::defaultIstruzioni();
@endphp

@extends('layouts/guest')

@section('title', $attivita ? 'Ordina · ' . $attivita->nome : 'Saltacoda')

@section('page-meta')
  <script>document.documentElement.classList.add('saltacoda-cliente-page');</script>
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,400;0,500;0,600;0,700;0,800;1,400&display=swap" rel="stylesheet" />
  <meta name="theme-color" content="{{ $accent }}">
  <meta name="theme-color" media="(prefers-color-scheme: light)" content="{{ $accent }}">
  <meta name="theme-color" media="(prefers-color-scheme: dark)" content="{{ $accent }}">
  <meta name="color-scheme" content="light">
  <meta name="mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="default">
@endsection

@section('page-style')
  @include('saltacoda._partials.cliente.fest-layout-style')
<style>
  .saltacoda-mobile {
    --saltacoda-topbar-h: 72px;
    --saltacoda-footbar-h: 86px;
    --saltacoda-accent: var(--card-accent);
    --saltacoda-accent-line: color-mix(in srgb, var(--card-accent) 42%, transparent);
    --saltacoda-accent-text: color-mix(in srgb, var(--card-accent) 72%, #15265c);
    --saltacoda-accent-surface: color-mix(in srgb, var(--card-accent) 8%, #fff);
    --saltacoda-accent-border: color-mix(in srgb, var(--card-accent) 45%, transparent);
    --saltacoda-accent-shadow: color-mix(in srgb, var(--card-accent) 18%, transparent);
    position: relative;
    z-index: 1;
    min-height: 100vh;
    min-height: 100dvh;
    width: 100vw;
    background: transparent;
    margin: 0;
  }

  .saltacoda-topbar {
    height: var(--saltacoda-topbar-h);
  }

  .saltacoda-topbar-title {
    margin: 0;
    flex: 1;
    min-width: 0;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-main);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: center;
  }

  .saltacoda-topbar-search {
    display: none;
    flex: 1;
  }

  .saltacoda-topbar.search-open .saltacoda-topbar-title {
    display: none;
  }

  .saltacoda-topbar.search-open .saltacoda-topbar-search {
    display: block;
  }

  .saltacoda-topbar-btn {
    width: 2.15rem;
    height: 2.15rem;
    border: 0;
    border-radius: 999px;
    background: color-mix(in srgb, var(--card-accent) 10%, #fff);
    color: var(--text-main);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    flex-shrink: 0;
  }

  .saltacoda-search {
    width: 100%;
    border: 1px solid color-mix(in srgb, var(--text-main) 10%, transparent);
    border-radius: 999px;
    background: var(--fest-surface);
    padding: 0.58rem 0.9rem;
    color: var(--text-main);
    font-size: 0.93rem;
    box-shadow: none;
  }

  .saltacoda-content {
    margin-top: var(--saltacoda-topbar-h);
    padding: 0.75rem 0.75rem calc(var(--saltacoda-footbar-h) + 1rem + env(safe-area-inset-bottom));
    height: calc(100vh - var(--saltacoda-topbar-h));
    height: calc(100dvh - var(--saltacoda-topbar-h));
    overflow-y: auto;
  }

  .saltacoda-no-results {
    background: var(--fest-surface);
    border: 1px dashed var(--fest-border);
    border-radius: 0.8rem;
    padding: 0.9rem;
    text-align: center;
    color: var(--text-muted);
    display: none;
  }

  .saltacoda-kitchen-title {
    margin: 0 0 0.85rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    position: sticky;
    top: 0;
    z-index: 1010;
    padding: 0.55rem 0;
    background: transparent;
    border: 0;
    box-shadow: none;
  }

  .saltacoda-kitchen-title::before,
  .saltacoda-kitchen-title::after {
    content: '';
    flex: 1 1 0;
    height: 1px;
    background: linear-gradient(
      90deg,
      transparent 0%,
      var(--saltacoda-accent-line) 18%,
      var(--saltacoda-accent-line) 82%,
      transparent 100%
    );
  }

  .saltacoda-kitchen-badge {
    flex: 0 1 auto;
    max-width: min(72%, 16rem);
    margin: 0;
    padding: 0 0.15rem;
    background: transparent;
    color: var(--saltacoda-accent-text);
    font-size: 0.82rem;
    font-weight: 700;
    font-family: inherit;
    text-transform: none;
    letter-spacing: 0.02em;
    line-height: 1.25;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    border-radius: 0;
    box-shadow: none;
  }

  .saltacoda-kitchen {
    margin-bottom: 1.05rem;
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
  }

  .saltacoda-dish {
    width: 100%;
    background: var(--fest-surface);
    border-radius: 0.85rem;
    padding: 0.82rem 0.85rem;
    margin-bottom: 0.55rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    text-align: left;
    border: 1px solid var(--fest-border);
    transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
  }

  .saltacoda-dish:active {
    transform: scale(0.99);
  }

  .saltacoda-dish.added {
    border-color: var(--saltacoda-accent-border);
    box-shadow: 0 6px 14px var(--saltacoda-accent-shadow);
    animation: saltacodaDishAdded 0.42s ease;
  }

  .saltacoda-dish.has-items {
    border-color: color-mix(in srgb, var(--card-accent) 32%, transparent);
    background: var(--saltacoda-accent-surface);
  }

  .saltacoda-dish:last-child {
    margin-bottom: 0;
  }

  .saltacoda-dish-left {
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.45rem;
    flex: 1;
  }

  .saltacoda-dish-name {
    font-weight: 600;
    color: var(--text-main);
    margin-right: 0;
    line-height: 1.22;
    word-break: break-word;
  }

  .saltacoda-dish-price {
    font-weight: 700;
    color: var(--card-accent);
    white-space: nowrap;
    font-size: 0.9rem;
    background: color-mix(in srgb, var(--card-accent) 12%, #fff);
    border-radius: 999px;
    padding: 0.2rem 0.55rem;
  }

  .saltacoda-dish-meta {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.35rem;
    flex-shrink: 0;
  }

  .saltacoda-dish-counter {
    min-width: 22px;
    height: 22px;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 700;
    display: none;
    align-items: center;
    justify-content: center;
    background: var(--saltacoda-accent);
    color: #fff;
    box-shadow: 0 2px 8px color-mix(in srgb, var(--card-accent) 28%, transparent);
  }

  .saltacoda-dish-counter.visible {
    display: inline-flex;
  }

  .saltacoda-dish-counter.pulse {
    animation: saltacodaCounterPulse 0.35s ease;
  }

  @keyframes saltacodaDishAdded {
    0% {
      transform: scale(1);
      box-shadow: 0 0 0 color-mix(in srgb, var(--card-accent) 6%, transparent);
    }
    45% {
      transform: scale(1.01);
      box-shadow: 0 10px 22px color-mix(in srgb, var(--card-accent) 22%, transparent);
    }
    100% {
      transform: scale(1);
      box-shadow: 0 6px 14px var(--saltacoda-accent-shadow);
    }
  }

  @keyframes saltacodaCounterPulse {
    0% {
      transform: scale(1);
    }
    50% {
      transform: scale(1.22);
    }
    100% {
      transform: scale(1);
    }
  }

  .saltacoda-footbar {
    position: fixed !important;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9999;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(8px);
    border-top: 1px solid rgba(21, 38, 92, 0.08);
    box-shadow: 0 -6px 24px var(--fest-shadow);
    display: block !important;
    visibility: visible !important;
  }

  .saltacoda-cart-summary {
    min-height: var(--saltacoda-footbar-h);
    padding: 0.65rem 0.75rem calc(0.65rem + env(safe-area-inset-bottom));
    display: flex;
    gap: 0.6rem;
    align-items: center;
  }

  .saltacoda-cart-toggle {
    border: 0;
    flex: 1;
    padding: 0.5rem;
    background: transparent;
    text-align: left;
    color: var(--text-muted);
  }

  .saltacoda-cart-toggle small {
    display: block;
    color: var(--text-muted);
    font-size: 0.75rem;
  }

  .saltacoda-cart-toggle strong {
    display: block;
    font-size: 0.95rem;
    line-height: 1.2;
    color: var(--text-main);
  }

  .saltacoda-cart-chevron {
    font-size: 1rem;
    color: var(--text-muted);
    margin-left: 0.25rem;
    transition: transform 0.2s ease;
  }

  .saltacoda-cart-toggle[aria-expanded="true"] .saltacoda-cart-chevron {
    transform: rotate(180deg);
  }

  .saltacoda-send-btn {
    min-width: 86px;
    padding: 0.7rem 0.95rem;
  }

  .saltacoda-cart-body {
    border-top: 1px solid var(--fest-border);
    max-height: 36vh;
    overflow-y: auto;
    padding: 0.5rem 0.75rem 0.85rem;
  }

  #saltacodaCartCollapse {
    max-height: calc(100vh - var(--saltacoda-topbar-h) - var(--saltacoda-footbar-h) - env(safe-area-inset-bottom) - 0.5rem);
    max-height: calc(100dvh - var(--saltacoda-topbar-h) - var(--saltacoda-footbar-h) - env(safe-area-inset-bottom) - 0.5rem);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }

  .saltacoda-cart-actions {
    border-top: 1px solid var(--fest-border);
    padding: 0.6rem 0.75rem calc(0.7rem + env(safe-area-inset-bottom));
    background: var(--fest-surface);
  }

  .saltacoda-clear-btn {
    width: 100%;
    border: 1px solid #f1c2c2;
    border-radius: 0.65rem;
    background: #fff7f7;
    color: #d14343;
    font-size: 0.86rem;
    font-weight: 700;
    padding: 0.62rem 0.85rem;
  }

  .saltacoda-clear-btn:disabled {
    background: #f7f7f9;
    border-color: #ebedf4;
    color: #9aa3b2;
  }

  .saltacoda-info-required {
    color: #d14343;
    margin-left: 0.15rem;
  }

  .saltacoda-cart-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0;
    border-bottom: 1px dashed var(--fest-border);
  }

  .saltacoda-cart-item:last-child {
    border-bottom: 0;
  }

  .saltacoda-qty {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--fest-border);
    border-radius: 999px;
  }

  .saltacoda-qty button {
    border: 0;
    background: transparent;
    width: 28px;
    height: 28px;
    color: var(--text-muted);
  }

  .saltacoda-qty button:active {
    background: color-mix(in srgb, var(--card-accent) 8%, #fff);
  }

  .saltacoda-qty span {
    min-width: 22px;
    text-align: center;
    font-size: 0.8rem;
    font-weight: 700;
  }

  .saltacoda-empty {
    color: var(--text-muted);
    text-align: center;
    padding: 0.7rem 0.2rem;
    margin: 0;
  }

  @media (min-width: 768px) {
    .saltacoda-mobile {
      margin: 0 auto;
      max-width: 680px;
      border-left: 1px solid color-mix(in srgb, var(--text-main) 8%, transparent);
      border-right: 1px solid color-mix(in srgb, var(--text-main) 8%, transparent);
    }
  }

  @media (max-width: 767.98px) {
    .saltacoda-topbar,
    .saltacoda-footbar {
      width: 100dvw;
      max-width: 100dvw;
    }

    .saltacoda-footbar {
      bottom: 0;
      padding-bottom: env(safe-area-inset-bottom);
    }
  }
</style>
@endsection

@section('content')
<div class="saltacoda-cliente">
  <div class="saltacoda-cliente__bg" aria-hidden="true"></div>

<div class="saltacoda-mobile">
  <header class="saltacoda-topbar saltacoda-fest-topbar" id="saltacodaTopbar">
    <a href="{{ $backUrl }}" class="saltacoda-fest-topbar__back" aria-label="Torna all'evento">
      <i class="bx bx-arrow-back"></i>
    </a>
    <h1 class="saltacoda-topbar-title saltacoda-fest-topbar__title">{{ $attivita->nome }}</h1>
    <div class="saltacoda-topbar-search">
      <input
        type="search"
        id="dishSearch"
        class="saltacoda-search"
        placeholder="Cerca un piatto..."
        autocomplete="off">
    </div>
    <button type="button" id="searchToggleBtn" class="saltacoda-topbar-btn" aria-label="Apri ricerca">
      <i id="searchToggleIcon" class="bx bx-search"></i>
    </button>
    <a href="{{ $backUrl }}" class="saltacoda-fest-topbar__brand" aria-label="{{ config('app.name') }}">
      <img src="{{ $festLogoLarge }}" alt="{{ config('app.name') }}" loading="lazy">
    </a>
  </header>

  <main class="saltacoda-content">
    @foreach($cucine as $cucina)
      <section class="saltacoda-kitchen" id="cucina_{{ $cucina->id }}">
        <h2 class="saltacoda-kitchen-title">
          <span class="saltacoda-kitchen-badge">{{ $cucina->nome }}</span>
        </h2>

        @forelse($cucina->piatti as $piatto)
          <button
            type="button"
            class="saltacoda-dish"
            data-piatto-id="{{ $piatto->id }}"
            data-piatto-nome="{{ $piatto->nome }}"
            data-piatto-prezzo="{{ (float) $piatto->prezzo }}">
            <span class="saltacoda-dish-left">
              <span class="saltacoda-dish-name">{{ $piatto->nome }}</span>
            </span>
            <span class="saltacoda-dish-meta">
              <span class="saltacoda-dish-price">€ {{ number_format((float) $piatto->prezzo, 2, ',', '.') }}</span>
              <span class="saltacoda-dish-counter" data-counter-for="{{ $piatto->id }}">0</span>
            </span>
          </button>
        @empty
          <p class="text-muted mb-0">Nessun piatto disponibile.</p>
        @endforelse
      </section>
    @endforeach
    <p id="noResultsMessage" class="saltacoda-no-results mb-0">Nessun piatto trovato con questa ricerca.</p>
  </main>

  <aside class="saltacoda-footbar">
    <div class="saltacoda-cart-summary">
      <button
        class="saltacoda-cart-toggle"
        type="button"
        data-bs-toggle="collapse"
        data-bs-target="#saltacodaCartCollapse"
        aria-expanded="false"
        aria-controls="saltacodaCartCollapse">
        <small>Il mio ordine</small>
        <strong>
          <span id="cartCount">0</span> piatti · € <span id="cartTotal">0,00</span>
          <i class="bx bx-chevron-up saltacoda-cart-chevron"></i>
        </strong>
      </button>

      <button type="button" id="sendOrderBtn" class="saltacoda-send-btn" disabled>Procedi</button>
    </div>

    <div class="collapse" id="saltacodaCartCollapse">
      <div class="saltacoda-cart-body" id="cartItemsContainer">
        <p class="saltacoda-empty mb-0">Il carrello è vuoto.</p>
      </div>
      <div class="saltacoda-cart-actions">
        <button type="button" id="clearCartBtn" class="saltacoda-clear-btn" disabled>
          Elimina tutti i piatti
        </button>
      </div>
    </div>
  </aside>
</div>

  <div id="scStepApertura" class="sc-step-overlay" hidden>
    <div class="sc-step-sheet sc-step-sheet--center">
      <div class="sc-istruzione-panel">
        <h2 class="sc-istruzione-panel__title" id="scAperturaTitle"></h2>
        <div class="sc-istruzione-panel__text" id="scAperturaText"></div>
      </div>
      <div class="sc-step-actions">
        <button type="button" id="scAperturaNext" class="saltacoda-fest-btn">Avanti</button>
      </div>
    </div>
  </div>

  <div id="scCheckoutWizard" class="sc-step-overlay sc-checkout-wizard" hidden>
    <div class="sc-step-sheet sc-checkout-wizard__sheet">
      <div id="scStepInfo" class="sc-wizard-pane sc-wizard-pane--info" hidden>
        <div class="sc-wizard-pane__head">
          <span class="sc-wizard-step-badge" id="scWizardStepBadge" hidden></span>
          <h2 class="sc-wizard-pane__heading">I tuoi dati</h2>
          <p class="sc-wizard-pane__hint">Compila i campi per completare l'ordine.</p>
        </div>
        <div class="sc-wizard-pane__body">
          <div class="sc-info-fields-wrap" id="saltacodaInfoFields"></div>
        </div>
        <div class="sc-wizard-pane__foot sc-step-actions">
          <button type="button" id="scInfoBack" class="sc-step-btn-secondary">Indietro</button>
          <button type="button" id="scInfoNext" class="saltacoda-fest-btn">Continua</button>
        </div>
      </div>

      <div id="scStepPreInvio" class="sc-wizard-pane sc-wizard-pane--confirm" hidden>
        <div class="sc-wizard-pane__head">
          <span class="sc-wizard-step-badge" id="scWizardConfirmBadge" hidden></span>
          <h2 class="sc-wizard-pane__heading">Conferma ordine</h2>
        </div>
        <div class="sc-wizard-pane__body">
          <div class="sc-istruzione-panel">
            <h3 class="sc-istruzione-panel__title" id="scPreInvioTitle"></h3>
            <div class="sc-istruzione-panel__text" id="scPreInvioText"></div>
          </div>
        </div>
        <div class="sc-wizard-pane__foot sc-step-actions">
          <button type="button" id="scPreInvioBack" class="sc-step-btn-secondary">Indietro</button>
          <button type="button" id="scPreInvioSend" class="saltacoda-fest-btn">Conferma e invia</button>
        </div>
      </div>
    </div>
  </div>
</div>

<script>
  (function () {
    const infoFieldsConfig = @json($campi_info ?? []);
    const istruzioni = @json($istruzioni);
    const savePreOrderUrl = @json(route('saltacoda.pre-ordine.salva'));
    const saltacodaId = @json($saltacoda_id ?? null);
    const attivitaId = @json($attivita->id ?? null);
    const cart = {};
    const infoValues = {};
    const countEl = document.getElementById('cartCount');
    const totalEl = document.getElementById('cartTotal');
    const cartToggleBtnEl = document.querySelector('.saltacoda-cart-toggle');
    const cartCollapseEl = document.getElementById('saltacodaCartCollapse');
    const containerEl = document.getElementById('cartItemsContainer');
    const sendBtnEl = document.getElementById('sendOrderBtn');
    const clearBtnEl = document.getElementById('clearCartBtn');
    const topbarEl = document.getElementById('saltacodaTopbar');
    const searchToggleBtnEl = document.getElementById('searchToggleBtn');
    const searchToggleIconEl = document.getElementById('searchToggleIcon');
    const dishSearchEl = document.getElementById('dishSearch');
    const noResultsEl = document.getElementById('noResultsMessage');
    const infoFieldsEl = document.getElementById('saltacodaInfoFields');
    const aperturaOverlayEl = document.getElementById('scStepApertura');
    const aperturaTitleEl = document.getElementById('scAperturaTitle');
    const aperturaTextEl = document.getElementById('scAperturaText');
    const aperturaNextEl = document.getElementById('scAperturaNext');
    const checkoutWizardEl = document.getElementById('scCheckoutWizard');
    const stepInfoEl = document.getElementById('scStepInfo');
    const stepPreInvioEl = document.getElementById('scStepPreInvio');
    const preInvioTitleEl = document.getElementById('scPreInvioTitle');
    const preInvioTextEl = document.getElementById('scPreInvioText');
    const infoBackEl = document.getElementById('scInfoBack');
    const infoNextEl = document.getElementById('scInfoNext');
    const preInvioBackEl = document.getElementById('scPreInvioBack');
    const preInvioSendEl = document.getElementById('scPreInvioSend');
    const wizardStepBadgeEl = document.getElementById('scWizardStepBadge');
    const wizardConfirmBadgeEl = document.getElementById('scWizardConfirmBadge');
    let isSearchOpen = false;
    let isSending = false;

    function slotIsActive(key) {
      const slot = istruzioni[key];
      return !!(slot && slot.attivo && ((slot.titolo || '').trim() || (slot.testo || '').trim()));
    }

    function fillIstruzioneSlot(titleEl, textEl, key) {
      const slot = istruzioni[key] || {};
      const titolo = (slot.titolo || '').trim();
      const testo = (slot.testo || '').trim();
      titleEl.textContent = titolo;
      textEl.textContent = testo;
      titleEl.hidden = titolo === '';
      textEl.hidden = testo === '';
    }

    function setWizardOpen(isOpen) {
      document.body.classList.toggle('sc-wizard-open', isOpen);
    }

    function showApertura() {
      fillIstruzioneSlot(aperturaTitleEl, aperturaTextEl, 'apertura');
      aperturaOverlayEl.hidden = false;
      setWizardOpen(true);
    }

    function hideApertura() {
      aperturaOverlayEl.hidden = true;
      if (checkoutWizardEl.hidden) {
        setWizardOpen(false);
      }
    }

    function getCheckoutStepCount() {
      let count = 0;
      if (infoFieldsConfig.length > 0) {
        count += 1;
      }
      if (slotIsActive('pre_invio')) {
        count += 1;
      }
      return count;
    }

    function updateStepBadges(currentStep) {
      const totalSteps = getCheckoutStepCount();
      const showBadges = totalSteps > 1;
      let currentIndex = 1;

      if (currentStep === 'pre_invio') {
        currentIndex = infoFieldsConfig.length > 0 ? 2 : 1;
      }

      const label = showBadges ? `Passo ${currentIndex} di ${totalSteps}` : '';

      if (wizardStepBadgeEl) {
        wizardStepBadgeEl.textContent = label;
        wizardStepBadgeEl.hidden = !showBadges || currentStep !== 'info';
      }

      if (wizardConfirmBadgeEl) {
        wizardConfirmBadgeEl.textContent = label;
        wizardConfirmBadgeEl.hidden = !showBadges || currentStep !== 'pre_invio';
      }
    }

    function showCheckoutStep(step) {
      checkoutWizardEl.hidden = false;
      checkoutWizardEl.classList.toggle('sc-checkout-wizard--info', step === 'info');
      checkoutWizardEl.classList.toggle('sc-checkout-wizard--confirm', step === 'pre_invio');
      stepInfoEl.hidden = step !== 'info';
      stepPreInvioEl.hidden = step !== 'pre_invio';
      if (step === 'pre_invio') {
        fillIstruzioneSlot(preInvioTitleEl, preInvioTextEl, 'pre_invio');
      }
      updateStepBadges(step);
      setWizardOpen(true);

      const activeBody = step === 'info'
        ? stepInfoEl.querySelector('.sc-wizard-pane__body')
        : stepPreInvioEl.querySelector('.sc-wizard-pane__body');
      if (activeBody) {
        activeBody.scrollTop = 0;
      }
    }

    function hideCheckoutWizard() {
      checkoutWizardEl.hidden = true;
      checkoutWizardEl.classList.remove('sc-checkout-wizard--info', 'sc-checkout-wizard--confirm');
      stepInfoEl.hidden = true;
      stepPreInvioEl.hidden = true;
      if (aperturaOverlayEl.hidden) {
        setWizardOpen(false);
      }
    }

    function startCheckoutFlow() {
      if (infoFieldsConfig.length > 0) {
        showCheckoutStep('info');
        return;
      }
      if (slotIsActive('pre_invio')) {
        showCheckoutStep('pre_invio');
        return;
      }
      completeOrderSend();
    }

    function goBackFromPreInvio() {
      if (infoFieldsConfig.length > 0) {
        showCheckoutStep('info');
        return;
      }
      hideCheckoutWizard();
    }

    function formatEuro(value) {
      return value.toLocaleString('it-IT', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    }

    function getTotals() {
      const items = Object.values(cart);
      const count = items.reduce((acc, item) => acc + item.qty, 0);
      const total = items.reduce((acc, item) => acc + item.qty * item.price, 0);
      return { count, total };
    }

    function renderCart() {
      const items = Object.values(cart);
      const { count, total } = getTotals();

      countEl.textContent = count;
      totalEl.textContent = formatEuro(total);
      sendBtnEl.disabled = count === 0;
      clearBtnEl.disabled = count === 0;
      document.querySelectorAll('.saltacoda-dish-counter').forEach((counterEl) => {
        const id = counterEl.dataset.counterFor;
        const qty = cart[id] ? cart[id].qty : 0;
        counterEl.textContent = qty;
        counterEl.classList.toggle('visible', qty > 0);
      });
      document.querySelectorAll('.saltacoda-dish').forEach((dishEl) => {
        const id = dishEl.dataset.piattoId;
        const qty = cart[id] ? cart[id].qty : 0;
        dishEl.classList.toggle('has-items', qty > 0);
      });

      if (items.length === 0) {
        containerEl.innerHTML = '<p class="saltacoda-empty mb-0">Il carrello è vuoto.</p>';
        return;
      }

      containerEl.innerHTML = items.map((item) => {
        return `
          <div class="saltacoda-cart-item">
            <div>
              <strong>${item.name}</strong>
              <div class="text-muted small">€ ${formatEuro(item.price)} cad.</div>
              <input
                type="text"
                class="form-control form-control-sm mt-2"
                placeholder="Nota riga (opzionale)"
                data-note-id="${item.id}"
                value="${(item.note || '').replace(/"/g, '&quot;')}">
            </div>
            <div class="d-flex align-items-center gap-2">
              <div class="saltacoda-qty">
                <button type="button" data-action="dec" data-id="${item.id}">−</button>
                <span>${item.qty}</span>
                <button type="button" data-action="inc" data-id="${item.id}">+</button>
              </div>
              <strong>€ ${formatEuro(item.qty * item.price)}</strong>
            </div>
          </div>
        `;
      }).join('');
    }

    function upsertItem(id, name, price, delta) {
      if (!cart[id]) {
        cart[id] = { id, name, price, qty: 0, note: '' };
      }

      cart[id].qty += delta;
      if (cart[id].qty <= 0) {
        delete cart[id];
      }

      renderCart();
    }

    function animateAddedFeedback(dishId) {
      const counterEl = document.querySelector(`.saltacoda-dish-counter[data-counter-for="${dishId}"]`);
      if (!counterEl) {
        return;
      }

      counterEl.classList.remove('pulse');
      // Force reflow to restart animation when tapping quickly.
      void counterEl.offsetWidth;
      counterEl.classList.add('pulse');
      setTimeout(() => counterEl.classList.remove('pulse'), 380);
    }

    document.querySelectorAll('.saltacoda-dish').forEach((dishBtn) => {
      dishBtn.addEventListener('click', function () {
        const id = this.dataset.piattoId;
        const name = this.dataset.piattoNome;
        const price = parseFloat(this.dataset.piattoPrezzo || '0');
        upsertItem(id, name, price, 1);
        animateAddedFeedback(id);
        this.classList.add('added');
        setTimeout(() => this.classList.remove('added'), 220);
      });
    });

    function normalizeText(value) {
      return (value || '').toLowerCase().trim();
    }

    function renderInfoFields() {
      if (!infoFieldsConfig.length) {
        infoFieldsEl.innerHTML = '';
        return;
      }

      infoFieldsEl.innerHTML = infoFieldsConfig.map((field, index) => {
        const requiredAttr = field.required ? 'required' : '';
        const errorEl = '<p class="sc-info-field-card__error">Compila questo campo per continuare.</p>';
        const currentValue = infoValues[field.key] || '';
        const totalFields = infoFieldsConfig.length;
        const indexLabel = totalFields > 1
          ? `<span class="sc-info-field-card__index">${index + 1} di ${totalFields}</span>`
          : '';
        const statusPill = field.required
          ? '<span class="sc-info-field-card__pill sc-info-field-card__pill--required">Obbligatorio</span>'
          : '<span class="sc-info-field-card__pill">Facoltativo</span>';
        const metaParts = [indexLabel, statusPill].filter(Boolean).join('<span class="sc-info-field-card__sep" aria-hidden="true">·</span>');
        const metaRow = `<p class="sc-info-field-card__meta">${metaParts}</p>`;
        const controlWrapStart = '<div class="sc-info-field-card__control-wrap">';
        const controlWrapEnd = '</div>';

        if (field.type === 'boolean') {
          return `
            <div class="sc-info-field-card" data-info-card="${field.key}">
              <div class="sc-info-field-card__header">
                <label class="sc-info-field-card__label" for="info-${field.key}">${field.label}</label>
                ${metaRow}
              </div>
              ${controlWrapStart}
              <select
                id="info-${field.key}"
                class="sc-info-field-card__control"
                data-info-key="${field.key}"
                data-info-type="boolean"
                ${requiredAttr}>
                <option value="">Scegli una risposta</option>
                <option value="si" ${currentValue === 'si' ? 'selected' : ''}>Sì</option>
                <option value="no" ${currentValue === 'no' ? 'selected' : ''}>No</option>
              </select>
              ${controlWrapEnd}
              ${errorEl}
            </div>
          `;
        }

        if (field.type === 'time') {
          return `
            <div class="sc-info-field-card" data-info-card="${field.key}">
              <div class="sc-info-field-card__header">
                <label class="sc-info-field-card__label" for="info-${field.key}">${field.label}</label>
                ${metaRow}
              </div>
              ${controlWrapStart}
              <input
                type="time"
                id="info-${field.key}"
                class="sc-info-field-card__control"
                data-info-key="${field.key}"
                data-info-type="time"
                value="${currentValue}"
                ${requiredAttr}>
              ${controlWrapEnd}
              ${errorEl}
            </div>
          `;
        }

        return `
          <div class="sc-info-field-card" data-info-card="${field.key}">
            <div class="sc-info-field-card__header">
              <label class="sc-info-field-card__label" for="info-${field.key}">${field.label}</label>
              ${metaRow}
            </div>
            ${controlWrapStart}
            <input
              type="text"
              id="info-${field.key}"
              class="sc-info-field-card__control"
              data-info-key="${field.key}"
              data-info-type="text"
              value="${currentValue}"
              autocomplete="off"
              ${requiredAttr}>
            ${controlWrapEnd}
            ${errorEl}
          </div>
        `;
      }).join('');
    }

    function validateInfoFields() {
      if (!infoFieldsConfig.length) {
        return true;
      }

      let isValid = true;
      infoFieldsEl.querySelectorAll('[data-info-key]').forEach((inputEl) => {
        const fieldKey = inputEl.dataset.infoKey;
        const fieldValue = (inputEl.value || '').trim();
        const config = infoFieldsConfig.find((field) => field.key === fieldKey);
        const required = !!(config && config.required);

        infoValues[fieldKey] = fieldValue;
        const hasError = required && fieldValue === '';
        inputEl.classList.toggle('is-invalid', hasError);
        const cardEl = inputEl.closest('[data-info-card]');
        if (cardEl) {
          cardEl.classList.toggle('sc-info-field-card--error', hasError);
        }
        if (hasError) {
          isValid = false;
        }
      });

      return isValid;
    }

    function completeOrderSend() {
      if (isSending) {
        return;
      }

      if (infoFieldsConfig.length > 0 && !validateInfoFields()) {
        showCheckoutStep('info');
        const firstInvalid = infoFieldsEl.querySelector('.is-invalid');
        if (firstInvalid) {
          const cardEl = firstInvalid.closest('[data-info-card]') || firstInvalid;
          cardEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
          firstInvalid.focus({ preventScroll: true });
        }
        return;
      }

      const rigaOrdine = Object.values(cart)
        .filter((item) => item.qty > 0)
        .map((item) => ({
          piatto_id: Number(item.id),
          qta: Number(item.qty),
          note: (item.note || '').trim()
        }));

      if (rigaOrdine.length === 0) {
        alert('Aggiungi almeno un piatto prima di inviare.');
        return;
      }

      const infoCliente = {};
      infoFieldsConfig.forEach((field) => {
        const value = (infoValues[field.key] || '').trim();
        if (value !== '') {
          infoCliente[field.key] = value;
        }
      });

      const payload = {
        saltacoda_id: saltacodaId,
        attivita_id: attivitaId,
        riga_ordine: rigaOrdine,
        info_cliente: infoCliente,
        idempotency_key: (window.crypto && window.crypto.randomUUID)
          ? window.crypto.randomUUID()
          : `${Date.now()}_${Math.random().toString(36).slice(2)}`
      };

      if (!payload.saltacoda_id || !payload.attivita_id) {
        alert('Configurazione saltacoda non valida. Ricarica la pagina.');
        return;
      }

      sendBtnEl.disabled = true;
      isSending = true;
      preInvioSendEl.disabled = true;
      fetch(savePreOrderUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
        },
        body: JSON.stringify(payload)
      })
        .then(async (response) => {
          const data = await response.json().catch(() => ({}));
          if (!response.ok) {
            throw data;
          }
          return data;
        })
        .then((data) => {
          if (data.success === true) {
            alert('Pre-ordine inviato correttamente.');
            window.location.href = "{{ route('saltacoda.pre-ordine.show') }}"+'?codice='+data.data.codice;
          } else {
            alert(data.message);
          }
        })
        .catch((error) => {
          const message = error && error.message ? error.message : 'Errore durante l\'invio del pre-ordine.';
          alert(message);
        })
        .finally(() => {
          isSending = false;
          sendBtnEl.disabled = getTotals().count === 0;
          preInvioSendEl.disabled = false;
        });
    }

    function ensureCartOpen() {
      if (cartCollapseEl.classList.contains('show')) {
        return;
      }
      cartToggleBtnEl.click();
    }

    function applyDishFilter() {
      const query = normalizeText(dishSearchEl.value);
      let visibleKitchenCount = 0;

      document.querySelectorAll('.saltacoda-kitchen').forEach((kitchenEl) => {
        let visibleDishCount = 0;
        kitchenEl.querySelectorAll('.saltacoda-dish').forEach((dishEl) => {
          const dishName = normalizeText(dishEl.dataset.piattoNome);
          const isVisible = query === '' || dishName.includes(query);
          dishEl.style.display = isVisible ? 'flex' : 'none';
          if (isVisible) {
            visibleDishCount += 1;
          }
        });

        kitchenEl.style.display = visibleDishCount > 0 ? '' : 'none';
        if (visibleDishCount > 0) {
          visibleKitchenCount += 1;
        }
      });

      noResultsEl.style.display = visibleKitchenCount === 0 ? 'block' : 'none';
    }

    function setSearchOpen(nextValue) {
      isSearchOpen = nextValue;
      topbarEl.classList.toggle('search-open', isSearchOpen);
      searchToggleIconEl.className = isSearchOpen ? 'bx bx-x' : 'bx bx-search';
      searchToggleBtnEl.setAttribute('aria-label', isSearchOpen ? 'Chiudi ricerca' : 'Apri ricerca');

      if (isSearchOpen) {
        dishSearchEl.focus();
        return;
      }

      if (dishSearchEl.value !== '') {
        dishSearchEl.value = '';
        applyDishFilter();
      }
      dishSearchEl.blur();
    }

    searchToggleBtnEl.addEventListener('click', function () {
      setSearchOpen(!isSearchOpen);
    });

    dishSearchEl.addEventListener('keydown', function (event) {
      if (event.key === 'Escape') {
        setSearchOpen(false);
      }
    });

    dishSearchEl.addEventListener('input', applyDishFilter);
    applyDishFilter();
    renderInfoFields();

    if (slotIsActive('apertura')) {
      showApertura();
    }

    aperturaNextEl.addEventListener('click', hideApertura);
    infoBackEl.addEventListener('click', hideCheckoutWizard);
    infoNextEl.addEventListener('click', function () {
      if (!validateInfoFields()) {
        const firstInvalid = infoFieldsEl.querySelector('.is-invalid');
        if (firstInvalid) {
          const cardEl = firstInvalid.closest('[data-info-card]') || firstInvalid;
          cardEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
          firstInvalid.focus({ preventScroll: true });
        }
        return;
      }
      if (slotIsActive('pre_invio')) {
        showCheckoutStep('pre_invio');
        return;
      }
      hideCheckoutWizard();
      completeOrderSend();
    });
    preInvioBackEl.addEventListener('click', goBackFromPreInvio);
    preInvioSendEl.addEventListener('click', completeOrderSend);

    containerEl.addEventListener('click', function (event) {
      const action = event.target.dataset.action;
      const id = event.target.dataset.id;
      if (!action || !id) {
        return;
      }

      const item = cart[id];
      if (!item) {
        return;
      }

      upsertItem(id, item.name, item.price, action === 'inc' ? 1 : -1);
    });

    containerEl.addEventListener('input', function (event) {
      const noteInput = event.target.closest('[data-note-id]');
      if (!noteInput) {
        return;
      }
      const itemId = noteInput.dataset.noteId;
      if (!cart[itemId]) {
        return;
      }
      cart[itemId].note = noteInput.value || '';
    });

    function handleInfoFieldChange(event) {
      const inputEl = event.target.closest('[data-info-key]');
      if (!inputEl) {
        return;
      }

      inputEl.classList.remove('is-invalid');
      const cardEl = inputEl.closest('[data-info-card]');
      if (cardEl) {
        cardEl.classList.remove('sc-info-field-card--error');
      }
      infoValues[inputEl.dataset.infoKey] = (inputEl.value || '').trim();
    }

    infoFieldsEl.addEventListener('input', handleInfoFieldChange);
    infoFieldsEl.addEventListener('change', handleInfoFieldChange);

    sendBtnEl.addEventListener('click', function () {
      const { count } = getTotals();
      if (count === 0) {
        return;
      }
      startCheckoutFlow();
    });

    clearBtnEl.addEventListener('click', function () {
      if (Object.keys(cart).length === 0) {
        return;
      }

      const firstConfirm = confirm('Vuoi eliminare tutti i piatti dal carrello?');
      if (!firstConfirm) {
        return;
      }

      const secondConfirm = confirm('Confermi definitivamente? Questa azione non può essere annullata.');
      if (!secondConfirm) {
        return;
      }

      Object.keys(cart).forEach((key) => {
        delete cart[key];
      });
      renderCart();
    });
  })();
</script>
@endsection