// =============================================================================
// Walkthrough Engine — Per-Page Onboarding Tours
// Self-contained: no external dependencies, uses ConfigEntry for persistence.
// Each page registers its own steps via Walkthrough.registerPage(pageId, steps).
// Completion is tracked per page: walkthrough_<pageId>_completed = '1'.
// =============================================================================

var Walkthrough = (function () {
    'use strict';

    // Registry: pageId → step array
    var _pages = {};
    var _active = false;
    var _currentStep = 0;
    var _currentPageId = null;
    var _backdrop = null;
    var _spotlight = null;
    var _tooltip = null;
    var _resizeTimer = null;

    // --- Page Registration ---

    function registerPage(pageId, steps) {
        if (!pageId || !Array.isArray(steps) || steps.length === 0) return;
        _pages[pageId] = steps;
    }

    // --- Public API ---

    function start(pageId) {
        if (_active) return;
        if (!pageId || !_pages[pageId]) return;
        _active = true;
        _currentPageId = pageId;
        _currentStep = 0;
        _createOverlay();
        _showStep(_currentStep);
    }

    function stop(markCompleted) {
        if (!_active) return;
        var pageId = _currentPageId;
        _active = false;
        _currentPageId = null;
        _destroyOverlay();
        if (markCompleted !== false && pageId) {
            ConfigEntry.set('walkthrough_' + pageId + '_completed', '1').catch(function () {});
        }
    }

    function maybeAutoStart(pageId) {
        if (_active) return;
        if (!pageId || !_pages[pageId]) return;
        var key = 'walkthrough_' + pageId + '_completed';
        ConfigEntry.get(key).then(function (val) {
            if (val === '1') return;
            // Delay to let the page finish rendering
            setTimeout(function () {
                if (!_active) start(pageId);
            }, 1200);
        }).catch(function () {});
    }

    function resetPage(pageId) {
        if (!pageId) return Promise.resolve();
        return ConfigEntry.set('walkthrough_' + pageId + '_completed', '');
    }

    // --- Overlay management ---

    function _createOverlay() {
        _backdrop = document.createElement('div');
        _backdrop.className = 'ck-wt-backdrop';
        _backdrop.addEventListener('click', function () { _advance(); });

        _spotlight = document.createElement('div');
        _spotlight.className = 'ck-wt-spotlight';

        _tooltip = document.createElement('div');
        _tooltip.className = 'ck-wt-tooltip';

        document.body.appendChild(_backdrop);
        document.body.appendChild(_spotlight);
        document.body.appendChild(_tooltip);

        document.addEventListener('keydown', _onKeyDown);
        window.addEventListener('resize', _onResize);
    }

    function _destroyOverlay() {
        if (_backdrop) { _backdrop.remove(); _backdrop = null; }
        if (_spotlight) { _spotlight.remove(); _spotlight = null; }
        if (_tooltip) { _tooltip.remove(); _tooltip = null; }
        document.removeEventListener('keydown', _onKeyDown);
        window.removeEventListener('resize', _onResize);
        if (_resizeTimer) { clearTimeout(_resizeTimer); _resizeTimer = null; }
    }

    // --- Step rendering ---

    function _getSteps() {
        return _pages[_currentPageId] || [];
    }

    function _showStep(index) {
        var steps = _getSteps();
        // Skip steps whose target element is missing
        while (index < steps.length && steps[index].target) {
            var el = document.querySelector(steps[index].target);
            if (el) break;
            index++;
        }
        if (index >= steps.length) { stop(true); return; }

        _currentStep = index;
        var step = steps[index];
        var targetEl = step.target ? document.querySelector(step.target) : null;

        // Position spotlight
        if (targetEl) {
            var rect = targetEl.getBoundingClientRect();
            var pad = 6;
            _spotlight.style.display = 'block';
            _spotlight.style.top = (rect.top - pad + window.scrollY) + 'px';
            _spotlight.style.left = (rect.left - pad) + 'px';
            _spotlight.style.width = (rect.width + pad * 2) + 'px';
            _spotlight.style.height = (rect.height + pad * 2) + 'px';
            _spotlight.style.borderRadius = '8px';
        } else {
            _spotlight.style.display = 'none';
        }

        // Build tooltip HTML
        var progress = (index + 1) + ' of ' + steps.length;
        _tooltip.innerHTML =
            '<div class="ck-wt-tooltip__title">' + _escHtml(step.title) + '</div>' +
            '<div class="ck-wt-tooltip__body">' + _escHtml(step.body) + '</div>' +
            '<div class="ck-wt-tooltip__footer">' +
                '<span class="ck-wt-tooltip__progress">' + progress + '</span>' +
                '<div class="ck-wt-tooltip__actions">' +
                    '<button class="ck-btn ck-btn--secondary ck-btn--sm ck-wt-skip-btn">Skip</button>' +
                    '<button class="ck-btn ck-btn--primary ck-btn--sm ck-wt-next-btn">' +
                        (index === steps.length - 1 ? 'Done' : 'Next') +
                    '</button>' +
                '</div>' +
            '</div>';

        _tooltip.querySelector('.ck-wt-skip-btn').addEventListener('click', function (e) {
            e.stopPropagation();
            stop(true);
        });
        _tooltip.querySelector('.ck-wt-next-btn').addEventListener('click', function (e) {
            e.stopPropagation();
            _advance();
        });

        // Position tooltip
        _positionTooltip(targetEl);
    }

    function _positionTooltip(targetEl) {
        if (!_tooltip) return;

        if (!targetEl) {
            // Center on screen
            _tooltip.style.top = '50%';
            _tooltip.style.left = '50%';
            _tooltip.style.transform = 'translate(-50%, -50%)';
            return;
        }

        _tooltip.style.transform = 'none';
        var rect = targetEl.getBoundingClientRect();
        var ttRect = _tooltip.getBoundingClientRect();
        var margin = 12;

        // Try below
        var top = rect.bottom + margin;
        var left = rect.left + (rect.width / 2) - (ttRect.width / 2);

        // Clamp horizontal
        if (left < 8) left = 8;
        if (left + ttRect.width > window.innerWidth - 8) {
            left = window.innerWidth - ttRect.width - 8;
        }

        // If below doesn't fit, try above
        if (top + ttRect.height > window.innerHeight - 8) {
            top = rect.top - ttRect.height - margin;
        }

        // If above doesn't fit either, just center vertically
        if (top < 8) {
            top = (window.innerHeight - ttRect.height) / 2;
        }

        _tooltip.style.top = top + 'px';
        _tooltip.style.left = left + 'px';
    }

    // --- Navigation ---

    function _advance() {
        if (!_active) return;
        var next = _currentStep + 1;
        if (next >= _getSteps().length) {
            stop(true);
        } else {
            _showStep(next);
        }
    }

    function _onKeyDown(e) {
        if (!_active) return;
        if (e.key === 'Escape') {
            e.preventDefault();
            stop(true);
        } else if (e.key === 'Enter' || e.key === 'ArrowRight') {
            e.preventDefault();
            _advance();
        }
    }

    function _onResize() {
        if (_resizeTimer) clearTimeout(_resizeTimer);
        _resizeTimer = setTimeout(function () {
            if (_active) _showStep(_currentStep);
        }, 150);
    }

    // --- Utility ---

    function _escHtml(str) {
        var div = document.createElement('div');
        div.textContent = str;
        return div.innerHTML;
    }

    // --- Expose ---

    return {
        registerPage: registerPage,
        start: start,
        stop: stop,
        maybeAutoStart: maybeAutoStart,
        resetPage: resetPage,
        get _active() { return _active; }
    };

})();


