{% extends "base.html" %}
{% block extra_head %}
<link rel="stylesheet" href="/static/css/clients-crm.css?v=5" />
{% endblock %}
{% block content %}
<div class="clients-shell" x-data="clientsHub()" x-init="init()">
  <header class="page-header">
    <div>
      <h1>CRM · Klanten</h1>
      <p class="subtitle page-tip">Klanten beheren · pipeline · supermarkten · 360° intelligence</p>
    </div>
    <div class="retail-actions">
      <button class="btn btn-sm btn-pulse" @click="loadAll()" :disabled="busy">↻ Verversen</button>
      <a class="btn btn-sm btn-pulse-green" href="/retail">Retail 360 →</a>
      <a class="btn btn-sm" href="/deals">Deals →</a>
    </div>
  </header>

  <div class="clients-kpi-row">
    <div class="clients-kpi"><span>Totaal klanten</span><strong x-text="stats.total||0"></strong></div>
    <div class="clients-kpi"><span>Actief</span><strong x-text="stats.active||0"></strong></div>
    <div class="clients-kpi"><span>MRR schatting</span><strong x-text="fmtEur(stats.mrr_total)"></strong></div>
    <div class="clients-kpi"><span>Pipeline</span><strong x-text="fmtEur(stats.pipeline_value)"></strong></div>
    <div class="clients-kpi"><span>Filiaal-koppelingen</span><strong x-text="stats.store_links||0"></strong></div>
  </div>

  <nav class="clients-tabs" aria-label="Klanten weergaven">
    <div class="clients-tab-bar">
      <button type="button" class="clients-tab" :class="{active: tab==='kanban'}" @click="tab='kanban'">
        <span class="clients-tab-icon" aria-hidden="true">▦</span> Kanban
      </button>
      <button type="button" class="clients-tab" :class="{active: tab==='list'}" @click="tab='list'">
        <span class="clients-tab-icon" aria-hidden="true">☰</span> Lijst
      </button>
      <button type="button" class="clients-tab" :class="{active: tab==='stores'}" @click="tab='stores'; if(!storeResults.length) searchStores(true)">
        <span class="clients-tab-icon" aria-hidden="true">🛒</span> Supermarkten
      </button>
      <button type="button" class="clients-tab" :class="{active: tab==='360'}" @click="open360Tab()">
        <span class="clients-tab-icon" aria-hidden="true">◎</span> 360° Klant
      </button>
    </div>
    <div class="clients-tab-actions">
      <button class="btn btn-primary btn-sm" @click="openClientModal()">+ Nieuwe klant</button>
      <button class="btn btn-sm" @click="openStoreCreate()" x-show="tab==='stores'">+ Nieuw filiaal</button>
    </div>
  </nav>

  <!-- Kanban -->
  <div x-show="tab==='kanban'" x-cloak>
    <div class="clients-kanban">
      <template x-for="st in stages" :key="st.id">
        <div class="clients-kanban-col">
          <h3><span x-text="st.label"></span> <span class="count" x-text="stageCount(st.id)"></span></h3>
          <template x-for="c in clientsByStage(st.id)" :key="c.id">
            <div class="clients-card" :class="'stage-'+c.stage" @click="openDetail(c)">
              <strong x-text="c.name"></strong>
              <div class="clients-card-meta">
                <span x-show="c.contact" x-text="c.contact"></span>
                <span x-show="c.sector"> · <span x-text="c.sector"></span></span>
              </div>
              <div class="clients-card-meta" x-show="c.email" x-text="c.email"></div>
              <div class="clients-card-tags">
                <span class="clients-tag mrr" x-show="c.mrr_estimate" x-text="'€'+Number(c.mrr_estimate).toLocaleString('nl-NL')+'/mnd'"></span>
                <span class="clients-tag" x-show="c.store_count" x-text="c.store_count+' filialen'"></span>
              </div>
              <select class="clients-card-stage" x-model="c.stage" @click.stop @focus="stageSelectFocus(c)" @change.stop="quickStage(c)" :title="'Status wijzigen voor '+c.name">
                <template x-for="st in stages" :key="'kb'+c.id+st.id">
                  <option :value="st.id" x-text="st.label"></option>
                </template>
              </select>
            </div>
          </template>
        </div>
      </template>
    </div>
  </div>

  <!-- List -->
  <div x-show="tab==='list'" x-cloak>
    <div class="clients-toolbar">
      <input type="search" placeholder="Zoek naam, contact, e-mail…" x-model="filterQ" @input="applyFilter()" />
      <select x-model="filterStage" @change="applyFilter()">
        <option value="">Alle stages</option>
        <template x-for="st in stages" :key="'f'+st.id"><option :value="st.id" x-text="st.label"></option></template>
      </select>
      <select x-model="filterSector" @change="applyFilter()">
        <option value="">Alle sectoren</option>
        <template x-for="s in sectorOptions" :key="s"><option :value="s" x-text="s"></option></template>
      </select>
    </div>
    <table class="data-table">
      <thead><tr>
        <th>Naam</th><th>Contact</th><th>E-mail</th><th>Sector</th><th>Stage</th><th>MRR</th><th>Filialen</th><th></th>
      </tr></thead>
      <tbody>
        <template x-for="c in filtered" :key="'l'+c.id">
          <tr class="clickable-row" @click="openDetail(c)">
            <td><strong x-text="c.name"></strong></td>
            <td x-text="c.contact||'—'"></td>
            <td x-text="c.email||'—'"></td>
            <td x-text="c.sector||'—'"></td>
            <td @click.stop>
              <select class="clients-inline-stage" x-model="c.stage" @focus="stageSelectFocus(c)" @change="quickStage(c)">
                <template x-for="st in stages" :key="'ls'+c.id+st.id">
                  <option :value="st.id" x-text="st.label"></option>
                </template>
              </select>
            </td>
            <td x-text="c.mrr_estimate ? fmtEur(c.mrr_estimate) : '—'"></td>
            <td x-text="c.store_count||0"></td>
            <td>
              <button class="btn btn-sm" @click.stop="editClient(c)">Bewerk</button>
              <button class="btn btn-sm btn-reject" @click.stop="removeClient(c.id)">×</button>
            </td>
          </tr>
        </template>
      </tbody>
    </table>
    <p class="clients-empty" x-show="!filtered.length">Geen klanten gevonden.</p>
  </div>

  <!-- Supermarkten -->
  <div x-show="tab==='stores'" x-cloak>
    <p class="page-tip" style="margin-bottom:0.75rem">Filter filialen, selecteer een rij en vul data aan of koppel aan een klant.</p>

    <div class="store-filters-card">
      <div class="store-filters-grid">
        <label class="store-filter-field store-filter-search">
          <span class="filter-label">Zoeken</span>
          <input type="search" class="form-input" placeholder="Naam, adres, stad…" x-model="storeQ" @keydown.enter="searchStores(true)" />
        </label>
        <label class="store-filter-field">
          <span class="filter-label">Keten</span>
          <select class="form-input" x-model="storeChain" @change="searchStores(true)">
            <option value="">Alle ketens</option>
            <template x-for="ch in chains" :key="ch"><option :value="ch" x-text="ch"></option></template>
          </select>
        </label>
        <label class="store-filter-field">
          <span class="filter-label">Provincie</span>
          <select class="form-input" x-model="storeProvince" @change="searchStores(true)">
            <option value="">Alle provincies</option>
            <template x-for="p in provinces" :key="p"><option :value="p" x-text="p"></option></template>
          </select>
        </label>
        <label class="store-filter-field">
          <span class="filter-label">Stad</span>
          <input type="text" class="form-input" placeholder="bv. Amsterdam" x-model="storeCity" @keydown.enter="searchStores(true)" />
        </label>
        <label class="store-filter-field">
          <span class="filter-label">Partnership</span>
          <select class="form-input" x-model="storePartnership" @change="searchStores(true)">
            <option value="">Alle statussen</option>
            <template x-for="p in storePartnerships" :key="p.partnership_status">
              <option :value="p.partnership_status" x-text="(p.partnership_status||'none')+' ('+p.n+')'"></option>
            </template>
          </select>
        </label>
        <label class="store-filter-field">
          <span class="filter-label">Sorteren</span>
          <select class="form-input" x-model="storeSort" @change="searchStores(true)">
            <option value="name">Naam A-Z</option>
            <option value="chain">Keten + naam</option>
            <option value="halal_opportunity">Halal kans ↓</option>
            <option value="population">Bevolking ↓</option>
          </select>
        </label>
      </div>

      <details class="store-filters-extra">
        <summary>Extra filters</summary>
        <div class="store-filter-checks">
          <label><input type="checkbox" x-model="storeHalalGap" @change="searchStores(true)" /> Halal-gap (geen cert + geen schap)</label>
          <label><input type="checkbox" x-model="storeHalalCert" @change="searchStores(true)" /> Halal gecertificeerd</label>
          <label><input type="checkbox" x-model="storeHalalSection" @change="searchStores(true)" /> Halal schap</label>
          <label><input type="checkbox" x-model="storeLinkedCrm" @change="searchStores(true)" /> Gekoppeld aan CRM</label>
          <label><input type="checkbox" x-model="storeHasPhone" @change="searchStores(true)" /> Heeft telefoon</label>
          <label><input type="checkbox" x-model="storeHasEmail" @change="searchStores(true)" /> Heeft e-mail</label>
          <label><input type="checkbox" x-model="storeHasManager" @change="searchStores(true)" /> Heeft manager</label>
        </div>
        <div class="store-filters-grid" style="margin-top:0.65rem">
          <label class="store-filter-field">
            <span class="filter-label">Min. halal-kans (0-100)</span>
            <input type="number" min="0" max="100" class="form-input" x-model.number="storeMinHalalOpp" @change="searchStores(true)" placeholder="bv. 35" />
          </label>
          <label class="store-filter-field">
            <span class="filter-label">Postcode (prefix)</span>
            <input type="text" class="form-input" x-model="storePostcode" @keydown.enter="searchStores(true)" placeholder="bv. 1012" />
          </label>
        </div>
      </details>

      <div class="store-filters-actions">
        <button class="btn btn-sm btn-pulse" @click="searchStores(true)" :disabled="storeBusy">Zoeken</button>
        <button class="btn btn-sm btn-secondary" type="button" @click="resetStoreFilters()" :disabled="storeBusy">Filters wissen</button>
        <span class="store-results-meta" x-show="storeTotal > 0" x-text="storeResultLabel()"></span>
      </div>
    </div>

    <div class="store-search-panel">
      <div class="store-results-col">
        <div class="store-table-wrap">
          <table class="data-table store-results-table" x-show="storeResults.length">
            <thead>
              <tr>
                <th>Keten</th>
                <th>Filiaal</th>
                <th>Stad</th>
                <th>Status</th>
                <th>Halal</th>
              </tr>
            </thead>
            <tbody>
              <template x-for="s in storeResults" :key="s.id">
                <tr class="store-table-row" :class="{selected: selectedStore?.id===s.id}" @click="selectStore(s.id)">
                  <td x-text="s.chain||'—'"></td>
                  <td><strong x-text="s.name||'—'"></strong></td>
                  <td x-text="(s.city||'—') + (s.province ? ', '+s.province : '')"></td>
                  <td><span class="clients-tag" x-text="s.partnership_status||'none'"></span></td>
                  <td>
                    <span class="clients-tag" x-show="s.halal_certified">Cert</span>
                    <span class="clients-tag" x-show="s.has_halal_section && !s.halal_certified">Schap</span>
                    <span class="muted" x-show="!s.halal_certified && !s.has_halal_section">—</span>
                  </td>
                </tr>
              </template>
            </tbody>
          </table>
          <p class="clients-empty" x-show="!storeResults.length && !storeBusy">Geen filialen — pas filters aan en klik Zoeken.</p>
          <p class="clients-empty" x-show="storeBusy">Zoeken…</p>
        </div>

        <div class="store-pagination" x-show="storeTotal > storePageSize">
          <button class="btn btn-sm btn-secondary" type="button" @click="storePrevPage()" :disabled="storePage <= 1 || storeBusy">← Vorige</button>
          <span class="muted" x-text="'Pagina '+storePage+' / '+storePageCount()"></span>
          <button class="btn btn-sm btn-secondary" type="button" @click="storeNextPage()" :disabled="storePage >= storePageCount() || storeBusy">Volgende →</button>
        </div>
      </div>
      <div class="store-edit-panel" x-show="selectedStore">
        <h3 x-text="(selectedStore?.chain||'') + ' · ' + (selectedStore?.name||'')"></h3>
        <div class="clients-form-grid">
          <label class="full"><span class="filter-label">Adres</span>
            <input class="form-input" x-model="storeForm.address" /></label>
          <label><span class="filter-label">Postcode</span>
            <input class="form-input" x-model="storeForm.postcode" /></label>
          <label><span class="filter-label">Stad</span>
            <input class="form-input" x-model="storeForm.city" /></label>
          <label><span class="filter-label">Provincie</span>
            <input class="form-input" x-model="storeForm.province" /></label>
          <label><span class="filter-label">Telefoon</span>
            <input class="form-input" x-model="storeForm.phone" /></label>
          <label><span class="filter-label">E-mail</span>
            <input class="form-input" x-model="storeForm.email" /></label>
          <label><span class="filter-label">Website</span>
            <input class="form-input" x-model="storeForm.website" /></label>
          <label><span class="filter-label">Manager</span>
            <input class="form-input" x-model="storeForm.manager_name" /></label>
          <label><span class="filter-label">Partnership</span>
            <select class="form-input" x-model="storeForm.partnership_status">
              <option value="none">Geen</option><option value="prospect">Prospect</option>
              <option value="active">Actief</option><option value="paused">Gepauzeerd</option>
            </select></label>
          <label><span class="filter-label">Halal certificerder</span>
            <input class="form-input" x-model="storeForm.halal_certifier" placeholder="HQC, OSM…" /></label>
        </div>
        <div class="store-checks">
          <label><input type="checkbox" x-model="storeForm.halal_certified" /> Halal gecertificeerd</label>
          <label><input type="checkbox" x-model="storeForm.has_halal_section" /> Halal schap</label>
        </div>
        <div class="clients-form-grid" style="margin-top:0.75rem">
          <label class="full"><span class="filter-label">Koppel aan klant</span>
            <select class="form-input" x-model="linkForm.client_id">
              <option value="">— Selecteer klant —</option>
              <template x-for="c in clients" :key="'lc'+c.id">
                <option :value="c.id" x-text="c.name + ' ('+stageLabel(c.stage)+')'"></option>
              </template>
            </select></label>
          <label><span class="filter-label">Relatie</span>
            <select class="form-input" x-model="linkForm.relationship_type">
              <option value="prospect">Prospect</option><option value="partner">Partner</option>
              <option value="supplier">Leverancier</option><option value="competitor">Concurrent</option>
            </select></label>
          <label><span class="filter-label">Notities koppeling</span>
            <input class="form-input" x-model="linkForm.notes" placeholder="Optioneel" /></label>
        </div>
        <div class="btn-group" style="margin-top:1rem">
          <button class="btn btn-primary btn-sm" @click="saveStore()" :disabled="storeBusy">Opslaan filiaal</button>
          <button class="btn btn-sm btn-pulse-green" @click="linkStore()" :disabled="!linkForm.client_id">Koppel klant</button>
          <a class="btn btn-sm" :href="'/retail?store='+selectedStore?.id" target="_blank">Retail 360 →</a>
        </div>
      </div>
      <div class="store-edit-panel clients-empty" x-show="!selectedStore && !storeBusy">
        Selecteer een filiaal links om data aan te vullen.
      </div>
    </div>
  </div>

  <!-- 360° Klant Intelligence -->
  <div x-show="tab==='360'" x-cloak class="crm-360-shell">
    <div class="crm-360-head">
      <div>
        <h2>360° Klant Intelligence</h2>
        <p class="page-tip">NAS-documenten · sentiment · retail · deals · second brain · <span x-text="autoSyncLabel"></span></p>
      </div>
      <div class="crm-360-actions">
        <button class="btn btn-secondary btn-sm" @click="runAutoSync(true)" :disabled="autoSyncBusy">⟳ Sync alles</button>
        <button class="btn btn-primary btn-sm" @click="linkNasFile()" :disabled="!view360ClientId || !linkPathInput.trim()">+ Koppel pad</button>
        <button class="btn btn-secondary btn-sm" @click="linkNasFolder()" :disabled="!view360ClientId || !linkPathInput.trim()">+ Koppel map</button>
        <a class="btn btn-sm" href="/documents" target="_blank">📂 Documenten</a>
      </div>
    </div>

    <div class="a360-toolbar">
      <select class="form-input" x-model.number="view360ClientId" @change="loadClient360()">
        <option value="">— Klant —</option>
        <template x-for="c in clients" :key="'v360c'+c.id">
          <option :value="c.id" x-text="c.name"></option>
        </template>
      </select>
      <select class="form-input" x-model.number="linkProjectId">
        <option value="">— Project (optioneel) —</option>
        <template x-for="p in linkProjectsForClient()" :key="'v360p'+p.id">
          <option :value="p.id" x-text="p.name"></option>
        </template>
      </select>
      <input class="form-input" placeholder="NAS pad (bv. Telegram/rapport.pdf of CUCINA/…)" x-model="linkPathInput" />
    </div>

    <div class="a360-grid" x-show="view360ClientId">
      <div class="a360-kpis">
        <div class="crm-360-stat"><div class="n" x-text="stat360('documents')"></div><div class="l">Documenten</div></div>
        <div class="crm-360-stat"><div class="n" x-text="stat360('linked_paths')"></div><div class="l">Koppelingen</div></div>
        <div class="crm-360-stat"><div class="n" x-text="stat360('projects')"></div><div class="l">Projecten</div></div>
        <div class="crm-360-stat"><div class="n" x-text="stat360('stores')"></div><div class="l">Winkels</div></div>
      </div>

      <div class="a360-panel">
        <p class="crm-360-section">Gekoppelde paden</p>
        <div class="a360-links">
          <template x-for="l in client360.links || []" :key="'lnk'+l.id">
            <div class="a360-link-row">
              <span x-text="(l.is_folder ? '📁 ' : '📄 ') + l.storage_path"></span>
              <button class="btn btn-sm btn-secondary" @click="unlinkDocument(l.id)">✕</button>
            </div>
          </template>
          <p class="clients-empty" x-show="!(client360.links||[]).length">Nog geen koppelingen — voeg een NAS-pad toe of open Documenten Workbench</p>
        </div>
      </div>

      <div class="a360-panel">
        <p class="crm-360-section">Sentiment &amp; trends</p>
        <div class="a360-sentiment">
          <template x-for="s in client360.sentiment_breakdown || []" :key="s.sentiment_label">
            <span class="a360-pill" x-text="s.sentiment_label + ': ' + s.n"></span>
          </template>
        </div>
        <div class="a360-trends">
          <template x-for="t in client360.monthly_trends || []" :key="t.month">
            <div class="a360-trend-row">
              <span x-text="(t.month||'').slice(0,7)"></span>
              <span x-text="t.docs + ' docs'"></span>
              <span x-text="'sentiment ' + (t.avg_sentiment||0).toFixed(2)"></span>
            </div>
          </template>
        </div>
      </div>

      <div class="a360-panel">
        <p class="crm-360-section">Top woorden (klant corpus)</p>
        <div class="a360-words">
          <template x-for="w in client360.top_words || []" :key="w.lemma">
            <span class="a360-word" x-text="w.lemma + ' (' + w.total + ')'"></span>
          </template>
        </div>
      </div>

      <div class="a360-panel">
        <p class="crm-360-section">Retail &amp; deals</p>
        <template x-for="s in client360.stores || []" :key="'st'+s.id">
          <p class="page-tip" x-text="s.chain + ' · ' + s.name + ' · ' + (s.city||'')"></p>
        </template>
        <template x-for="d in client360.deals || []" :key="'dl'+d.id">
          <p class="page-tip" x-text="d.title + ' · €' + d.value + ' · ' + d.stage"></p>
        </template>
      </div>
    </div>

    <p class="clients-empty" x-show="!view360ClientId" style="padding:2rem">Selecteer een klant om de 360° view te laden</p>
  </div>

  <!-- Client modal -->
  <div class="modal" :class="{ open: clientModal }" @click.self="clientModal=false">
    <div class="modal-card" style="max-width:560px">
      <h3 x-text="clientForm.id ? 'Klant bewerken' : 'Nieuwe klant'"></h3>
      <div class="clients-form-grid">
        <label class="full"><span class="filter-label">Bedrijfsnaam *</span>
          <input class="form-input" x-model="clientForm.name" placeholder="Chai N Masala B.V." /></label>
        <label><span class="filter-label">Contactpersoon</span>
          <input class="form-input" x-model="clientForm.contact" /></label>
        <label><span class="filter-label">E-mail</span>
          <input class="form-input" type="email" x-model="clientForm.email" /></label>
        <label><span class="filter-label">Sector</span>
          <select class="form-input" x-model="clientForm.sector">
            <option value="">— Kies sector —</option>
            <template x-for="s in sectorOptions" :key="'s'+s"><option :value="s" x-text="s"></option></template>
          </select></label>
        <label><span class="filter-label">Stage</span>
          <select class="form-input" x-model="clientForm.stage">
            <template x-for="st in stages" :key="'cs'+st.id"><option :value="st.id" x-text="st.label"></option></template>
          </select></label>
        <label><span class="filter-label">MRR schatting (€/mnd)</span>
          <input class="form-input" type="number" min="0" step="100" x-model="clientForm.mrr_estimate" /></label>
        <label class="full"><span class="filter-label">Notities</span>
          <textarea class="form-input" rows="4" x-model="clientForm.notes" placeholder="Context, afspraken, next steps…"></textarea></label>
      </div>
      <div class="btn-group" style="margin-top:1rem">
        <button class="btn btn-primary" @click="saveClient()" :disabled="!clientForm.name.trim()">Opslaan</button>
        <button class="btn btn-secondary" @click="clientModal=false">Annuleren</button>
        <button class="btn btn-reject" x-show="clientForm.id" @click="removeClient(clientForm.id); clientModal=false">Verwijderen</button>
      </div>
    </div>
  </div>

  <!-- Store create modal -->
  <div class="modal" :class="{ open: storeCreateModal }" @click.self="storeCreateModal=false">
    <div class="modal-card" style="max-width:560px">
      <h3>Nieuw filiaal toevoegen</h3>
      <div class="clients-form-grid">
        <label><span class="filter-label">Keten *</span>
          <input class="form-input" x-model="newStore.chain" list="chain-list" placeholder="Jumbo, AH, Lidl…" /></label>
        <datalist id="chain-list"><template x-for="ch in chains" :key="'dl'+ch"><option :value="ch"></option></template></datalist>
        <label><span class="filter-label">Naam *</span>
          <input class="form-input" x-model="newStore.name" placeholder="Jumbo Bos en Lommer" /></label>
        <label class="full"><span class="filter-label">Adres *</span>
          <input class="form-input" x-model="newStore.address" /></label>
        <label><span class="filter-label">Postcode</span>
          <input class="form-input" x-model="newStore.postcode" /></label>
        <label><span class="filter-label">Stad *</span>
          <input class="form-input" x-model="newStore.city" /></label>
        <label><span class="filter-label">Provincie</span>
          <input class="form-input" x-model="newStore.province" /></label>
        <label><span class="filter-label">Telefoon</span>
          <input class="form-input" x-model="newStore.phone" /></label>
        <label><span class="filter-label">E-mail</span>
          <input class="form-input" x-model="newStore.email" /></label>
      </div>
      <div class="btn-group" style="margin-top:1rem">
        <button class="btn btn-primary" @click="createStore()" :disabled="!newStore.name||!newStore.chain||!newStore.city">Toevoegen</button>
        <button class="btn btn-secondary" @click="storeCreateModal=false">Annuleren</button>
      </div>
    </div>
  </div>

  <!-- Detail drawer -->
  <aside class="clients-drawer" :class="{ open: drawer }">
    <div class="clients-drawer-head">
      <div>
        <h2 x-text="detail?.client?.name||''"></h2>
        <p class="muted" x-text="stageLabel(detail?.client?.stage)+' · '+(detail?.client?.sector||'Geen sector')"></p>
      </div>
      <button class="drawer-close" @click="drawer=false">×</button>
    </div>
    <template x-if="detail?.client">
      <div>
        <div class="clients-card-meta">
          <div x-show="detail.client.contact"><strong>Contact:</strong> <span x-text="detail.client.contact"></span></div>
          <div x-show="detail.client.email"><strong>E-mail:</strong> <span x-text="detail.client.email"></span></div>
          <div x-show="detail.client.mrr_estimate"><strong>MRR:</strong> <span x-text="fmtEur(detail.client.mrr_estimate)"></span></div>
          <div x-show="detail.client.notes" style="margin-top:0.5rem;white-space:pre-wrap" x-text="detail.client.notes"></div>
        </div>
        <div class="btn-group" style="margin-top:0.75rem">
          <button class="btn btn-sm" @click="editClient(detail.client)">Bewerken</button>
          <button class="btn btn-sm btn-pulse-green" @click="openClient360(detail.client)">360° view →</button>
          <select class="form-input" style="width:auto" x-model="detail.client.stage" @change="quickStage(detail.client)">
            <template x-for="st in stages" :key="'ds'+st.id"><option :value="st.id" x-text="st.label"></option></template>
          </select>
        </div>
        <div class="clients-drawer-section">
          <h4>Deals (<span x-text="(detail.deals||[]).length"></span>)</h4>
          <template x-for="d in detail.deals||[]" :key="d.id">
            <div class="clients-card" style="cursor:default">
              <strong x-text="d.title"></strong>
              <div class="clients-card-meta" x-text="fmtEur(d.value)+' · '+d.stage"></div>
            </div>
          </template>
          <p class="muted" x-show="!(detail.deals||[]).length">Nog geen deals — <a href="/deals">voeg toe</a></p>
        </div>
        <div class="clients-drawer-section">
          <h4>Gekoppelde filialen (<span x-text="(detail.stores||[]).length"></span>)</h4>
          <template x-for="s in detail.stores||[]" :key="s.id">
            <div class="clients-card" style="cursor:default">
              <strong x-text="s.chain+' · '+s.name"></strong>
              <div class="clients-card-meta" x-text="s.city+(s.province?', '+s.province:'')"></div>
              <span class="clients-tag" x-text="s.relationship_type||s.partnership_status"></span>
            </div>
          </template>
          <button class="btn btn-sm" style="margin-top:0.5rem" @click="tab='stores'; drawer=false">+ Filiaal koppelen</button>
        </div>
      </div>
    </template>
  </aside>
