'use strict';

(function () {
  var reduceMotion =
    window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  /* ------------------------------------------------------------------
     Scroll reveal: "hoisting" for flags, strips and content blocks.
     Adds the class `visible` once an element enters the viewport.
     ------------------------------------------------------------------ */
  function initReveal() {
    var targets = Array.prototype.slice.call(
      document.querySelectorAll('.reveal, .flag-hoist, .strip-reveal')
    );
    if (!targets.length) return;

    if (reduceMotion || !('IntersectionObserver' in window)) {
      targets.forEach(function (el) {
        el.classList.add('visible');
      });
      return;
    }

    // 120ms stagger per row/step inside sequences of repeated items.
    var groups = document.querySelectorAll('.svc-list, .steps, .team-grid, .stats-band__inner');
    Array.prototype.forEach.call(groups, function (group) {
      Array.prototype.forEach.call(group.children, function (child, index) {
        var delay = index * 120 + 'ms';
        if (child.matches('.reveal, .flag-hoist, .strip-reveal')) {
          child.style.transitionDelay = delay;
        }
        Array.prototype.forEach.call(
          child.querySelectorAll('.reveal, .flag-hoist, .strip-reveal'),
          function (el) {
            el.style.transitionDelay = delay;
          }
        );
      });
    });

    var observer = new IntersectionObserver(
      function (entries) {
        entries.forEach(function (entry) {
          if (!entry.isIntersecting) return;
          entry.target.classList.add('visible');
          observer.unobserve(entry.target);
        });
      },
      { threshold: 0.12, rootMargin: '0px 0px -5% 0px' }
    );

    targets.forEach(function (el) {
      observer.observe(el);
    });
  }

  /* ------------------------------------------------------------------
     Scroll-to-top button (present on pages that carry the markup).
     Page scroll is read from window; the visible state is toggled on
     the button itself.
     ------------------------------------------------------------------ */
  function initScrollTop() {
    var buttons = Array.prototype.slice
      .call(document.querySelectorAll('#scroll-top, .scroll-to-top'))
      .filter(function (el, index, all) {
        return all.indexOf(el) === index;
      });
    if (!buttons.length) return;

    function currentScroll() {
      return window.scrollY || window.pageYOffset || document.documentElement.scrollTop || 0;
    }

    function update() {
      var show = currentScroll() > 400;
      buttons.forEach(function (button) {
        button.classList.toggle('visible', show);
      });
    }

    window.addEventListener('scroll', update, { passive: true });
    update();

    buttons.forEach(function (button) {
      button.addEventListener('click', function () {
        if (reduceMotion) {
          window.scrollTo(0, 0);
          return;
        }
        window.scrollTo({ top: 0, behavior: 'smooth' });
      });
    });
  }

  /* ------------------------------------------------------------------
     Contact form (no backend): validates, then opens a mailto message.
     Adding an `action` attribute to the form hands over to a real endpoint.
     ------------------------------------------------------------------ */
  var COURSE_LABELS = {
    proveseiling: 'Prøveseiling',
    nybegynnerkurs: 'Nybegynnerkurs',
    'videregaende-kurs': 'Videregående kurs',
    skipperkurs: 'Skipperkurs',
    teorikurs: 'Teorikurs til båtførerprøven',
    'seilleir-barn': 'Seilleir for barn 9–13 år',
    ungdomsgruppe: 'Ungdomsgruppe 14–18 år',
  };

  var MAIL_TO = 'post@vindkastseilskole.no';
  var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

  function initContactForm() {
    var form = document.getElementById('contact-form');
    if (!form) {
      if (document.querySelector('.contact')) {
        console.error('[contact-form] #contact-form not found');
      }
      return;
    }

    var success = document.getElementById('form-success');
    var resetButton = document.getElementById('form-reset');
    var submitButton = document.getElementById('form-submit');
    var nameInput = document.getElementById('navn');
    var emailInput = document.getElementById('epost');
    var phoneInput = document.getElementById('telefon');
    var courseSelect = document.getElementById('kurs');
    var periodInput = document.getElementById('periode');
    var messageInput = document.getElementById('melding');

    if (!success || !submitButton || !nameInput || !emailInput || !courseSelect) {
      console.error(
        '[contact-form] required form elements are missing (#form-success, #form-submit, #navn, #epost, #kurs)'
      );
      return;
    }

    form.noValidate = true;

    var errorBoxes = {
      navn: document.getElementById('navn-error'),
      epost: document.getElementById('epost-error'),
    };

    // Which parts of the form are hidden on success (works whether the
    // success panel sits inside or outside the <form>).
    var hideableParts = form.contains(success)
      ? Array.prototype.filter.call(form.children, function (child) {
          return child !== success && !child.contains(success);
        })
      : [form];

    // Honest fallback note: the form is not connected to a server.
    var fallbackNote = document.createElement('p');
    fallbackNote.className = 'ck-form__note';
    fallbackNote.textContent =
      'Åpnet ikke e-postprogrammet? Send meldingen til ' + MAIL_TO + ' eller ring 33 31 50 13.';
    var successTitle = success.querySelector('.ck-form__success-title');
    if (successTitle) {
      successTitle.textContent =
        'Takk! E-postprogrammet ditt åpnes med meldingen klar til å sendes.';
    }
    if (resetButton && resetButton.parentNode === success) {
      success.insertBefore(fallbackNote, resetButton);
    } else {
      success.appendChild(fallbackNote);
    }
    success.setAttribute('tabindex', '-1');

    // Preselect course from ?kurs=
    preselectCourse(courseSelect);

    function setError(input, box, message) {
      if (message) {
        input.setAttribute('aria-invalid', 'true');
        if (box) {
          box.textContent = message;
          box.hidden = false;
          input.setAttribute('aria-describedby', box.id);
        }
      } else {
        input.removeAttribute('aria-invalid');
        if (box) {
          box.textContent = '';
          box.hidden = true;
          input.removeAttribute('aria-describedby');
        }
      }
    }

    function validateName() {
      var ok = nameInput.value.trim().length > 0;
      setError(nameInput, errorBoxes.navn, ok ? '' : 'Fyll ut dette feltet.');
      return ok;
    }

    function validateEmail() {
      var value = emailInput.value.trim();
      var message = '';
      if (!value) {
        message = 'Fyll ut dette feltet.';
      } else if (!EMAIL_PATTERN.test(value)) {
        message = 'Skriv en gyldig e-postadresse.';
      }
      setError(emailInput, errorBoxes.epost, message);
      return !message;
    }

    nameInput.addEventListener('input', function () {
      if (nameInput.getAttribute('aria-invalid')) validateName();
    });
    emailInput.addEventListener('input', function () {
      if (emailInput.getAttribute('aria-invalid')) validateEmail();
    });

    function selectedExperience() {
      var checked = form.querySelector('input[name="erfaring"]:checked');
      if (!checked) return '';
      var label = form.querySelector('label[for="' + checked.id + '"]');
      return label ? label.textContent.trim() : checked.value;
    }

    function buildMailto() {
      var courseOption = courseSelect.selectedOptions && courseSelect.selectedOptions[0];
      var courseText = courseOption ? courseOption.textContent.trim() : '';
      var lines = [
        'Navn: ' + nameInput.value.trim(),
        'E-post: ' + emailInput.value.trim(),
        'Telefon: ' + (phoneInput ? phoneInput.value.trim() : ''),
        'Kurs: ' + courseText,
        'Ønsket periode: ' + (periodInput ? periodInput.value.trim() : ''),
        'Erfaring: ' + selectedExperience(),
        '',
        'Melding:',
        messageInput ? messageInput.value.trim() : '',
      ];
      var subject =
        'Forespørsel' + (courseText && courseOption && courseOption.value ? ': ' + courseText : '');
      return (
        'mailto:' +
        MAIL_TO +
        '?subject=' +
        encodeURIComponent(subject) +
        '&body=' +
        encodeURIComponent(lines.join('\n'))
      );
    }

    function setFormVisible(visible) {
      hideableParts.forEach(function (part) {
        part.hidden = !visible;
      });
      success.hidden = visible;
    }

    form.addEventListener('submit', function (event) {
      // Upgrade path: with a real endpoint on the form, do not intercept.
      if (form.getAttribute('action')) return;
      event.preventDefault();

      var nameOk = validateName();
      var emailOk = validateEmail();
      if (!nameOk || !emailOk) {
        (nameOk ? emailInput : nameInput).focus();
        return;
      }

      submitButton.disabled = true;
      try {
        window.location.href = buildMailto();
        setFormVisible(false);
        success.focus();
      } finally {
        submitButton.disabled = false;
      }
    });

    if (resetButton) {
      resetButton.addEventListener('click', function () {
        form.reset();
        setError(nameInput, errorBoxes.navn, '');
        setError(emailInput, errorBoxes.epost, '');
        setFormVisible(true);
        nameInput.focus();
      });
    } else {
      console.error('[contact-form] #form-reset not found');
    }
  }

  function preselectCourse(select) {
    var param = new URLSearchParams(window.location.search).get('kurs');
    if (!param) return;
    var label = COURSE_LABELS[param];
    var match = null;
    Array.prototype.forEach.call(select.options, function (option) {
      if (match) return;
      var text = option.textContent.trim();
      if (option.value === param || (label && text.indexOf(label) === 0)) {
        match = option;
      }
    });
    if (match) select.value = match.value;
  }

  function init() {
    initReveal();
    initScrollTop();
    initContactForm();
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();
/* ============================================================
   NAVIGATION SCAFFOLD — DO NOT EDIT (managed by Orchestra)
   ============================================================ */
(function () {
  var nav = document.getElementById('ns-nav');
  var linksContainer = document.getElementById('ns-links');
  var burger = document.getElementById('ns-hamburger');
  var overlay = document.getElementById('ns-overlay');
  if (!nav || !linksContainer || !burger) return;

  var isOpen = false;

  function openMenu() {
    isOpen = true;
    linksContainer.classList.add('open');
    if (overlay) {
      overlay.classList.add('open');
      overlay.setAttribute('aria-hidden', 'false');
    }
    burger.setAttribute('aria-expanded', 'true');
    document.body.style.overflow = 'hidden';
  }

  function closeMenu() {
    isOpen = false;
    linksContainer.classList.remove('open');
    if (overlay) {
      overlay.classList.remove('open');
      overlay.setAttribute('aria-hidden', 'true');
    }
    burger.setAttribute('aria-expanded', 'false');
    document.body.style.overflow = '';
  }

  function toggleMenu() {
    if (isOpen) closeMenu();
    else openMenu();
  }

  // Event listeners
  burger.addEventListener('click', toggleMenu);
  if (overlay) overlay.addEventListener('click', closeMenu);

  linksContainer.querySelectorAll('a').forEach(function (link) {
    link.addEventListener('click', function () {
      if (window.innerWidth <= 768) closeMenu();
    });
  });

  // Keyboard — Escape closes menu
  document.addEventListener('keydown', function (e) {
    if (e.key === 'Escape' && isOpen) {
      closeMenu();
      burger.focus();
    }
  });

  // Resize safety — prevents double nav when resizing from mobile to desktop
  window.addEventListener(
    'resize',
    function () {
      if (window.innerWidth > 768 && isOpen) {
        closeMenu();
      }
    },
    { passive: true }
  );

  // Scroll effect — transparent to solid background
  window.addEventListener(
    'scroll',
    function () {
      nav.classList.toggle('scrolled', window.scrollY > 80);
    },
    { passive: true }
  );

  // Active link highlighting via IntersectionObserver
  var sections = [];
  linksContainer.querySelectorAll('a[href^="#"]').forEach(function (a) {
    var id = a.getAttribute('href').slice(1);
    var el = document.getElementById(id);
    if (el) sections.push({ el: el, link: a });
  });
  if (sections.length && 'IntersectionObserver' in window) {
    var obs = new IntersectionObserver(
      function (entries) {
        entries.forEach(function (entry) {
          if (entry.isIntersecting) {
            linksContainer.querySelectorAll('a').forEach(function (a) {
              a.classList.remove('active');
            });
            sections.forEach(function (s) {
              if (s.el === entry.target) s.link.classList.add('active');
            });
          }
        });
      },
      { rootMargin: '-20% 0px -70% 0px', threshold: 0 }
    );
    sections.forEach(function (s) {
      obs.observe(s.el);
    });
  }
})();

/* ============================================================
   NAV CONTROLS SCAFFOLD — DO NOT EDIT (managed by Orchestra)
   ------------------------------------------------------------
   Wires the optional right-slot controls (search trigger, theme
   toggle) to their behaviour. Both branches are guarded by an
   element-existence check, so this block is inert on builds that
   don't opt in to controls.

   TRIGGERED-COMPONENT INVARIANT (see core/nav_scaffold.py docstring):
   • #ns-search-modal defaults to `hidden` + CSS `display:none`.
   • Open state is set ONLY here, in response to a user click.
   • Close paths: backdrop click, close button, Escape key.
   • Re-opening focus returns to the trigger for keyboard users.

   Do not duplicate this logic in script.js. Do not pre-open the
   modal in markup. Open state belongs to the user, not the template.
   ============================================================ */
(function () {
  // ── Search modal ───────────────────────────────────────────────────────
  var trigger = document.getElementById('ns-search-trigger');
  var modal = document.getElementById('ns-search-modal');
  if (trigger && modal) {
    var input = modal.querySelector('#ns-search-input');
    var closers = modal.querySelectorAll('[data-ns-search-close]');

    // Function EXPRESSIONS, not declarations. A `function foo() {}` inside an
    // `if` block is `no-inner-declarations`, and this template shipped three of
    // them into every static_site and nye_eventyr build — where the Developer
    // is forbidden to fix them, because this is the reserved `ns-` namespace.
    // Measured on marstrand-bokbinderi: all 6 of its eslint errors were in this
    // file's output, the build was filed `partial` for them, and a --bugfix run
    // then burned all three of its capped attempts on code it may not touch.
    // Both are declared before the listeners below that call them, so the
    // behaviour is identical.
    var openSearch = function () {
      modal.removeAttribute('hidden');
      modal.classList.add('open');
      modal.setAttribute('aria-hidden', 'false');
      trigger.setAttribute('aria-expanded', 'true');
      document.body.style.overflow = 'hidden';
      if (input)
        setTimeout(function () {
          input.focus();
        }, 30);
    };
    var closeSearch = function () {
      modal.classList.remove('open');
      modal.setAttribute('hidden', '');
      modal.setAttribute('aria-hidden', 'true');
      trigger.setAttribute('aria-expanded', 'false');
      document.body.style.overflow = '';
      trigger.focus();
    };

    trigger.addEventListener('click', openSearch);
    closers.forEach(function (el) {
      el.addEventListener('click', closeSearch);
    });
    document.addEventListener('keydown', function (e) {
      if (e.key === 'Escape' && modal.classList.contains('open')) closeSearch();
    });
  }

  // ── Theme toggle ───────────────────────────────────────────────────────
  // Sets `data-theme` on <html>; consumer CSS variables read from that
  // attribute (`:root[data-theme="light"] { ... }`) to recolour the site.
  // Persisted in localStorage so the choice survives reloads.
  var themeBtn = document.getElementById('ns-theme-toggle');
  if (themeBtn) {
    var STORAGE_KEY = 'orch-theme';

    // Expression, not a declaration — see the openSearch note below.
    var applyTheme = function (t) {
      document.documentElement.setAttribute('data-theme', t);
      themeBtn.setAttribute('aria-pressed', t === 'light' ? 'true' : 'false');
    };

    var stored = null;
    try {
      stored = localStorage.getItem(STORAGE_KEY);
    } catch (_) {
      /* storage blocked (private mode / 3rd-party cookies off) */
    }
    applyTheme(stored === 'light' ? 'light' : 'dark');

    themeBtn.addEventListener('click', function () {
      var current = document.documentElement.getAttribute('data-theme');
      var next = current === 'light' ? 'dark' : 'light';
      try {
        localStorage.setItem(STORAGE_KEY, next);
      } catch (_) {
        /* storage blocked: the theme still applies for this page */
      }
      applyTheme(next);
    });
  }
})();
/* END NAVIGATION SCAFFOLD */

/* ============================================================
   NAV PAGE-ACTIVE SCAFFOLD — DO NOT EDIT (managed by Orchestra)
   Multi-page builds: mark the current page's nav link .active by
   matching normalised pathnames. Works under file://, http(s)://,
   index/root, trailing slash, and extension-less routes.
   ============================================================ */
(function () {
  var links = document.getElementById('ns-links');
  if (!links) return;
  function pageKey(p) {
    try {
      p = decodeURIComponent(p || '');
    } catch (_) {
      /* malformed %-escape: fall through with the raw path */
    }
    p = p.split('#')[0].split('?')[0].replace(/\\/g, '/');
    var seg = p.substring(p.lastIndexOf('/') + 1).toLowerCase();
    if (seg === '' || seg === 'index.html' || seg === 'home.html') return 'index.html';
    if (seg.indexOf('.') === -1) seg += '.html';
    return seg;
  }
  var current = pageKey(window.location.pathname || window.location.href);
  links.querySelectorAll('a').forEach(function (a) {
    var href = a.getAttribute('href') || '';
    if (href.charAt(0) === '#') return; // in-page anchor, not a page link
    if (pageKey(href) === current) {
      a.classList.add('active');
      a.setAttribute('aria-current', 'page');
    } else {
      a.classList.remove('active');
      a.removeAttribute('aria-current');
    }
  });
})();
/* END NAV PAGE-ACTIVE SCAFFOLD */

/* ============================================================
   FOOTER SCAFFOLD — newsletter (managed by Orchestra)
   No backend on a static site: validate, confirm, done. A real
   endpoint is wired later by giving the form an action attribute.
   ============================================================ */
document.querySelectorAll('form[data-ns-newsletter]').forEach(function (form) {
  form.addEventListener('submit', function (event) {
    if (form.getAttribute('action')) return; // real endpoint wired — let it post
    event.preventDefault();
    var input = form.querySelector('input[type="email"]');
    if (input && !input.checkValidity()) {
      input.reportValidity();
      return;
    }
    var note = form.querySelector('[data-ns-newsletter-note]');
    if (note) {
      note.hidden = false;
      note.textContent = note.getAttribute('data-success') || note.textContent;
    }
    form.reset();
  });
});
/* END FOOTER SCAFFOLD */