// =============================================================================
// First-Visit Banner — One-line page intro shown once per page
// Persisted via ConfigEntry: banner_<pageId>_dismissed = '1'
// Usage: Onboarding.showBanner(pageId, insertBeforeSelector, text, tourPageId?)
// =============================================================================

var Onboarding = (function () {
    'use strict';

    /**
     * Show a first-visit banner for a page.
     * @param {string} pageId - Unique page identifier (e.g. 'people')
     * @param {string} insertBeforeSelector - CSS selector; banner is inserted before this element
     * @param {string} text - The one-line description text
     * @param {string} [tourPageId] - If set, adds a "Take a tour" link that starts this walkthrough
     */
    function showBanner(pageId, insertBeforeSelector, text, tourPageId) {
        if (!pageId || !insertBeforeSelector || !text) return;

        var key = 'banner_' + pageId + '_dismissed';
        ConfigEntry.get(key).then(function (val) {
            if (val === '1') return;

            var anchor = document.querySelector(insertBeforeSelector);
            if (!anchor || !anchor.parentNode) return;

            var banner = document.createElement('div');
            banner.className = 'ck-onboard-banner';
            banner.setAttribute('data-page', pageId);

            var content = document.createElement('span');
            content.className = 'ck-onboard-banner__text';
            content.textContent = text;
            banner.appendChild(content);

            if (tourPageId && typeof Walkthrough !== 'undefined') {
                var tourLink = document.createElement('button');
                tourLink.className = 'ck-onboard-banner__tour';
                tourLink.textContent = 'Take a tour';
                tourLink.addEventListener('click', function (e) {
                    e.stopPropagation();
                    _dismissBanner(banner, key);
                    Walkthrough.start(tourPageId);
                });
                banner.appendChild(tourLink);
            }

            var closeBtn = document.createElement('button');
            closeBtn.className = 'ck-onboard-banner__close';
            closeBtn.innerHTML = '&#10005;';
            closeBtn.title = 'Dismiss';
            closeBtn.addEventListener('click', function (e) {
                e.stopPropagation();
                _dismissBanner(banner, key);
            });
            banner.appendChild(closeBtn);

            anchor.parentNode.insertBefore(banner, anchor);
        }).catch(function () {});
    }

    function _dismissBanner(el, key) {
        el.classList.add('ck-onboard-banner--hiding');
        ConfigEntry.set(key, '1').catch(function () {});
        setTimeout(function () { el.remove(); }, 250);
    }

    /**
     * Reset a banner so it shows again.
     */
    function resetBanner(pageId) {
        if (!pageId) return Promise.resolve();
        return ConfigEntry.set('banner_' + pageId + '_dismissed', '');
    }

    /**
     * Reset all banners and walkthroughs.
     */
    function resetAll() {
        var pages = ['home', 'people', 'conversations', 'discover', 'insights'];
        var promises = [];
        pages.forEach(function (p) {
            promises.push(Walkthrough.resetPage(p));
            promises.push(resetBanner(p));
        });
        // Also reset all hints
        var hintKeys = Hints._allKeys();
        hintKeys.forEach(function (k) {
            promises.push(ConfigEntry.set(k, ''));
        });
        return Promise.all(promises);
    }

    return {
        showBanner: showBanner,
        resetBanner: resetBanner,
        resetAll: resetAll
    };

})();


