/**
 * First-run / replayable product quick guide (spotlight tour).
 */

const STORAGE_KEY = 'supermarkQuickGuideCompleted';
const LEGACY_STORAGE_KEY = 'onboardingCompleted';
const PAD = 10;
const SIDEBAR_EXPAND_MS = 360;

function t(key, fallback = '') {
  try {
    if (typeof window.getLocalizedMessage === 'function') {
      const msg = window.getLocalizedMessage(key);
      if (msg && msg !== key) return msg;
    }
    const msg = chrome.i18n.getMessage(key);
    if (msg) return msg;
  } catch (_) {
    /* ignore */
  }
  return fallback || key;
}

function isCompleted() {
  try {
    return Boolean(
      localStorage.getItem(STORAGE_KEY) || localStorage.getItem(LEGACY_STORAGE_KEY)
    );
  } catch (_) {
    return false;
  }
}

function markCompleted() {
  try {
    localStorage.setItem(STORAGE_KEY, 'true');
    localStorage.setItem(LEGACY_STORAGE_KEY, 'true');
  } catch (_) {
    /* ignore */
  }
}

function isMostlyInViewport(rect) {
  const vw = window.innerWidth;
  const vh = window.innerHeight;
  const visibleW = Math.min(rect.right, vw) - Math.max(rect.left, 0);
  const visibleH = Math.min(rect.bottom, vh) - Math.max(rect.top, 0);
  return visibleW >= 8 && visibleH >= 8;
}

/**
 * Resolve the first usable target from a comma-separated selector list.
 * @param {string} selector
 * @param {{ allowEmpty?: boolean }} [options]
 */
function resolveTarget(selector, options = {}) {
  if (!selector) return null;
  const allowEmpty = Boolean(options.allowEmpty);
  const candidates = String(selector)
    .split(',')
    .map((s) => s.trim())
    .filter(Boolean);

  for (const sel of candidates) {
    const el = document.querySelector(sel);
    if (!el) continue;

    const style = window.getComputedStyle(el);
    if (style.display === 'none' || style.visibility === 'hidden') continue;

    const rect = el.getBoundingClientRect();
    if (rect.width < 8) continue;
    if (!allowEmpty && rect.height < 8) continue;

    // Reject off-screen targets (e.g. collapsed sidebar slid out of view)
    if (rect.height >= 8 && !isMostlyInViewport(rect)) continue;
    if (allowEmpty && rect.height < 8) {
      const vw = window.innerWidth;
      const vh = window.innerHeight;
      if (rect.right < 0 || rect.left > vw || rect.bottom < 0 || rect.top > vh) continue;
    }

    return el;
  }
  return null;
}

function getGuideSteps() {
  return [
    {
      id: 'welcome',
      title: t('quickGuideWelcomeTitle', 'Welcome to SuperMark'),
      body: t(
        'quickGuideWelcomeBody',
        'A bookmark-driven new tab. This short guide highlights the main areas — you can replay it anytime from Settings → About.'
      )
    },
    {
      id: 'search',
      selector: '#search-form',
      title: t('quickGuideSearchTitle', 'Search the web'),
      body: t(
        'quickGuideSearchBody',
        'Search from the new tab. Click the engine icon to switch providers, or use Cmd/Ctrl + Enter for compare search (Pro).'
      )
    },
    {
      id: 'sidebar',
      selector: '#sidebar-container > aside.custom-width',
      title: t('quickGuideSidebarTitle', 'Bookmarks sidebar'),
      body: t(
        'quickGuideSidebarBody',
        'Browse Chrome bookmark folders, search bookmarks, and jump between roots from the left sidebar.'
      ),
      placeCard: 'right'
    },
    {
      id: 'quickLinks',
      selector: '.recently-visited-links-wrapper',
      title: t('quickGuideQuickLinksTitle', 'Recently visited links'),
      body: t(
        'quickGuideQuickLinksBody',
        'Your recently visited sites appear here for one-click access. Turn them on or off in Settings → Search.'
      ),
      allowEmpty: true,
      minHoleHeight: 72
    },
    {
      id: 'bookmarks',
      selector: '.bookmarks-container',
      title: t('quickGuideBookmarksTitle', 'Bookmark workspace'),
      body: t(
        'quickGuideBookmarksBody',
        'Preview or edit the current folder. Use AI Organize, AI Recommend, and Clear 404 from the header actions when available.'
      )
    },
    {
      id: 'chromeQuickIcons',
      selector: '.chrome-quick-icons',
      title: t('quickGuideChromeQuickIconsTitle', 'Chrome quick icons'),
      body: t(
        'quickGuideChromeQuickIconsBody',
        'Jump to History, Downloads, Passwords, Extensions, the Chrome Web Store, and Customize Chrome. Show or hide each icon in Settings → Navigation.'
      ),
      placeCard: 'left'
    },
    {
      id: 'settings',
      selector: '.settings-icon',
      title: t('quickGuideSettingsTitle', 'Settings & themes'),
      body: t(
        'quickGuideSettingsBody',
        'Open Settings for wallpapers, layout, plugins, Account plans, and more. Revisit this guide under About anytime.'
      ),
      placeCard: 'left'
    },
    {
      id: 'done',
      title: t('quickGuideDoneTitle', "You're ready"),
      body: t(
        'quickGuideDoneBody',
        'Explore at your own pace. For membership and AI quotas, open Settings → Account.'
      )
    }
  ];
}

