/* JustZix — onboarding / samouczek (coach-marks).
 * Samodzielny moduł ładowany przez options.html. Nie modyfikuje options.js.
 * Wariant wizualny: Glow. Teksty w pełni zlokalizowane (JZ_I18N, klucze onboard.*).
 *
 * API globalne: window.JZ_ONBOARD = { open(), start(id) }
 */
(function () {
  'use strict';

  var STORE_KEY = 'jzOnboarding';
  var state = { completed: false, firstRunDone: false };

  // Helpery — lokalizacja i ikony (tylko zestaw JustZix: JZ_ICONS).
  function t(key) {
    try { return JZ_I18N.t(key); } catch (e) { return key; }
  }
  function icon(name) {
    try { return (JZ_ICONS && JZ_ICONS[name]) || ''; } catch (e) { return ''; }
  }

  // ---- Scenariusze --------------------------------------------------------
  // Każdy krok: { target, place, interactive, code }. Tytuł i treść pobierane
  // z i18n po kluczu onboard.<scenario>.s<N>.title / .body (N = pozycja 1-based).
  var SCENARIOS = [{
    id: 'first-project',
    i18n: 'onboard.proj',
    steps: [
      { target: null, place: 'center' },
      { target: '#addFolderBtn', place: 'right', interactive: true },
      { target: '#folderName', place: 'bottom' },
      { target: '#folderUrlsInput', place: 'top' },
      { target: '#folderIcon', place: 'bottom' },
      { target: '#folderActionBarsBtn', place: 'top', interactive: true },
      { target: '#addActionBarBtn', place: 'bottom', interactive: true },
      { target: '#closeActionBarsBtn', place: 'top', interactive: true },
      { target: '#foldersList', place: 'right' },
      { target: '#addRuleInGroupBtn', place: 'top', interactive: true },
      { target: '#foldersList', place: 'right' },
      { target: '.editor-pane[data-pane="css"]', place: 'left',
        code: 'body { filter: grayscale(1); transition: filter .25s; }\nhtml.jz-demo-off body { filter: none; }' },
      { target: '.editor-tab[data-tab="js"]', place: 'bottom', interactive: true },
      { target: '.editor-pane[data-pane="js"]', place: 'left',
        code: 'alert("JustZix works on this page!");' },
      { target: '.editor-tab[data-tab="actions"]', place: 'bottom', interactive: true },
      { target: '.add-action-btn', place: 'top', interactive: true },
      { target: '.ab-code-edit', place: 'top', interactive: true },
      { target: '#actionCodeModal', place: 'left',
        code: "document.documentElement.classList.toggle('jz-demo-off');" },
      { target: null, place: 'center' }
    ]
  }];

  function scenarioById(id) {
    return SCENARIOS.filter(function (s) { return s.id === id; })[0] || null;
  }

  // ---- Stan / persystencja ------------------------------------------------
  function loadState(cb) {
    try {
      chrome.storage.local.get([STORE_KEY], function (d) {
        if (d && d[STORE_KEY] && typeof d[STORE_KEY] === 'object') {
          for (var k in d[STORE_KEY]) state[k] = d[STORE_KEY][k];
        }
        cb && cb();
      });
    } catch (e) { cb && cb(); }
  }
  function saveState() {
    try { chrome.storage.local.set({ [STORE_KEY]: state }); } catch (e) {}
  }

  // ---- Silnik coach-marków ------------------------------------------------
  var root = null, spot = null, ring = null, bubble = null;
  var scenario = null, stepIdx = 0;
  var pendingTarget = null, waitTimer = 0, layoutRaf = 0;
  var interactiveCleanup = null;

  function onKey(e) {
    if (e.key === 'Escape') { e.preventDefault(); e.stopPropagation(); skip(); }
  }

  function cleanup() {
    if (waitTimer) { clearInterval(waitTimer); waitTimer = 0; }
    if (interactiveCleanup) { interactiveCleanup(); interactiveCleanup = null; }
    window.removeEventListener('scroll', onLayout, true);
    window.removeEventListener('resize', onLayout);
    document.removeEventListener('keydown', onKey, true);
    if (root && root.parentNode) root.parentNode.removeChild(root);
    root = spot = ring = bubble = null;
    scenario = null;
  }

  function buildRoot() {
    root = document.createElement('div');
    root.className = 'jz-ob-root jz-ob-v-glow';
    spot = document.createElement('div'); spot.className = 'jz-ob-spot';
    ring = document.createElement('div'); ring.className = 'jz-ob-ring';
    bubble = document.createElement('div'); bubble.className = 'jz-ob-bubble';
    root.appendChild(spot); root.appendChild(ring); root.appendChild(bubble);
    document.body.appendChild(root);
    window.addEventListener('scroll', onLayout, true);
    window.addEventListener('resize', onLayout);
    document.addEventListener('keydown', onKey, true);
  }

  function onLayout() {
    if (layoutRaf) return;
    layoutRaf = requestAnimationFrame(function () { layoutRaf = 0; position(); });
  }

  function isVisible(el) {
    if (!el) return false;
    var r = el.getBoundingClientRect();
    return r.width > 1 && r.height > 1 && el.getClientRects().length > 0;
  }

  // Czeka aż cel pojawi się i będzie widoczny; po timeoucie zwraca null.
  function waitForTarget(sel, cb) {
    if (!sel) { cb(null); return; }
    var el = document.querySelector(sel);
    if (isVisible(el)) { cb(el); return; }
    var started = Date.now();
    waitTimer = setInterval(function () {
      var e = document.querySelector(sel);
      if (isVisible(e)) { clearInterval(waitTimer); waitTimer = 0; cb(e); }
      else if (Date.now() - started > 5200) { clearInterval(waitTimer); waitTimer = 0; cb(null); }
    }, 120);
  }

  function start(scenarioId) {
    var sc = scenarioById(scenarioId);
    if (!sc) return;
    closeLauncher();
    cleanup();
    scenario = sc;
    stepIdx = 0;
    buildRoot();
    goStep(0);
  }

  function goStep(i) {
    if (!scenario) return;
    if (i < 0) i = 0;
    if (i >= scenario.steps.length) { finish(); return; }
    stepIdx = i;
    if (waitTimer) { clearInterval(waitTimer); waitTimer = 0; }
    if (interactiveCleanup) { interactiveCleanup(); interactiveCleanup = null; }
    var step = scenario.steps[i];
    bubble.classList.remove('jz-ob-in');
    waitForTarget(step.target, function (el) {
      pendingTarget = el;
      renderStep(step, el);
    });
  }

  function renderStep(step, el) {
    var n = scenario.steps.length;
    var last = stepIdx === n - 1;
    var pct = Math.round(((stepIdx + 1) / n) * 100);
    var base = scenario.i18n + '.s' + (stepIdx + 1);
    bubble.innerHTML =
      '<div class="jz-ob-arrow"></div>' +
      '<div class="jz-ob-head">' +
        '<span class="jz-ob-badge">' + (stepIdx + 1) + '</span>' +
        '<span class="jz-ob-title"></span>' +
        '<button class="jz-ob-x" type="button" aria-label="' + t('onboard.ui.close') + '">&times;</button>' +
      '</div>' +
      '<div class="jz-ob-body"></div>' +
      (step.code ? '<div class="jz-ob-code"><pre></pre><button class="jz-ob-copy" type="button"></button></div>' : '') +
      (step.interactive && el ? '<div class="jz-ob-hint">' + icon('arrowRight') + '<span></span></div>' : '') +
      '<div class="jz-ob-foot">' +
        '<span class="jz-ob-progress">' +
          '<span class="jz-ob-bar"><span class="jz-ob-bar-fill" style="width:' + pct + '%"></span></span>' +
          '<span class="jz-ob-progress-txt">' + (stepIdx + 1) + ' / ' + n + '</span>' +
        '</span>' +
        '<span class="jz-ob-btns">' +
          (stepIdx > 0 ? '<button class="jz-ob-back" type="button"></button>' : '') +
          '<button class="jz-ob-next" type="button"></button>' +
        '</span>' +
      '</div>';
    bubble.querySelector('.jz-ob-title').textContent = t(base + '.title');
    bubble.querySelector('.jz-ob-body').innerHTML = t(base + '.body');
    bubble.querySelector('.jz-ob-x').addEventListener('click', skip);
    var nextBtn = bubble.querySelector('.jz-ob-next');
    nextBtn.textContent = last ? t('onboard.ui.finish') : t('onboard.ui.next');
    nextBtn.addEventListener('click', function () { goStep(stepIdx + 1); });
    var backBtn = bubble.querySelector('.jz-ob-back');
    if (backBtn) {
      backBtn.textContent = t('onboard.ui.back');
      backBtn.addEventListener('click', function () { goStep(stepIdx - 1); });
    }
    var hintSpan = bubble.querySelector('.jz-ob-hint span');
    if (hintSpan) hintSpan.textContent = t('onboard.ui.hint');

    if (step.code) {
      bubble.querySelector('.jz-ob-code pre').textContent = step.code;
      var copyBtn = bubble.querySelector('.jz-ob-copy');
      copyBtn.textContent = t('onboard.ui.copy');
      copyBtn.addEventListener('click', function () {
        try {
          navigator.clipboard.writeText(step.code).then(function () {
            copyBtn.textContent = t('onboard.ui.copied');
            copyBtn.classList.add('jz-ob-copied');
            setTimeout(function () {
              copyBtn.textContent = t('onboard.ui.copy');
              copyBtn.classList.remove('jz-ob-copied');
            }, 1600);
          });
        } catch (e) {}
      });
    }

    if (step.interactive && el) {
      var handler = function () { setTimeout(function () { goStep(stepIdx + 1); }, 220); };
      el.addEventListener('click', handler, { once: true });
      interactiveCleanup = function () { el.removeEventListener('click', handler); };
    }

    if (el && typeof el.scrollIntoView === 'function') {
      el.scrollIntoView({ block: 'center', inline: 'nearest', behavior: 'smooth' });
      setTimeout(position, 240);
    }
    position();
    requestAnimationFrame(function () { bubble.classList.add('jz-ob-in'); });
  }

  // Pozycjonowanie spotlightu, pierścienia i dymka względem celu.
  function position() {
    if (!root || !bubble) return;
    var el = pendingTarget;
    var r = (el && isVisible(el)) ? el.getBoundingClientRect() : null;
    var bw = bubble.offsetWidth || 340, bh = bubble.offsetHeight || 160;
    var vw = window.innerWidth, vh = window.innerHeight;
    var arrow = bubble.querySelector('.jz-ob-arrow');

    if (!r) {
      spot.style.display = 'none';
      ring.style.display = 'none';
      if (arrow) arrow.style.display = 'none';
      bubble.style.left = Math.round((vw - bw) / 2) + 'px';
      bubble.style.top = Math.round((vh - bh) / 2) + 'px';
      return;
    }

    var pad = 6;
    var hx = Math.max(0, r.left - pad), hy = Math.max(0, r.top - pad);
    var hw = r.width + pad * 2, hh = r.height + pad * 2;
    spot.style.display = ring.style.display = 'block';
    spot.style.left = ring.style.left = hx + 'px';
    spot.style.top = ring.style.top = hy + 'px';
    spot.style.width = ring.style.width = hw + 'px';
    spot.style.height = ring.style.height = hh + 'px';

    var gap = 18;
    var space = { bottom: vh - r.bottom, top: r.top, right: vw - r.right, left: r.left };
    var pl = step_().place || 'bottom';
    if (pl === 'center' || pl === 'auto') pl = 'bottom';
    var need = (pl === 'top' || pl === 'bottom') ? bh + gap : bw + gap;
    if (space[pl] < need) {
      pl = Object.keys(space).sort(function (a, b) { return space[b] - space[a]; })[0];
    }

    var left, top;
    if (pl === 'bottom') { top = r.bottom + gap; left = r.left + r.width / 2 - bw / 2; }
    else if (pl === 'top') { top = r.top - gap - bh; left = r.left + r.width / 2 - bw / 2; }
    else if (pl === 'right') { left = r.right + gap; top = r.top + r.height / 2 - bh / 2; }
    else { left = r.left - gap - bw; top = r.top + r.height / 2 - bh / 2; }
    left = Math.max(12, Math.min(left, vw - bw - 12));
    top = Math.max(12, Math.min(top, vh - bh - 12));
    bubble.style.left = Math.round(left) + 'px';
    bubble.style.top = Math.round(top) + 'px';

    if (arrow) {
      arrow.style.display = 'block';
      var ax, ay;
      if (pl === 'bottom') { ay = -7; ax = r.left + r.width / 2 - left - 7; }
      else if (pl === 'top') { ay = bh - 7; ax = r.left + r.width / 2 - left - 7; }
      else if (pl === 'right') { ax = -7; ay = r.top + r.height / 2 - top - 7; }
      else { ax = bw - 7; ay = r.top + r.height / 2 - top - 7; }
      arrow.style.left = Math.max(10, Math.min(ax, bw - 24)) + 'px';
      arrow.style.top = Math.max(10, Math.min(ay, bh - 24)) + 'px';
    }
  }
  function step_() { return (scenario && scenario.steps[stepIdx]) || {}; }

  function finish() {
    state.completed = true;
    saveState();
    cleanup();
  }
  function skip() { cleanup(); }

  // ---- Launcher (centrum samouczków) -------------------------------------
  var launcher = null;

  function onLauncherKey(e) {
    if (e.key === 'Escape') { e.preventDefault(); e.stopPropagation(); closeLauncher(); }
  }

  function openLauncher(firstRun) {
    if (launcher) return;
    launcher = document.createElement('div');
    launcher.className = 'jz-ob-launcher';
    var scensHtml = SCENARIOS.map(function (s) {
      return '<div class="jz-ob-scen">' +
        '<div class="jz-ob-scen-ico">' + icon('target') + '</div>' +
        '<div class="jz-ob-scen-txt">' +
          '<div class="jz-ob-scen-name">' + t(s.i18n + '.name') + '</div>' +
          '<div class="jz-ob-scen-desc">' + t(s.i18n + '.desc') + '</div>' +
          '<div class="jz-ob-scen-meta">' + t(s.i18n + '.meta') + '</div>' +
        '</div>' +
        '<button type="button" data-scen="' + s.id + '">' + t('onboard.lr.start') + '</button>' +
      '</div>';
    }).join('');
    launcher.innerHTML =
      '<div class="jz-ob-card">' +
        '<h2>' + (firstRun ? t('onboard.lr.titleFirst') : t('onboard.lr.title')) + '</h2>' +
        '<p class="jz-ob-lead">' + (firstRun ? t('onboard.lr.leadFirst') : t('onboard.lr.lead')) + '</p>' +
        '<div class="jz-ob-sect-t">' + t('onboard.lr.scenarios') + '</div>' +
        scensHtml +
        '<div class="jz-ob-launcher-foot">' +
          '<button class="jz-ob-skip" type="button">' + t('onboard.lr.later') + '</button>' +
          '<label><input type="checkbox" class="jz-ob-noauto"' + (state.firstRunDone ? ' checked' : '') + '> ' + t('onboard.lr.noAuto') + '</label>' +
        '</div>' +
      '</div>';
    document.body.appendChild(launcher);
    document.addEventListener('keydown', onLauncherKey, true);

    launcher.addEventListener('click', function (e) {
      if (e.target === launcher) closeLauncher();
    });
    Array.prototype.forEach.call(launcher.querySelectorAll('[data-scen]'), function (b) {
      b.addEventListener('click', function () { start(b.getAttribute('data-scen')); });
    });
    launcher.querySelector('.jz-ob-skip').addEventListener('click', closeLauncher);
    launcher.querySelector('.jz-ob-noauto').addEventListener('change', function (e) {
      state.firstRunDone = e.target.checked;
      saveState();
    });
  }

  function closeLauncher() {
    document.removeEventListener('keydown', onLauncherKey, true);
    if (launcher && launcher.parentNode) launcher.parentNode.removeChild(launcher);
    launcher = null;
  }

  // ---- Inicjalizacja ------------------------------------------------------
  function bindTutorialButton() {
    var btn = document.getElementById('tutorialBtn');
    if (btn) btn.addEventListener('click', function () {
      var menu = document.getElementById('settingsMenu');
      if (menu) menu.hidden = true;
      openLauncher(false);
    });
  }

  function init() {
    bindTutorialButton();
    loadState(function () {
      if (state.firstRunDone) return;
      // Pierwsze uruchomienie: brak katalogów → pokaż launcher.
      try {
        chrome.storage.local.get(['folders'], function (d) {
          var empty = !d || !Array.isArray(d.folders) || d.folders.length === 0;
          state.firstRunDone = true;
          saveState();
          if (empty) setTimeout(function () { openLauncher(true); }, 600);
        });
      } catch (e) {}
    });
  }

  window.JZ_ONBOARD = { open: function () { openLauncher(false); }, start: start };

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();
