<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/layout/concepcoes/ex-header-conceitual.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<!-- ===========================================================
     TEMPLATE DE REFERÊNCIA — Hero Header Sticky
     Padrão utilizado em: AgendaTerapeutaPage, ProfilePage
     ===========================================================

  ESTRUTURA GERAL
  ───────────────
  1. Sentinel (div 1px) + IntersectionObserver → detecta quando o header
     "cola" no topo da viewport e ativa a classe --stuck.
  2. Hero div com position:sticky, top: var(--layout-sticky-top, 56px).
     Layout 1 (classic): 56px (topbar fixed). Layout 2 (rail): 0px (topbar no fluxo).
  3. Dois estados:
     - Expandido : blobs decorativos visíveis, subtítulo, filtros e busca
     - Colado    : comprimido (max-height), apenas brand + ações essenciais
  4. Responsividade:
     - ≥1200px  : todos os controles inline (ag-hero__desktop-controls)
     - <1200px  : botão "Ações" abre Menu popup (ag-hero__mobile-controls)
       O menu mobile DEVE incluir "Buscar" abrindo um Dialog com input + resultados.

  SCRIPT (refs + onMounted)
  ─────────────────────────
  const headerSentinelRef = ref(null)
  const headerEl          = ref(null)
  const headerStuck       = ref(false)
  const headerMenuRef     = ref(null)

  const headerMenuItems = computed(() => [
    { label: 'Ação principal', icon: 'pi pi-plus',   command: () => acaoPrincipal() },
    { label: 'Buscar',         icon: 'pi pi-search', command: () => { searchModalOpen.value = true } },
    { separator: true },
    { label: 'Recarregar',     icon: 'pi pi-refresh', command: () => refetch() },
    { label: 'Configurações',  icon: 'pi pi-cog',     command: () => goSettings() },
  ])

  onMounted(() => {
    if (headerSentinelRef.value) {
      const io = new IntersectionObserver(
        ([entry]) => { headerStuck.value = !entry.isIntersecting },
        { rootMargin: `${document.querySelector('.l2-main') ? '0px' : '-56px'} 0px 0px 0px` }
      )
      io.observe(headerSentinelRef.value)
    }
  })

  CSS (scoped)
  ────────────
  Ver seção <style> ao final deste arquivo.

  BUSCA MOBILE
  ────────────
  O Dialog de busca deve ter o InputText DENTRO do dialog (não só resultados),
  com autofocus, compartilhando o mesmo v-model="search" do header desktop.
  Estados: sem texto → instrução | buscando → loading | sem resultado | lista.
=========================================================== -->

<!-- ── SENTINEL ─────────────────────────────────────────── -->
<div ref="headerSentinelRef" class="pg-sentinel" />

