/* ===================== PRELOADER ===================== */
(function () {
  const preloader   = document.querySelector('.preloader');
  const bar         = document.querySelector('.loader_progress');
  const percentEl   = document.querySelector('.loader_percent');
  const loaderVideo = document.querySelector('.loader_img video');

  // prevent page scroll while loading
  document.documentElement.classList.add('is-loading');
  document.body.classList.add('is-loading');

  // collect assets to track
  function unique(list) { return Array.from(new Set(list)); }

  const imgEls   = Array.from(document.images).filter(img => img.src);
  const vidEls   = Array.from(document.querySelectorAll('video')).filter(v => v.src);
  const extraEls = Array.from(document.querySelectorAll('[data-preload]'));

  const extraUrls = extraEls.flatMap(el =>
    String(el.getAttribute('data-preload') || '')
      .split(',').map(s => s.trim()).filter(Boolean)
  );

  const preloaders = [];

  // images
  imgEls.forEach(img => {
    preloaders.push(new Promise(res => {
      if (img.complete) return res();
      img.addEventListener('load', res, { once: true });
      img.addEventListener('error', res, { once: true });
    }));
  });

  // videos (including your preloader video)
  vidEls.forEach(v => {
    preloaders.push(new Promise(res => {
      if (v.readyState >= 2) return res();
      const done = () => res();
      v.addEventListener('loadeddata', done, { once: true });
      v.addEventListener('canplaythrough', done, { once: true });
      v.addEventListener('error', done, { once: true });
    }));
  });

  // web fonts
  if (document.fonts && document.fonts.ready) {
    preloaders.push(document.fonts.ready.catch(() => {}));
  }

  // GSAP & plugins existence (in case they load async)
  preloaders.push(new Promise(res => {
    let tries = 0;
    const need = ['gsap', 'ScrollToPlugin', 'Observer'];
    const tick = () => {
      const ok = window.gsap && need.every(n => window[n] || gsap?.plugins?.[n] || gsap?.core?.Globals?.().Plugins?.[n]);
      if (ok || tries > 200) return res(); // ~4s cap at 20ms steps
      tries++;
      setTimeout(tick, 20);
    };
    tick();
  }));

  // custom extra URLs (optional)
  unique(extraUrls).forEach(url => {
    preloaders.push(fetch(url, { cache: 'force-cache' }).catch(() => {}));
  });

  // optional: wait for your app init — call this when your other JS finished booting:
  const appReady = new Promise(res => {
    const timeout = setTimeout(res, 4000);
    window.addEventListener('app:ready', () => { clearTimeout(timeout); res(); }, { once: true });
  });
  preloaders.push(appReady);

  // progress UI
  let loaded = 0;
  const total = preloaders.length;

  function updateProgress() {
    const pct = Math.round((loaded / total) * 100);
    if (bar) gsap.to(bar, { width: pct + '%', duration: 0.2, ease: 'power1.out' });
    if (percentEl) percentEl.textContent = pct + '%';
  }

  const tracked = preloaders.map(p =>
    Promise.resolve(p).catch(() => {}).then(() => { loaded++; updateProgress(); })
  );

  Promise.all(tracked).then(() => {
    setTimeout(() => {
      if (!preloader) return;
      gsap.to(preloader, {
        autoAlpha: 0,
        duration: 0.6,
        ease: 'power2.out',
        onComplete() {
          preloader.style.display = 'none';
          document.documentElement.classList.remove('is-loading');
          document.body.classList.remove('is-loading');
          window.dispatchEvent(new Event('preloader:done'));
        }
      });
    }, 150);
  });

  // ensure the preloader video starts (some browsers pause it)
  if (loaderVideo) {
    const playTry = () => loaderVideo.play().catch(()=>{});
    document.addEventListener('visibilitychange', playTry);
    playTry();
  }
})();

