---
import '@fontsource/montserrat/400.css';
import '@fontsource/montserrat/500.css';
import '@fontsource/montserrat/600.css';
import '@fontsource/montserrat/700.css';
import '@fontsource/open-sans/400.css';
import '@fontsource/open-sans/600.css';
import '../styles/global.css';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import { getDb } from '../lib/db';
import { getSessionUser, SESSION_COOKIE } from '../lib/auth';

interface Props { title: string; description?: string }
const { title, description = 'InsanityLab — Performance. Balance. Longevity. Allenamento personalizzato, piccoli gruppi e benessere a Bologna.' } = Astro.props;

const tok = Astro.cookies.get(SESSION_COOKIE)?.value;
const user = tok ? getSessionUser(getDb(), tok) : null;
const canTags = !!user && (user.role === 'superuser' || user.role === 'admin');
const wantTags = Astro.cookies.get('showtags')?.value === '1' || Astro.url.searchParams.get('annotate') === '1';
const showTags = canTags && wantTags;
---
<!doctype html>
<html lang="it">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>{title} — InsanityLab</title>
    <meta name="description" content={description} />
    <meta property="og:title" content={`${title} — InsanityLab`} />
    <meta property="og:description" content={description} />
    <meta property="og:type" content="website" />
    <meta property="og:image" content={new URL('/img/og.jpg', Astro.site)} />
    <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
    <link rel="sitemap" href="/sitemap.xml" />
    <script is:inline>document.documentElement.classList.add('js');</script>
  </head>
  <body>
    <Header user={user} showTags={showTags} canTags={canTags} />
    <main><slot /></main>
    <Footer />
    <script>
      // Reveal allo scroll: trigger a -100px dal viewport come il template Prowess.
      const io = new IntersectionObserver((entries) => {
        for (const e of entries) {
          if (e.isIntersecting) {
            e.target.classList.add('is-inview');
            io.unobserve(e.target);
            // A reveal concluso l'attributo va tolto, così la transition del reveal
            // non rallenta gli hover su transform del componente.
            e.target.addEventListener('transitionend', () => {
              e.target.removeAttribute('data-reveal');
            }, { once: true });
          }
        }
      }, { rootMargin: '0px 0px -100px 0px' });
      document.querySelectorAll('[data-reveal], .section-heading').forEach((el) => io.observe(el));

      const parallaxEls = document.querySelectorAll<HTMLElement>('[data-parallax]');
      if (parallaxEls.length && matchMedia('(min-width: 992px)').matches
        && !matchMedia('(prefers-reduced-motion: reduce)').matches) {
        let raf = 0;
        const update = () => {
          raf = 0;
          for (const el of parallaxEls) {
            const r = el.getBoundingClientRect();
            // Clamp entro il margine di sfondo (inset -120px) per non scoprire i bordi
            const y = Math.max(-110, Math.min(110, (r.top + r.height / 2 - innerHeight / 2) * -0.3));
            el.style.setProperty('--parallax-y', `${y.toFixed(1)}px`);
          }
        };
        addEventListener('scroll', () => { if (!raf) raf = requestAnimationFrame(update); }, { passive: true });
        update();
      }
    </script>
    {showTags && (
      <style is:global>
        [data-tag] { outline: 1px dashed #b8a98c; outline-offset: 2px; }
        .tag-badge { position: absolute; z-index: 9999; display: inline-flex; align-items: center; gap: 4px;
          background: #3a2929; color: #fff; font: 600 10px/1.6 monospace; padding: 0 4px 0 6px; opacity: .85; }
        .tag-badge:hover { opacity: 1; }
        .tag-badge__edit { background: #9c8b70; color: #fff; border: 0; cursor: pointer; font: inherit; padding: 0 5px; }
        .tag-modal { position: fixed; inset: 0; z-index: 10000; background: rgba(0,0,0,.5); display: flex; align-items: center; justify-content: center; }
        .tag-modal[hidden] { display: none; }
        .tag-modal__box { background: #fff; color: #222; width: min(560px, 92vw); max-height: 88vh; overflow: auto; padding: 20px; border-radius: 4px; }
        .tag-modal__box h3 { margin: 0 0 4px; font: 600 14px monospace; }
        .tag-modal__box .guid { font: 11px monospace; color: #888; margin: 0 0 14px; }
        .tag-modal__box textarea { width: 100%; min-height: 140px; font: inherit; padding: 8px; box-sizing: border-box; }
        .tag-modal__box select { margin: 6px 8px 6px 0; }
        .tag-modal__row { display: flex; gap: 10px; margin-top: 14px; }
        .tag-modal__row button { padding: 9px 16px; border: 0; cursor: pointer; }
        .tag-modal__save { background: #3a2d26; color: #fff; }
        .tag-modal__cancel { background: #ddd; }
        .tag-modal__msg { color: #a33; margin-top: 8px; min-height: 18px; }
      </style>
      <div class="tag-modal" id="tag-modal" hidden>
        <div class="tag-modal__box">
          <h3 id="tm-tag"></h3>
          <p class="guid" id="tm-guid"></p>
          <div id="tm-body"></div>
          <div class="tag-modal__msg" id="tm-msg"></div>
          <div class="tag-modal__row">
            <button type="button" class="tag-modal__save" id="tm-save">Salva</button>
            <button type="button" class="tag-modal__cancel" id="tm-cancel">Annulla</button>
          </div>
        </div>
      </div>
      <script is:inline>
        (() => {
          const STYLE_GROUPS = { size: ['s','m','l'], color: ['accent','accent-dark','dark','heading','text','text-light','white'], weight: ['normal','bold'], style: ['normal','italic'], align: ['left','center','right'] };
          const modal = document.getElementById('tag-modal');
          const tmTag = document.getElementById('tm-tag');
          const tmGuid = document.getElementById('tm-guid');
          const tmBody = document.getElementById('tm-body');
          const tmMsg = document.getElementById('tm-msg');
          const tmSave = document.getElementById('tm-save');
          let current = null; // { tag, type, el }

          function closeModal() { modal.hidden = true; tmBody.innerHTML = ''; tmMsg.textContent = ''; current = null; }
          document.getElementById('tm-cancel').addEventListener('click', closeModal);
          modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });

          async function openModal(tag, el) {
            tmMsg.textContent = '';
            let data;
            try {
              const res = await fetch('/api/admin/content/' + encodeURIComponent(tag));
              if (!res.ok) { alert('Impossibile caricare il contenuto.'); return; }
              data = await res.json();
            } catch { alert('Errore di rete.'); return; }
            current = { tag: data.tag, type: data.type, el };
            tmTag.textContent = data.tag;
            tmGuid.textContent = data.guid || '';
            tmBody.innerHTML = '';
            if (data.type === 'image') {
              const inp = document.createElement('input');
              inp.type = 'file'; inp.accept = 'image/*'; inp.id = 'tm-file';
              tmBody.appendChild(inp);
              const del = document.createElement('button');
              del.type = 'button'; del.textContent = 'Rimuovi immagine'; del.id = 'tm-del';
              del.style.cssText = 'margin-top:10px;padding:8px 14px;border:0;background:#a33;color:#fff;cursor:pointer';
              tmBody.appendChild(del);
              del.addEventListener('click', async () => {
                const r = await fetch('/api/admin/content/' + encodeURIComponent(current.tag) + '/image', { method: 'DELETE' });
                if (r.ok) { location.reload(); } else { tmMsg.textContent = 'Rimozione non riuscita.'; }
              });
            } else {
              const ta = document.createElement('textarea');
              ta.id = 'tm-value'; ta.value = data.value;
              tmBody.appendChild(ta);
              (data.styleOptions || []).forEach((group) => {
                const opts = STYLE_GROUPS[group];
                if (!opts) return;
                const sel = document.createElement('select');
                sel.dataset.group = group;
                sel.className = 'tm-style';
                const none = document.createElement('option');
                none.value = ''; none.textContent = group + ': —';
                sel.appendChild(none);
                opts.forEach((v) => { const o = document.createElement('option'); o.value = v; o.textContent = group + ': ' + v; sel.appendChild(o); });
                tmBody.appendChild(sel);
              });
            }
            modal.hidden = false;
          }

          tmSave.addEventListener('click', async () => {
            if (!current) return;
            tmMsg.textContent = '';
            if (current.type === 'image') {
              const file = document.getElementById('tm-file').files[0];
              if (!file) { tmMsg.textContent = 'Scegli un file.'; return; }
              const fd = new FormData(); fd.append('file', file);
              const r = await fetch('/api/admin/content/' + encodeURIComponent(current.tag) + '/image', { method: 'POST', body: fd });
              if (r.ok) { location.reload(); } else { tmMsg.textContent = (await r.json()).error || 'Upload non riuscito.'; }
              return;
            }
            const value = document.getElementById('tm-value').value;
            const styles = {};
            document.querySelectorAll('.tm-style').forEach((s) => { if (s.value) styles[s.dataset.group] = s.value; });
            const body = { value };
            if (Object.keys(styles).length) body.styles = styles;
            const r = await fetch('/api/admin/content/' + encodeURIComponent(current.tag), {
              method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body),
            });
            if (!r.ok) { tmMsg.textContent = (await r.json()).error || 'Salvataggio non riuscito.'; return; }
            const saved = await r.json();
            // Aggiorna in-place il contenuto nel DOM.
            if (current.type === 'html') current.el.innerHTML = saved.value;
            else current.el.textContent = saved.value;
            closeModal();
          });

          document.querySelectorAll('[data-tag]').forEach((el) => {
            const tag = el.dataset.tag;
            const guid = el.dataset.guid || '';
            const badge = document.createElement('span');
            badge.className = 'tag-badge';
            const label = document.createElement('span');
            label.textContent = guid ? tag + ' · ' + guid.slice(0, 8) : tag;
            const edit = document.createElement('button');
            edit.type = 'button'; edit.className = 'tag-badge__edit'; edit.textContent = '✎';
            edit.addEventListener('click', () => openModal(tag, el));
            badge.appendChild(label); badge.appendChild(edit);
            document.body.appendChild(badge);
            const place = () => {
              const r = el.getBoundingClientRect();
              badge.style.top = window.scrollY + r.top - 16 + 'px';
              badge.style.left = window.scrollX + r.left + 'px';
            };
            place();
            addEventListener('scroll', place, { passive: true });
            addEventListener('resize', place);
          });
        })();
      </script>
    )}
  </body>
</html>