</div>
{% endblock %}
{% block scripts %}
<script>
function clientsHub() {
  const STAGES = [
    { id: 'intake', label: 'Intake' },
    { id: 'discovery', label: 'Verkenning' },
    { id: 'proposal', label: 'Voorstel' },
    { id: 'active', label: 'Actief' },
    { id: 'churned', label: 'Verloren' },
  ];
  const SECTORS = [
    'Retail', 'Supermarkt', 'Groothandel', 'Horeca', 'Food service',
    'Spices & Tea', 'Kant-en-klaar', 'Import/Export', 'Private label', 'Overig',
  ];
  return {
    tab: 'kanban',
    busy: false,
    storeBusy: false,
    clientModal: false,
    storeCreateModal: false,
    drawer: false,
    stages: STAGES,
    sectorOptions: SECTORS,
    stats: {},
    clients: [],
    filtered: [],
    filterQ: '',
    filterStage: '',
    filterSector: '',
    detail: null,
    clientForm: {},
    storeResults: [],
    selectedStore: null,
    storeForm: {},
    linkForm: { client_id: '', relationship_type: 'prospect', notes: '' },
    storeQ: '',
    storeChain: '',
    storeProvince: '',
    storeCity: '',
    storePartnership: '',
    storeSort: 'name',
    storePostcode: '',
    storeMinHalalOpp: null,
    storeHalalGap: false,
    storeHalalCert: false,
    storeHalalSection: false,
    storeLinkedCrm: false,
    storeHasPhone: false,
    storeHasEmail: false,
    storeHasManager: false,
    storePage: 1,
    storePageSize: 25,
    storeTotal: 0,
    chains: [],
    provinces: [],
    storePartnerships: [],
    newStore: { chain: '', name: '', address: '', postcode: '0000AA', city: '', province: '', phone: '', email: '' },

    view360ClientId: '',
    linkProjectId: '',
    linkPathInput: '',
    linkProjects: [],
    client360: { stats: {}, links: [], sentiment_breakdown: [], monthly_trends: [], top_words: [], stores: [], deals: [] },
    autoSyncBusy: false,
    autoSyncLabel: 'Second brain: —',

    fmtEur(v) {
      if (v == null || v === '') return '—';
      return '€' + Number(v).toLocaleString('nl-NL', { maximumFractionDigits: 0 });
    },
    stageLabel(id) {
      return (STAGES.find(s => s.id === id) || {}).label || id || '—';
    },
    stageCount(id) { return this.clients.filter(c => c.stage === id).length; },
    clientsByStage(id) { return this.clients.filter(c => c.stage === id); },

    async init() {
      const qs = new URLSearchParams(location.search);
      const tab = qs.get('tab');
      const clientId = qs.get('client');
      await this.loadAll();
      if (tab === '360' || tab === 'view360') {
        this.tab = '360';
        if (clientId) this.view360ClientId = parseInt(clientId, 10) || '';
        await this.on360Tab();
      }
    },

    async loadAll() {
      this.busy = true;
      try {
        const [statsR, clientsR, filtersR] = await Promise.all([
          Cockpit.api('/clients/stats'),
          Cockpit.api('/clients'),
          fetch('/api/retail/filters').then(r => r.json()).catch(() => ({})),
        ]);
        this.stats = statsR.stats || {};
        this.clients = clientsR.items || [];
        this.chains = (filtersR.chains || []).map(x => x.chain || x).filter(Boolean);
        this.provinces = (filtersR.provinces || []).map(x => x.province || x).filter(Boolean);
        this.storePartnerships = filtersR.partnerships || [];
        this.applyFilter();
      } catch (e) {
        Cockpit.toast(e.message, 'error');
      }
      this.busy = false;
    },

    applyFilter() {
      const q = (this.filterQ || '').toLowerCase();
      this.filtered = this.clients.filter(c => {
        if (this.filterStage && c.stage !== this.filterStage) return false;
        if (this.filterSector && c.sector !== this.filterSector) return false;
        if (!q) return true;
        return [c.name, c.contact, c.email, c.sector, c.notes].some(
          f => f && String(f).toLowerCase().includes(q)
        );
      });
    },

    openClientModal() {
      this.clientForm = { id: null, name: '', contact: '', email: '', stage: 'intake', sector: '', mrr_estimate: '', notes: '' };
      this.clientModal = true;
    },
    editClient(c) {
      this.clientForm = {
        id: c.id, name: c.name || '', contact: c.contact || '', email: c.email || '',
        stage: c.stage || 'intake', sector: c.sector || '', mrr_estimate: c.mrr_estimate || '',
        notes: c.notes || '',
      };
      this.clientModal = true;
      this.drawer = false;
    },

    async saveClient() {
      const body = {
        name: this.clientForm.name.trim(),
        contact: this.clientForm.contact || null,
        email: this.clientForm.email || null,
        stage: this.clientForm.stage,
        sector: this.clientForm.sector || null,
        mrr_estimate: this.clientForm.mrr_estimate ? parseFloat(this.clientForm.mrr_estimate) : null,
        notes: this.clientForm.notes || null,
      };
      try {
        if (this.clientForm.id) {
          await Cockpit.api('/clients/' + this.clientForm.id, { method: 'PUT', body: JSON.stringify(body) });
        } else {
          await Cockpit.api('/clients', { method: 'POST', body: JSON.stringify(body) });
        }
        Cockpit.toast('Klant opgeslagen', 'success');
        this.clientModal = false;
        await this.loadAll();
      } catch (e) { Cockpit.toast(e.message, 'error'); }
    },

    async removeClient(id) {
      if (!Cockpit.confirmDelete('Klant definitief verwijderen?')) return;
      try {
        await Cockpit.api('/clients/' + id, { method: 'DELETE' });
        Cockpit.toast('Klant verwijderd', 'info');
        this.drawer = false;
        await this.loadAll();
      } catch (e) { Cockpit.toast(e.message, 'error'); }
    },

    async openDetail(c) {
      try {
        const d = await Cockpit.api('/clients/' + c.id + '/detail');
        this.detail = d;
        this.drawer = true;
      } catch (e) { Cockpit.toast(e.message, 'error'); }
    },

    openClient360(c) {
      if (!c || !c.id) return;
      this.view360ClientId = c.id;
      this.tab = '360';
      this.drawer = false;
      this.on360Tab();
    },

    async open360Tab() {
      this.tab = '360';
      await this.on360Tab();
    },

    async on360Tab() {
      if (this.view360ClientId) await this.loadClient360();
      await this.refreshAutoSyncStatus();
    },

    stat360(key) {
      const stats = this.client360 && this.client360.stats;
      if (!stats || stats[key] == null) return 0;
      return stats[key];
    },

    linkProjectsForClient() {
      if (!this.view360ClientId) return [];
      return (this.client360.projects || []).length
        ? this.client360.projects
        : this.linkProjects.filter((p) => p.client_id === Number(this.view360ClientId));
    },

    async loadClient360() {
      if (!this.view360ClientId) return;
      try {
        const data = await Cockpit.api('/clients/' + this.view360ClientId + '/360');
        if (!data.ok) throw new Error(data.error || '360 laden mislukt');
        this.client360 = data;
        this.linkProjects = data.projects || [];
      } catch (e) {
        Cockpit.toast('360: ' + (e.message || e), 'error');
      }
    },

    async linkNasFile() {
      const path = (this.linkPathInput || '').trim();
      if (!path || !this.view360ClientId) return;
      try {
        await Cockpit.api('/documents/links', {
          method: 'POST',
          body: JSON.stringify({
            storage_path: path,
            client_id: Number(this.view360ClientId),
            project_id: this.linkProjectId ? Number(this.linkProjectId) : null,
            is_folder: false,
          }),
        });
        Cockpit.toast('Bestand gekoppeld', 'success');
        await this.loadClient360();
      } catch (e) { Cockpit.toast(e.message, 'error'); }
    },

    async linkNasFolder() {
      let path = (this.linkPathInput || '').trim();
      if (!path || !this.view360ClientId) return;
      if (!path.endsWith('/')) path = path.replace(/\/[^/]+$/, '') || path;
      try {
        await Cockpit.api('/documents/links', {
          method: 'POST',
          body: JSON.stringify({
            storage_path: path,
            client_id: Number(this.view360ClientId),
            project_id: this.linkProjectId ? Number(this.linkProjectId) : null,
            is_folder: true,
          }),
        });
        Cockpit.toast('Map gekoppeld: ' + path, 'success');
        await this.loadClient360();
      } catch (e) { Cockpit.toast(e.message, 'error'); }
    },

    async unlinkDocument(linkId) {
      try {
        await Cockpit.api('/documents/links/' + linkId, { method: 'DELETE' });
        await this.loadClient360();
      } catch (e) { Cockpit.toast(e.message, 'error'); }
    },

    async runAutoSync(force) {
      this.autoSyncBusy = true;
      try {
        const data = await Cockpit.api('/brain/auto-sync' + (force ? '?force=true' : ''), { method: 'POST' });
        const brain = (data.steps || {}).brain_sync || {};
        Cockpit.toast('Sync: ' + (brain.synced || 0) + ' docs → second brain', 'success');
        await this.refreshAutoSyncStatus();
      } catch (e) {
        Cockpit.toast(e.message, 'error');
      } finally {
        this.autoSyncBusy = false;
      }
    },

    async refreshAutoSyncStatus() {
      try {
        const data = await Cockpit.api('/brain/auto-sync/status');
        const last = data.last;
        if (last && last.created_at) {
          this.autoSyncLabel = 'Laatste sync: ' + last.created_at.slice(0, 16) + ' (' + last.status + ')';
        }
      } catch (e) {}
    },

    async quickStage(c) {
      if (!c || !c.id) return;
      const prev = c._prevStage;
      const body = {
        name: c.name, contact: c.contact, email: c.email, stage: c.stage,
        sector: c.sector, mrr_estimate: c.mrr_estimate, notes: c.notes,
      };
      try {
        await Cockpit.api('/clients/' + c.id, { method: 'PUT', body: JSON.stringify(body) });
        Cockpit.toast((c.name || 'Klant') + ' → ' + this.stageLabel(c.stage), 'success');
        if (this.detail?.client?.id === c.id) this.detail.client.stage = c.stage;
        await this.loadAll();
      } catch (e) {
        if (prev) c.stage = prev;
        Cockpit.toast(e.message, 'error');
      }
    },

    stageSelectFocus(c) {
      c._prevStage = c.stage;
    },

    async searchStores(resetPage) {
      if (resetPage) this.storePage = 1;
      this.storeBusy = true;
      try {
        const params = this.buildStoreParams();
        const r = await fetch('/api/retail/list?' + params).then(x => x.json());
        this.storeResults = r.items || [];
        this.storeTotal = r.total != null ? r.total : (r.count || this.storeResults.length);
        if (this.selectedStore && !this.storeResults.find(s => s.id === this.selectedStore.id)) {
          this.selectedStore = null;
        }
      } catch (e) { Cockpit.toast(e.message, 'error'); }
      this.storeBusy = false;
    },

    buildStoreParams() {
      const params = new URLSearchParams({
        limit: String(this.storePageSize),
        offset: String((this.storePage - 1) * this.storePageSize),
        sort: this.storeSort || 'name',
      });
      if (this.storeQ) params.set('q', this.storeQ);
      if (this.storeChain) params.set('chain', this.storeChain);
      if (this.storeProvince) params.set('province', this.storeProvince);
      if (this.storeCity) params.set('city', this.storeCity);
      if (this.storePartnership) params.set('partnership', this.storePartnership);
      if (this.storePostcode) params.set('postcode_prefix', this.storePostcode);
      if (this.storeMinHalalOpp != null && this.storeMinHalalOpp !== '') params.set('min_halal_opportunity', String(this.storeMinHalalOpp));
      if (this.storeHalalGap) params.set('halal_gap_only', 'true');
      if (this.storeHalalCert) params.set('halal_certified', 'true');
      if (this.storeHalalSection) params.set('has_halal_section', 'true');
      if (this.storeLinkedCrm) params.set('linked_to_crm', 'true');
      if (this.storeHasPhone) params.set('has_phone', 'true');
      if (this.storeHasEmail) params.set('has_email', 'true');
      if (this.storeHasManager) params.set('has_manager', 'true');
      return params;
    },

    resetStoreFilters() {
      this.storeQ = '';
      this.storeChain = '';
      this.storeProvince = '';
      this.storeCity = '';
      this.storePartnership = '';
      this.storeSort = 'name';
      this.storePostcode = '';
      this.storeMinHalalOpp = null;
      this.storeHalalGap = false;
      this.storeHalalCert = false;
      this.storeHalalSection = false;
      this.storeLinkedCrm = false;
      this.storeHasPhone = false;
      this.storeHasEmail = false;
      this.storeHasManager = false;
      this.storePage = 1;
      this.searchStores(false);
    },

    storePageCount() {
      return Math.max(1, Math.ceil((this.storeTotal || 0) / this.storePageSize));
    },

    storeResultLabel() {
      const from = this.storeTotal ? (this.storePage - 1) * this.storePageSize + 1 : 0;
      const to = Math.min(this.storePage * this.storePageSize, this.storeTotal);
      return from + '–' + to + ' van ' + this.storeTotal + ' filialen';
    },

    storePrevPage() {
      if (this.storePage <= 1) return;
      this.storePage -= 1;
      this.searchStores(false);
    },

    storeNextPage() {
      if (this.storePage >= this.storePageCount()) return;
      this.storePage += 1;
      this.searchStores(false);
    },

    async selectStore(id) {
      try {
        const r = await fetch('/api/retail/supermarkets/' + id).then(x => x.json());
        this.selectedStore = r;
        this.storeForm = {
          address: r.address || '', postcode: r.postcode || '', city: r.city || '',
          province: r.province || '', phone: r.phone || '', email: r.email || '',
          website: r.website || '', manager_name: r.manager_name || r.profile_manager || '',
          partnership_status: r.partnership_status || 'none',
          halal_certified: !!r.halal_certified, has_halal_section: !!r.has_halal_section,
          halal_certifier: r.halal_certifier || '',
        };
      } catch (e) { Cockpit.toast(e.message, 'error'); }
    },

    async saveStore() {
      if (!this.selectedStore) return;
      this.storeBusy = true;
      try {
        await fetch('/api/retail/supermarkets/' + this.selectedStore.id, {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(this.storeForm),
        }).then(r => { if (!r.ok) throw new Error('Opslaan mislukt'); return r.json(); });
        Cockpit.toast('Filiaaldata opgeslagen', 'success');
        await this.selectStore(this.selectedStore.id);
        await this.searchStores(false);
      } catch (e) { Cockpit.toast(e.message, 'error'); }
      this.storeBusy = false;
    },

    async linkStore() {
      if (!this.selectedStore || !this.linkForm.client_id) return;
      try {
        await fetch('/api/retail/supermarkets/' + this.selectedStore.id + '/link', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            client_id: parseInt(this.linkForm.client_id, 10),
            relationship_type: this.linkForm.relationship_type,
            partnership_status: this.storeForm.partnership_status !== 'none' ? this.storeForm.partnership_status : 'prospect',
            notes: this.linkForm.notes || null,
          }),
        }).then(r => { if (!r.ok) throw new Error('Koppelen mislukt'); return r.json(); });
        Cockpit.toast('Filiaal gekoppeld aan klant', 'success');
        await this.loadAll();
      } catch (e) { Cockpit.toast(e.message, 'error'); }
    },

    openStoreCreate() {
      this.newStore = { chain: '', name: '', address: '', postcode: '0000AA', city: '', province: '', phone: '', email: '' };
      this.storeCreateModal = true;
    },

    async createStore() {
      try {
        const r = await fetch('/api/retail/supermarkets', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(this.newStore),
        }).then(x => { if (!x.ok) throw new Error('Toevoegen mislukt'); return x.json(); });
        Cockpit.toast('Filiaal toegevoegd', 'success');
        this.storeCreateModal = false;
        await this.searchStores(false);
        if (r.item?.id) await this.selectStore(r.item.id);
      } catch (e) { Cockpit.toast(e.message, 'error'); }
    },
  };
}
</script>
{% endblock %}