<!-- ── HERO HEADER ──────────────────────────────────────── -->
<div ref="headerEl" class="pg-hero mb-4" :class="{ 'pg-hero--stuck': headerStuck }">

  <!-- Blobs decorativos (some automaticamente quando colado via overflow:hidden) -->
  <div class="pg-hero__blobs" aria-hidden="true">
    <div class="pg-hero__blob pg-hero__blob--1" />
    <div class="pg-hero__blob pg-hero__blob--2" />
    <div class="pg-hero__blob pg-hero__blob--3" />
  </div>

  <!-- ── Linha 1: brand + controles ── -->
  <div class="pg-hero__row1">

    <!-- Brand: ícone + título + subtítulo (some quando colado) -->
    <div class="pg-hero__brand">
      <div class="pg-hero__icon">
        <i class="pi pi-ICON_AQUI text-lg" />
      </div>
      <div class="min-w-0">
        <div class="pg-hero__title">Título da Página</div>
        <div v-if="!headerStuck" class="pg-hero__sub">Subtítulo ou data/contexto atual</div>
      </div>
    </div>

    <!-- Controles desktop (≥1200px) -->
    <div class="pg-hero__desktop-controls">

      <!-- Grupo de busca (oculto quando colado) -->
      <div v-if="!headerStuck" class="w-[260px]">
        <FloatLabel variant="on">
          <IconField>
            <InputIcon class="pi pi-search" />
            <InputText v-model="search" class="w-full" autocomplete="off" @keyup.enter="searchModalOpen = true" />
          </IconField>
          <label>Buscar…</label>
        </FloatLabel>
      </div>

      <!-- Ações secundárias (ocultas quando colado, ex: filtros contextuais) -->
      <div v-if="!headerStuck" class="flex items-center gap-2">
        <!-- SplitButton, Dropdown, etc. -->
      </div>

      <!-- Ações primárias (sempre visíveis) -->
      <div class="flex items-center gap-1">
        <Button icon="pi pi-plus"    class="h-9 w-9 rounded-full" title="Ação principal" @click="acaoPrincipal" />
        <Button icon="pi pi-refresh" severity="secondary" outlined class="h-9 w-9 rounded-full" title="Recarregar" @click="refetch" />
        <Button icon="pi pi-cog"     severity="secondary" outlined class="h-9 w-9 rounded-full" title="Configurações" @click="goSettings" />
      </div>
    </div>

    <!-- Botão mobile (<1200px) -->
    <div class="pg-hero__mobile-controls">
      <Button label="Ações" icon="pi pi-ellipsis-v" severity="secondary" size="small" class="rounded-full"
              @click="(e) => headerMenuRef.toggle(e)" />
      <Menu ref="headerMenuRef" :model="headerMenuItems" :popup="true" />
    </div>
  </div>

  <!-- ── Linha 2: filtros/KPIs — oculta quando colado ── -->
  <div v-if="!headerStuck" class="pg-hero__row2">
    <div class="flex flex-wrap items-center gap-2">
      <!-- SelectButtons, Tags de filtro, KPIs clicáveis, etc. -->
      <Button class="!rounded-full" outlined severity="secondary">
        <span class="flex items-center gap-2">
          <i class="pi pi-list" /> Total: <b>{{ total }}</b>
        </span>
      </Button>
    </div>

    <!-- Chips de filtros ativos + limpar -->
    <div v-if="hasActiveFilters" class="flex items-center gap-2">
      <Tag value="Filtro ativo" severity="secondary" />
      <Button label="Limpar" icon="pi pi-filter-slash" severity="danger" outlined size="small" class="!rounded-full" @click="clearFilters" />
    </div>
  </div>
</div>


<!-- ── DIALOG DE BUSCA (mobile + desktop) ───────────────── -->
<!--
  REGRA: o InputText de busca FICA DENTRO do dialog.
  Isso garante boa UX no mobile (teclado não cobre resultados).
  O v-model="search" é o mesmo do header desktop — resultados sincronizados.
-->
<Dialog
  v-model:visible="searchModalOpen"
  modal
  header="Buscar"
  :style="{ width: '96vw', maxWidth: '720px' }"
  :breakpoints="{ '960px': '92vw', '640px': '96vw' }"
  :draggable="false"
>
  <div class="flex flex-col gap-3">
    <FloatLabel variant="on">
      <IconField>
        <InputIcon class="pi pi-search" />
        <InputText v-model="search" class="w-full" autocomplete="off" autofocus />
      </IconField>
      <label>Nome, e-mail, título…</label>
    </FloatLabel>

    <Divider class="my-0" />

    <div v-if="!searchTrim" class="text-color-secondary text-sm py-2">
      Digite para buscar.
    </div>
    <div v-else-if="searchLoading" class="text-color-secondary text-sm">Buscando…</div>
    <div v-else-if="!searchResults.length" class="text-color-secondary text-sm">
      Nenhum resultado para "<b>{{ searchTrim }}</b>".
    </div>
    <div v-else class="flex flex-col gap-2 max-h-[60vh] overflow-auto pr-1">
      <div class="text-xs text-color-secondary mb-1">{{ searchResults.length }} resultado(s)</div>
      <button
        v-for="r in searchResults" :key="r.id"
        class="text-left rounded-2xl border border-[var(--surface-border)] p-3 transition hover:shadow-sm"
        @click="gotoResultFromModal(r)"
      >
        <div class="font-medium truncate">{{ r.titulo || r.nome }}</div>
        <div class="mt-1 text-xs opacity-70 truncate">{{ r.subtitulo }}</div>
      </button>
    </div>
  </div>
  <template #footer>
    <Button label="Fechar" icon="pi pi-times" text @click="searchModalOpen = false" />
    <Button v-if="searchTrim" label="Limpar" icon="pi pi-eraser" severity="secondary" outlined class="rounded-full" @click="search = ''; searchModalOpen = false" />
  </template>