/* ===================== APP ===================== */
addEventListener('DOMContentLoaded', () => {
  /* --------- Register GSAP plugins --------- */
  if (window.gsap) {
    gsap.registerPlugin(window.Observer, window.ScrollToPlugin);
  }

  /* --------- Team slider (2 rows) with autoplay + built-in pagination --------- */
  // Ensure you have <div class="swiper-pagination"></div> inside .team_slider
  const teamSlider = new Swiper('.team_slider', {
    slidesPerView: 3,
    grid: {
      rows: 2,
      fill: 'row'
    },
    spaceBetween: 20,

    // Use rewind (NOT loop) with grid to keep pagination correct
    loop: false,
    rewind: true,

    autoplay: {
      delay: 3000,
      disableOnInteraction: false,
      pauseOnMouseEnter: true
    },

    pagination: {
      el: '.team_slider .swiper-pagination',
      clickable: true
    },

    breakpoints: {
        0: { slidesPerView: 1.4, grid: { rows: 1 } },
        320: { slidesPerView: 1.8, grid: { rows: 1 } },
        480: { slidesPerView: 2, grid: { rows: 1 } },
        768: { slidesPerView: 2.6, grid: { rows: 1 } },
        1200: { slidesPerView: 3, grid: { rows: 2 } }
    }
  });

  /* --------- Modal open/close --------- */
  // Open: .button[data-modalname] -> fill .modal-form input[name="btn_name"], add .opened to .modal
  document.addEventListener("click", (e) => {
    const btn = e.target.closest(".button[data-modalname]");
    if (!btn) return;

    e.preventDefault();

    const modal = document.querySelector(".modal");
    if (!modal) return;

    const modalName = btn.getAttribute("data-modalname") || "";
    const input = modal.querySelector('.modal-form input[name="btn_name"]');
    if (input) input.value = modalName;

    modal.classList.add("opened");
  });

  // Close via .modal_close
  document.addEventListener("click", (e) => {
    if (e.target.closest(".modal_close")) {
      const opened = document.querySelector(".modal.opened");
      if (opened) opened.classList.remove("opened");
    }
  });

  // Close via overlay click
  document.addEventListener("click", (e) => {
    const opened = document.querySelector(".modal.opened");
    if (!opened) return;
    if (e.target === opened) opened.classList.remove("opened");
  });

  // Close via Esc
  document.addEventListener("keydown", (e) => {
    if (e.key === "Escape") {
      const opened = document.querySelector(".modal.opened");
      if (opened) opened.classList.remove("opened");
    }
  });

  /* --------- Fancybox binds (null-safe) --------- */
  if (window.Fancybox?.bind) {
    Fancybox.bind('[data-fancybox="gallery"]', {
      groupAll: true, dragToClose: true, Thumbs: false, animated: true,
      showClass: 'fancybox-fadeIn', hideClass: 'fancybox-fadeOut',
    });
    Fancybox.bind('.led_locations a', {
      groupAll: true, dragToClose: true, Thumbs: false, animated: true,
      showClass: 'fancybox-fadeIn', hideClass: 'fancybox-fadeOut',
    });
    Fancybox.bind('.billboard_animation a', {
      groupAll: true, dragToClose: true, Thumbs: false, animated: true,
      showClass: 'fancybox-fadeIn', hideClass: 'fancybox-fadeOut',
    });
  }

  /* --------- Logo shining --------- */
  const logoEl = document.querySelector('.logo-shine');
  if (logoEl) {
    gsap.set(logoEl, {'--angle': '0deg', scale:1});
    const tl = gsap.timeline({ repeat: -1, defaults:{ ease: "none" }});
    tl.to(logoEl, { duration: 1.8, '--angle': '140deg', ease: "power2.out" })
      .to(logoEl, { duration: 0.25, scale: 1.02, yoyo:true, repeat:1, ease:"power1.inOut" }, "<0.2")
      .to(logoEl, { duration: 1.2, '--angle': '290deg', ease: "power3.inOut" })
      .to(logoEl, { duration: 0.35, '--angle': '310deg', ease: "power4.out" })
      .to(logoEl, { duration: 0.6, '--angle': '360deg', ease: "power1.in" })
      .to({},     { duration: 0.25 });
  }

  /* --------- Menu toggler (all media) --------- */
  (function(){
    const toggler   = document.querySelector('.menu_toggler');
    const navbar    = document.querySelector('.menu_navbar');
    const menuClose = document.querySelector('.menu_close');

    if (toggler && navbar) {
      toggler.addEventListener('click', () => {
        toggler.classList.toggle('active');
        navbar.classList.toggle('active');
      });
    }
    if (menuClose && toggler && navbar) {
      menuClose.addEventListener('click', () => {
        toggler.classList.remove('active');
        navbar.classList.remove('active');
      });
    }
    document.addEventListener('click', (e) => {
      if (!navbar || !toggler) return;
      if (!navbar.contains(e.target) && !toggler.contains(e.target)) {
        toggler.classList.remove('active');
        navbar.classList.remove('active');
      }
    });
  })();

  /* --------- Scroller Setup (all media clicks) + Desktop-only snap --------- */
  const scroller = document.querySelector('.content'); // must be scrollable: height:100vh; overflow:auto;
  const sections = gsap.utils.toArray('.sec', scroller);
  const thumbs   = gsap.utils.toArray('.thumb');
  const serviceLinks = Array.from(document.querySelectorAll('.service_block .service_item'));
  const navLinks     = Array.from(document.querySelectorAll('.menu_navbar ul a'));

  if (window.gsap) gsap.registerPlugin(ScrollToPlugin, Observer);

  const mm = gsap.matchMedia();
  let index = 0, isAnimating = false;

  const isDesktop = () => window.matchMedia('(min-width: 1200px)').matches;

  function closeMenu() {
    const toggler = document.querySelector('.menu_toggler');
    const navbar  = document.querySelector('.menu_navbar');
    if (toggler && navbar) { toggler.classList.remove('active'); navbar.classList.remove('active'); }
  }

  function getHashFromHref(a) {
    const raw = a.getAttribute('href') || '';
    if (!raw) return '';
    try { return new URL(raw, location.href).hash || ''; }
    catch { return raw.startsWith('#') ? raw : ''; }
  }

  function resolveTargetEl(a) {
    const pickSecById = (id) =>
      id ? (scroller.querySelector('.sec#' + id) || scroller.querySelector('#' + id)?.closest('.sec')) : null;

    const hash = getHashFromHref(a);
    if (hash && hash !== '#') {
      const el = pickSecById(hash.slice(1)); if (el) return el;
    }
    if (a.dataset && a.dataset.target) {
      const id = a.dataset.target.replace(/^#/, ''); const el = pickSecById(id); if (el) return el;
    }
    if (a.id) {
      const el = pickSecById(a.id); if (el) return el;
    }
    return null;
  }

  function setActive(i){
    if (thumbs && thumbs.length) thumbs.forEach(btn => btn.classList.toggle('is-active', +btn.dataset.index === i));
    if (navLinks && navLinks.length) navLinks.forEach(a => a.classList.toggle('is-active', +a.dataset.index === i));
    if (serviceLinks && serviceLinks.length) serviceLinks.forEach(a => a.classList.toggle('is-active', +a.dataset.index === i));
  }

  function goTo(i) { // desktop snap
    if (!scroller || !sections.length) return;
    const next = Math.max(0, Math.min(sections.length - 1, i));
    if (next === index || isAnimating) return;
    index = next; isAnimating = true;
    gsap.to(scroller, {
      duration: 1, ease: "power2.inOut",
      scrollTo: { y: sections[index], offsetY: 0, autoKill: false },
      onComplete: () => { isAnimating = false; }
    });
    setActive(index);
  }

  function smoothToEl(el, dur = 0.7) { // mobile/tablet smooth scroll
    if (!el || !scroller) return;
    gsap.to(scroller, { duration: dur, ease: "power2.out", scrollTo: { y: el, offsetY: 0, autoKill: true } });
  }

  // Click handlers work on ALL media (desktop = snap; mobile/tablet = smooth scroll)
  function bindClickFor(a) {
    const targetEl = resolveTargetEl(a);
    const idx = targetEl ? sections.indexOf(targetEl) : -1;
    if (idx < 0) return;

    a.dataset.index = String(idx);
    a.addEventListener('click', (e) => {
      e.preventDefault();
      if (isDesktop()) { goTo(idx); }
      else { smoothToEl(targetEl); }
      closeMenu();
    });
  }

  serviceLinks.forEach(bindClickFor);
  navLinks.forEach(bindClickFor);
  if (thumbs && thumbs.length) {
    thumbs.forEach(btn => btn.addEventListener('click', () => {
      const i = parseInt(btn.dataset.index, 10) || 0;
      if (isDesktop()) goTo(i); else smoothToEl(sections[i]);
    }));
  }

  // DESKTOP-ONLY: wheel/touch + keyboard snap + active sync
  mm.add("(min-width: 1200px)", () => {
    if (!scroller || !sections.length) return;

    function throttle(fn, wait = 150) {
      let last = 0; return (...args) => { const now = Date.now(); if (now - last >= wait) { last = now; fn(...args); } };
    }
    function updateIndexFromScroll(){
      const top = scroller.scrollTop;
      let nearest = 0, best = Infinity;
      sections.forEach((sec, i) => {
        const d = Math.abs(sec.offsetTop - top);
        if (d < best) { best = d; nearest = i; }
      });
      if (nearest !== index && !isAnimating) { index = nearest; setActive(index); }
    }

    const wheelObs = Observer.create({
      target: scroller, type: "wheel,touch,pointer",
      wheelSpeed: 1, tolerance: 10, preventDefault: true, passive: false,
      onDown: () => (index < sections.length - 1) && goTo(index + 1),
      onUp:   () => (index > 0) && goTo(index - 1),
    });

    const keyObs = Observer.create({
      target: window, type: "key", preventDefault: true,
      onKeyDown(self) {
        const e = self.event, t = e?.target;
        if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) return;
        if ((e.key === "ArrowDown" || e.key === "PageDown") && index < sections.length - 1) goTo(index + 1);
        if ((e.key === "ArrowUp"   || e.key === "PageUp")   && index > 0)               goTo(index - 1);
      }
    });

    const scrollHandler = throttle(updateIndexFromScroll, 150);
    scroller.addEventListener('scroll', scrollHandler);
    setActive(0);

    // cleanup when leaving desktop
    return () => {
      wheelObs?.kill?.(); keyObs?.kill?.();
      scroller.removeEventListener('scroll', scrollHandler);
    };
  });

  /* ===================== COMBO CALCULATOR ===================== */
  (function(){
    const price  = { A:500000, B:400000, C:300000, D:100000 };
    const combos = { "ABC": 1000000, "ABCD": 1100000 };

    const boxes   = ["A","B","C","D"].map(id => document.getElementById(id)).filter(Boolean);
    const newSumEl= document.getElementById("newSum");
    const oldSumEl= document.getElementById("oldSum");
    const saveEl  = document.getElementById("saveNote");
    const tagEl   = document.getElementById("comboTag");
    const noteEl  = document.getElementById("comboNote");
    const listEl  = document.getElementById("selList");

    const fmt = n => (n ?? 0).toLocaleString('uz-UZ') + " so‘m";

    function selection(){
      return boxes.filter(b=>b.checked).map(b=>b.id).sort();
    }
    function sumNormal(sel){
      return sel.reduce((acc,id)=> acc + (price[id]||0), 0);
    }
    function applyView({oldVal=null, newVal, comboKey=null}){
      if (!newSumEl) return;

      if (oldVal !== null && oldVal !== newVal) {
        if (oldSumEl) {
          oldSumEl.style.display = "inline-block";
          oldSumEl.textContent = fmt(oldVal);
        }
        if (tagEl) {
          tagEl.style.display = "inline-block";
          tagEl.textContent = comboKey + " COMBO";
        }
        const diff = oldVal - newVal;
        const perc = Math.round(diff / oldVal * 100);
        if (saveEl) {
          saveEl.style.display = "block";
          saveEl.textContent = "Tejov: " + fmt(diff) + " (" + perc + "%)";
        }
        if (noteEl) noteEl.textContent = comboKey + " to‘plamiga maxsus combo narx qo‘llandi";
      } else {
        if (oldSumEl) oldSumEl.style.display = "none";
        if (tagEl) tagEl.style.display = "none";
        if (saveEl) saveEl.style.display = "none";
        if (noteEl) noteEl.textContent = "";
      }
      newSumEl.textContent = fmt(newVal);
    }
    function recalc(){
      const sel = selection();

      boxes.forEach(b=>{
        const parent = b.closest(".box");
        if (!parent) return;
        parent.classList.toggle("selected", b.checked);
      });

      if (listEl) listEl.textContent = "Tanlangan: " + (sel.length ? sel.join(", ") : "–");

      const key = sel.join("");
      if (combos[key] !== undefined) {
        const oldVal = sumNormal(sel);
        const newVal = combos[key];
        applyView({oldVal, newVal, comboKey:key});
        return;
      }
      const total = sumNormal(sel);
      applyView({newVal: total});
    }

    boxes.forEach(b => b && b.addEventListener('change', recalc));

    const pickABC  = document.getElementById("pickABC");
    const pickABCD = document.getElementById("pickABCD");
    const resetBtn = document.getElementById("reset");

    if (pickABC)  pickABC.onclick  = ()=>{ boxes.forEach(b=> b.checked = ["A","B","C"].includes(b.id)); recalc(); };
    if (pickABCD) pickABCD.onclick = ()=>{ boxes.forEach(b=> b.checked = ["A","B","C","D"].includes(b.id)); recalc(); };
    if (resetBtn) resetBtn.onclick = ()=>{ boxes.forEach(b=> b.checked = false); recalc(); };

    recalc();
  })();
});