class QuickGuide {
  constructor() {
    this.active = false;
    this.stepIndex = 0;
    this.steps = [];
    this.root = null;
    this.hole = null;
    this.card = null;
    this._startToken = 0;
    this._onKeyDown = this._onKeyDown.bind(this);
    this._onResize = this._onResize.bind(this);
    this._ensureRoot();
  }

  _ensureRoot() {
    this.root = document.getElementById('quick-guide-root');
    if (!this.root) {
      this.root = document.createElement('div');
      this.root.id = 'quick-guide-root';
      this.root.className = 'quick-guide-root';
      this.root.hidden = true;
      document.body.appendChild(this.root);
    }
  }

  async _prepareSidebar() {
    const sidebar = document.getElementById('sidebar-container');
    if (!sidebar?.classList.contains('collapsed')) return;
    document.getElementById('toggle-sidebar')?.click();
    await new Promise((resolve) => setTimeout(resolve, SIDEBAR_EXPAND_MS));
  }

  async start({ force = false } = {}) {
    if (this.active) {
      this.stop({ completed: false });
    }
    if (!force && isCompleted()) return false;

    const token = ++this._startToken;
    await this._prepareSidebar();
    if (token !== this._startToken) return false;

    this.steps = getGuideSteps().filter((step) => {
      if (!step.selector) return true;
      return Boolean(resolveTarget(step.selector, { allowEmpty: step.allowEmpty }));
    });
    // Always keep welcome + done; if middle steps all missing, still show those two.
    if (this.steps.length < 2) {
      this.steps = getGuideSteps().filter((s) => !s.selector);
    }

    this.stepIndex = 0;
    this.active = true;
    this.root.hidden = false;
    this.root.setAttribute('aria-modal', 'true');
    this.root.setAttribute('role', 'dialog');
    document.body.classList.add('quick-guide-open');
    window.addEventListener('keydown', this._onKeyDown);
    window.addEventListener('resize', this._onResize);
    window.addEventListener('scroll', this._onResize, true);
    this.renderStep();
    return true;
  }

  stop({ completed = true } = {}) {
    this._startToken += 1;
    if (!this.active && this.root.hidden) return;
    this.active = false;
    this.root.hidden = true;
    this.root.innerHTML = '';
    this.hole = null;
    this.card = null;
    document.body.classList.remove('quick-guide-open');
    window.removeEventListener('keydown', this._onKeyDown);
    window.removeEventListener('resize', this._onResize);
    window.removeEventListener('scroll', this._onResize, true);
    if (completed) markCompleted();
  }

  _onKeyDown(event) {
    if (!this.active) return;
    if (event.key === 'Escape') {
      event.preventDefault();
      this.stop({ completed: true });
    } else if (event.key === 'ArrowRight' || event.key === 'Enter') {
      event.preventDefault();
      this.next();
    } else if (event.key === 'ArrowLeft') {
      event.preventDefault();
      this.prev();
    }
  }

  _onResize() {
    if (!this.active) return;
    this.positionElements();
  }

  next() {
    if (this.stepIndex >= this.steps.length - 1) {
      this.stop({ completed: true });
      return;
    }
    this.stepIndex += 1;
    this.renderStep();
  }

  prev() {
    if (this.stepIndex <= 0) return;
    this.stepIndex -= 1;
    this.renderStep();
  }