</Dialog>


<!-- ══════════════════════════════════════════════════════════
     CSS DE REFERÊNCIA (copiar para <style scoped> da página)
     Prefixo: "pg-" → substitua pelo prefixo da página (ag-, prof-, etc.)
     ══════════════════════════════════════════════════════════ -->
<style scoped>
/* Sentinel */
.pg-sentinel { height: 1px; }

/* Hero base */
.pg-hero {
  position: sticky;
  top: var(--layout-sticky-top, 56px); /* 56px Layout1 / 0px Layout2 (Rail) */
  z-index: 20;
  overflow: hidden;
  border-radius: 1.75rem;
  border: 1px solid var(--surface-border);
  background: var(--surface-card);
  padding: 1.25rem 1.5rem;
  max-height: 600px;
}

/* Estado colado */
.pg-hero--stuck {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  max-height: 64px;
  padding-top: 0.625rem;
  padding-bottom: 0.625rem;
}

/* Blobs decorativos */
.pg-hero__blobs { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.pg-hero__blob  { position: absolute; border-radius: 50%; filter: blur(70px); }
.pg-hero__blob--1 { width: 18rem; height: 18rem; top: -4rem;  right: -3rem;  background: rgba(99,102,241,0.12); }
.pg-hero__blob--2 { width: 20rem; height: 20rem; top: 0.5rem; left: -5rem;   background: rgba(52,211,153,0.09); }
.pg-hero__blob--3 { width: 14rem; height: 14rem; bottom: -2rem; right: 22%;  background: rgba(217,70,239,0.08); }

/* Linha 1 */
.pg-hero__row1 {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 1rem;
}
.pg-hero__brand {
  display: flex; align-items: center; gap: 0.75rem;
  flex-shrink: 0; min-width: 0;
}
.pg-hero__icon {
  display: grid; place-items: center;
  width: 2.5rem; height: 2.5rem; border-radius: 0.875rem;
  flex-shrink: 0;
  background: color-mix(in srgb, var(--p-primary-500, #6366f1) 12%, transparent);
  color: var(--p-primary-500, #6366f1);
}
.pg-hero__title {
  font-size: 1.1rem; font-weight: 700; letter-spacing: -0.02em;
  color: var(--text-color); white-space: nowrap;
}
.pg-hero__sub {
  font-size: 0.78rem; color: var(--text-color-secondary); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pg-hero__desktop-controls {
  flex: 1; display: flex; align-items: center;
  justify-content: flex-end; gap: 0.75rem; flex-wrap: wrap;
}
.pg-hero__mobile-controls { display: none; }

/* Linha 2 */
.pg-hero__row2 {
  position: relative; z-index: 1;
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 0.75rem;
  margin-top: 0.875rem; padding-top: 0.75rem;
  border-top: 1px solid var(--surface-border);
}

/* Mobile < 1200px */
@media (max-width: 1199px) {
  .pg-hero__desktop-controls { display: none; }
  .pg-hero__mobile-controls  { display: flex; margin-left: auto; }
  .pg-hero__row2             { display: none; }
}
</style>