// =============================================================================
// Contextual Hints — One-time inline tips shown near specific elements
// Persisted via ConfigEntry: hint_<key>_shown = '1'
// Usage: Hints.show(key, targetSelector, text, position?)
// =============================================================================

var Hints = (function () {
    'use strict';

    var _shownThisSession = {};
    var _allRegisteredKeys = [];

    /**
     * Show a one-time contextual hint near a target element.
     * @param {string} key - Unique hint identifier (e.g. 'churn_dot')
     * @param {string} targetSelector - CSS selector for the anchor element
     * @param {string} text - Hint text
     * @param {object} [opts] - Options: { position: 'top'|'bottom'|'left'|'right', delay: ms }
     */
    function show(key, targetSelector, text, opts) {
        if (!key || !targetSelector || !text) return;
        if (_shownThisSession[key]) return;

        var configKey = 'hint_' + key + '_shown';
        if (_allRegisteredKeys.indexOf(configKey) === -1) _allRegisteredKeys.push(configKey);

        opts = opts || {};
        var delay = opts.delay || 0;

        ConfigEntry.get(configKey).then(function (val) {
            if (val === '1') return;
            _shownThisSession[key] = true;

            setTimeout(function () {
                var target = document.querySelector(targetSelector);
                if (!target) return;

                var hint = document.createElement('div');
                hint.className = 'ck-hint';
                hint.setAttribute('data-hint', key);
                hint.setAttribute('data-position', opts.position || 'bottom');

                var hintText = document.createElement('span');
                hintText.className = 'ck-hint__text';
                hintText.textContent = text;
                hint.appendChild(hintText);

                var closeBtn = document.createElement('button');
                closeBtn.className = 'ck-hint__close';
                closeBtn.innerHTML = '&#10005;';
                closeBtn.addEventListener('click', function (e) {
                    e.stopPropagation();
                    _dismissHint(hint, configKey);
                });
                hint.appendChild(closeBtn);

                // Position the hint relative to the target
                _positionHint(hint, target, opts.position || 'bottom');
                document.body.appendChild(hint);

                // Auto-dismiss after 12 seconds
                setTimeout(function () {
                    if (hint.parentNode) _dismissHint(hint, configKey);
                }, 12000);

            }, delay);
        }).catch(function () {});
    }

    function _positionHint(hint, target, position) {
        // Use fixed positioning based on target's bounding rect
        hint.style.position = 'fixed';
        hint.style.zIndex = '9999';

        // We need to add to DOM first to measure, then reposition
        hint.style.visibility = 'hidden';
        document.body.appendChild(hint);

        var tRect = target.getBoundingClientRect();
        var hRect = hint.getBoundingClientRect();
        var margin = 8;
        var top, left;

        switch (position) {
            case 'top':
                top = tRect.top - hRect.height - margin;
                left = tRect.left + (tRect.width / 2) - (hRect.width / 2);
                break;
            case 'left':
                top = tRect.top + (tRect.height / 2) - (hRect.height / 2);
                left = tRect.left - hRect.width - margin;
                break;
            case 'right':
                top = tRect.top + (tRect.height / 2) - (hRect.height / 2);
                left = tRect.right + margin;
                break;
            default: // bottom
                top = tRect.bottom + margin;
                left = tRect.left + (tRect.width / 2) - (hRect.width / 2);
                break;
        }

        // Clamp to viewport
        if (left < 8) left = 8;
        if (left + hRect.width > window.innerWidth - 8) left = window.innerWidth - hRect.width - 8;
        if (top < 8) top = 8;
        if (top + hRect.height > window.innerHeight - 8) top = window.innerHeight - hRect.height - 8;

        hint.style.top = top + 'px';
        hint.style.left = left + 'px';
        hint.style.visibility = 'visible';

        // Remove the extra DOM insertion (we re-appended above)
        hint.remove();
    }

    function _dismissHint(el, configKey) {
        el.classList.add('ck-hint--hiding');
        ConfigEntry.set(configKey, '1').catch(function () {});
        setTimeout(function () { if (el.parentNode) el.remove(); }, 250);
    }

    function _allKeys() {
        return _allRegisteredKeys.slice();
    }

    return {
        show: show,
        _allKeys: _allKeys
    };

})();