  renderStep() {
    const step = this.steps[this.stepIndex];
    if (!step) {
      this.stop({ completed: true });
      return;
    }

    const isFirst = this.stepIndex === 0;
    const isLast = this.stepIndex === this.steps.length - 1;
    const target = resolveTarget(step.selector, { allowEmpty: step.allowEmpty });

    this.root.innerHTML = `
      <div class="quick-guide-backdrop" data-guide-skip="1"></div>
      <div class="quick-guide-hole" hidden></div>
      <div class="quick-guide-card" role="document">
        <div class="quick-guide-card-top">
          <span class="quick-guide-progress">${this.stepIndex + 1} / ${this.steps.length}</span>
          <button type="button" class="quick-guide-skip" data-guide-skip="1">${t('quickGuideSkip', 'Skip')}</button>
        </div>
        <h2 class="quick-guide-title">${step.title}</h2>
        <p class="quick-guide-body">${step.body}</p>
        <div class="quick-guide-actions">
          <button type="button" class="quick-guide-btn secondary" data-guide-prev="1" ${isFirst ? 'disabled' : ''}>
            ${t('quickGuideBack', 'Back')}
          </button>
          <button type="button" class="quick-guide-btn primary" data-guide-next="1">
            ${isLast ? t('quickGuideFinish', 'Got it') : t('quickGuideNext', 'Next')}
          </button>
        </div>
      </div>
    `;

    this.hole = this.root.querySelector('.quick-guide-hole');
    this.card = this.root.querySelector('.quick-guide-card');
    this.root.dataset.hasTarget = target ? '1' : '0';

    this.root.querySelector('[data-guide-next]')?.addEventListener('click', () => this.next());
    this.root.querySelector('[data-guide-prev]')?.addEventListener('click', () => this.prev());
    this.root.querySelectorAll('[data-guide-skip]').forEach((el) => {
      el.addEventListener('click', () => this.stop({ completed: true }));
    });

    if (target) {
      target.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' });
      requestAnimationFrame(() => this.positionElements());
      setTimeout(() => this.positionElements(), 280);
    } else {
      this.positionElements();
    }
  }

  positionElements() {
    if (!this.active || !this.card) return;
    const step = this.steps[this.stepIndex];
    const target = resolveTarget(step?.selector, { allowEmpty: step?.allowEmpty });

    if (!target || !this.hole) {
      if (this.hole) this.hole.hidden = true;
      this.card.classList.add('is-centered');
      this.card.style.top = '';
      this.card.style.left = '';
      this.card.style.transform = '';
      return;
    }

    const rect = target.getBoundingClientRect();
    const minH = Number(step?.minHoleHeight) || 0;
    const holeTop = Math.max(8, rect.top - PAD);
    const holeLeft = Math.max(8, rect.left - PAD);
    const holeWidth = Math.min(window.innerWidth - holeLeft - 8, Math.max(rect.width, 8) + PAD * 2);
    const holeHeight = Math.min(
      window.innerHeight - holeTop - 8,
      Math.max(rect.height, minH) + PAD * 2
    );

    this.hole.hidden = false;
    this.hole.style.top = `${holeTop}px`;
    this.hole.style.left = `${holeLeft}px`;
    this.hole.style.width = `${holeWidth}px`;
    this.hole.style.height = `${holeHeight}px`;

    this.card.classList.remove('is-centered');
    const cardRect = this.card.getBoundingClientRect();
    let top;
    let left;
    const place = step?.placeCard;

    if (place === 'right') {
      left = holeLeft + holeWidth + 16;
      top = Math.max(12, Math.min(holeTop + 20, window.innerHeight - cardRect.height - 12));
      if (left + cardRect.width > window.innerWidth - 12) {
        left = Math.max(12, window.innerWidth - cardRect.width - 12);
        top = Math.min(window.innerHeight - cardRect.height - 12, holeTop + holeHeight + 16);
      }
    } else if (place === 'left') {
      left = holeLeft - cardRect.width - 16;
      top = Math.max(12, Math.min(holeTop, window.innerHeight - cardRect.height - 12));
      if (left < 12) {
        left = Math.min(window.innerWidth - cardRect.width - 12, Math.max(12, holeLeft + holeWidth / 2 - cardRect.width / 2));
        top = Math.min(window.innerHeight - cardRect.height - 12, Math.max(12, holeTop - cardRect.height - 16));
      }
    } else {
      const spaceBelow = window.innerHeight - (holeTop + holeHeight);
      const placeBelow = spaceBelow >= cardRect.height + 24 || holeTop < cardRect.height + 24;
      top = placeBelow
        ? holeTop + holeHeight + 16
        : holeTop - cardRect.height - 16;
      left = holeLeft + holeWidth / 2 - cardRect.width / 2;
    }

    top = Math.min(Math.max(12, top), window.innerHeight - cardRect.height - 12);
    left = Math.min(Math.max(12, left), window.innerWidth - cardRect.width - 12);

    this.card.style.top = `${top}px`;
    this.card.style.left = `${left}px`;
    this.card.style.transform = 'none';
  }
}

const guide = new QuickGuide();

export function startQuickGuide(options = {}) {
  return guide.start({ force: true, ...options });
}

export function maybeStartQuickGuideOnFirstRun() {
  if (isCompleted()) return false;
  const run = () => guide.start({ force: false });
  if (document.readyState === 'complete') {
    setTimeout(run, 600);
  } else {
    window.addEventListener('load', () => setTimeout(run, 600), { once: true });
  }
  return true;
}

export function isQuickGuideCompleted() {
  return isCompleted();
}

window.SuperMarkQuickGuide = {
  start: startQuickGuide,
  maybeStart: maybeStartQuickGuideOnFirstRun,
  isCompleted: isQuickGuideCompleted
};

maybeStartQuickGuideOnFirstRun();
