var headingList = [];
var menuList = [];
var bottomNavBtn;
var bottomNavBtnLabel;
var scrollBehaviorAvaliable = (function() {
	// 检测Chrome
    var v = navigator.userAgent.match(/Chrome\/(?<version>\S+)/);
    if (v && v.groups.version) {
        var chromeVersion = parseInt(v.groups.version);
        return chromeVersion >= 61;
    }

	// 检测Firefox
	v = navigator.userAgent.match(/Firefox\/(?<version>\S+)/);
	if (v && v.groups.version) {
        var firefoxVersion = parseInt(v.groups.version);
		return firefoxVersion >= 36;
	}

	// 检测Safari
	v = navigator.userAgent.match(/Version\/(?<version>\S+)/);
	if (v && v.groups.version) { // Safari
		var safariVersion = parseFloat(v.groups.version);
		return safariVersion >= 14;
	}

	return false;
})();

function getScrollOffset() {
    if (mw.config.get('skin') === 'timeless' && window.innerWidth > 850) {
        return 60;
    } else if (mw.config.get('skin') === 'minerva') {
        return 60;
    } else {
        return 10;
    }
}

function getAnchorOffset() {
    if (mw.config.get('skin') === 'timeless' && window.innerWidth > 850) {
        return 70;
    } else if (mw.config.get('skin') === 'minerva') {
        return 70;
    } else {
        return 20;
    }
}

function scrollToAnchor(link) {
    var el = document.getElementById(link.replace(/^#/, ''));
    if (el) {
        var target = $(el);

        function doScroll() {
            var position = target.offset().top - getScrollOffset();

            if (scrollBehaviorAvaliable) {
                window.scrollTo({
                    top: position,
                    behavior: 'smooth'
                });
            } else {
                $('html, body').animate({
                    scrollTop: position,
                }, 500);
            }
        }

        if (mw.config.get('skin') === 'minerva') { // 手机端主题,需要检测折叠状态
            var collapseBlock = target.parents('.collapsible-block');
            if (collapseBlock.length > 0 && !collapseBlock.hasClass('open-block')) {
                var h1Elem = collapseBlock.prev('.collapsible-heading');
                if (h1Elem.length > 0) {
                    // 展开目录
                    h1Elem.click();
                    var tid = setInterval(function() {
                        // 检测是否已经展开
                        if (collapseBlock.hasClass('open-block')) {
                            doScroll();
                            clearInterval(tid);
                        }
                    }, 100);
                    return false;
                }
            }
            doScroll();
        } else {
            doScroll();
        }
        return false;
	} else {
	    return true;
	}
}

function getScrollbarWidth() {
    if (window.innerWidth && document.body.clientWidth) {
        return window.innerWidth - document.body.clientWidth;
    } else {
        return 0;
    }
}

var lastActiveId = null;
function updateActive() {
    var scrollTop = $(window).scrollTop() + getAnchorOffset();
    
    if (headingList.length > 0) {
        var activedId;
        for (var i = 0; i < headingList.length; i ++) {
            var headItem = headingList[i];
            var headPos = headItem.offset().top;
            if (i === 0 && scrollTop < headPos) { // 比第一个head位置靠上,则是简介
                activedId = 'bodyContent';
                break;
            } else if (scrollTop < headPos) { // 如果当前滚动条高度低于目前head,则是上一个
                activedId = headingList[i - 1].attr('id');
                break;
            }
        }
        if (!activedId) {
            activedId = headingList[headingList.length - 1].attr('id');
        }
        if (activedId !== lastActiveId) {
            $('#isekai-offcanvas-toc ul .list-item').removeClass('active');
            $('#isekai-offcanvas-toc ul .list-item[data-id="' + activedId + '"]').addClass('active');
            var menuItem = menuList.find((item) => {
                return item.id === activedId;
            });
            if (menuItem) {
                if (menuItem.number) {
                    bottomNavBtnLabel.text(menuItem.number + '. ' + menuItem.text);
                } else {
                    bottomNavBtnLabel.text(menuItem.text);
                }
            }
            lastActiveId = activedId;
        }
    }
}

function openOffcanvas() {
    $('#iseai-offcanvas-btn').show();
    menuHidden = false;

    let scrollbarWidth = getScrollbarWidth();
    $('#isekai-offcanvas-cover').removeClass('hidden');

    window.requestAnimationFrame(function() {
        $('body').addClass(['toc-offcanvas-show', 'toc-offcanvas-open'])
            .css('margin-right', scrollbarWidth);
        $('#isekai-fab-container').css('margin-right', scrollbarWidth);
        if (mw.config.get('skin') === 'timeless') {
            $('#mw-header-container').css('padding-right', scrollbarWidth);
        }

        // 滚动到当前项目
        let activedItem = $('#isekai-offcanvas-toc ul .list-item.active');
        if (activedItem.length > 0) {
            let targetY = Math.max(activedItem.eq(0).prop('offsetTop') - 50, 0);
            $('#isekai-offcanvas-toc').scrollTop(targetY);
        }
    });
}

function closeOffcanvas() {
    if ($('#iseai-offcanvas-contextmenu').length > 0) {
        $('#iseai-offcanvas-contextmenu').remove();
        $('#isekai-offcanvas-cover').addClass('hidden');
    } else {
        $('body').removeClass('toc-offcanvas-open');
        setTimeout(function() {
            $('body').removeClass('toc-offcanvas-show').css('margin-right', 0);
            $('#isekai-offcanvas-cover').addClass('hidden');
            $('#isekai-fab-container').css('margin-right', 0);
            if (mw.config.get('skin') === 'timeless') {
                $('#mw-header-container').css('padding-right', 0);
            }
        }, 260);
    }
}

function throttle(fn, delay) {
    var timer = null;
    return function() {
        if (!timer) {
            timer = setTimeout(function() {
                fn();
                timer = null;
            }, delay);
        }
    };
}

$(function() {
    if (mw.config.get('wgIsArticle')) {
        // 创建目录dom
        $('body').append(`
        <div id="isekai-offcanvas-toc" class="toc-offcanvas">
            <ul></ul>
        </div>
        <div id="isekai-offcanvas-cover" class="toc-offcanvas-cover hidden"></div>
        `);

        // 创建按钮
        var menuIcon = new OO.ui.IconWidget({ icon: 'menu' });
        isekai.fab.addButton({
            id: 'offcanvas-toc',
            label: mw.msg('isekai-offcanvastoc-menubutton'),
            icon: menuIcon.$element[0],
            priority: 0,
            onClick: function() {
                openOffcanvas();
            }
        });
        var bottomMenuIcon = new OO.ui.IconWidget({ icon: 'menu' });
        bottomNavBtn = isekai.bottomNav.addButton({
            id: 'offcanvas-toc',
            label: mw.msg('isekai-offcanvastoc-menubutton'),
            icon: bottomMenuIcon.$element[0],
            priority: 0,
            expand: true,
            onClick: function() {
                openOffcanvas();
            }
        });
        bottomNavBtnLabel = $(bottomNavBtn).find('.isekai-bottom-nav-btn-label');
        bottomNavBtnLabel.text('');

        // 生成目录
        var parserOutput = $('.mw-parser-output');
        var headings = parserOutput.find('h1,h2,h3,h4,h5,h6,heading-6');

        var headNum = new Array(6).fill(0);
        menuList = [{
            number: false,
            text: mw.msg('isekai-offcanvastoc-description-item'),
            id: 'bodyContent'
        }];

        headings.each(function() {
            var headline = $(this).find('.mw-headline');
            if (headline.length > 0) {
                headingList.push(headline);
                var text = headline.text();
                var headId = headline.prop('id');
                
                var indentNum = parseInt(this.tagName.replace(/^H/, ''));
                this.classList.forEach((className) => {
                    if (className.indexOf('heading-') === 0) {
                        indentNum = parseInt(className.replace(/^heading-/, ''));
                    }
                })

                // 计算折叠
                var menuNumStringBuilder = [];
                headNum[indentNum - 1] ++;
                for (var i = 0; i < indentNum; i ++) {
                    menuNumStringBuilder.push(headNum[i]);
                }
                for (var i = indentNum; i < headNum.length; i ++) {
                    headNum[i] = 0;
                }
                var menuNum = menuNumStringBuilder.join('.');
                menuList.push({
                    number: menuNum,
                    text: text,
                    id: headId
                });
            }
        });

        // 生成dom
        var tocContainer = $('#isekai-offcanvas-toc ul');
        menuList.forEach(function(menuInfo) {
            var listItem = document.createElement('a');
            listItem.href = '#' + menuInfo.id;
            listItem.dataset.id = menuInfo.id;
            listItem.classList.add('list-item');

            var titleItem = document.createElement('span');
            titleItem.classList.add('title');
            titleItem.innerText = menuInfo.text;

            if (menuInfo.number) {
                var numberItem = document.createElement('span');
                numberItem.classList.add('number');
                numberItem.innerText = menuInfo.number;
                listItem.appendChild(numberItem);
            }
            
            listItem.appendChild(titleItem);

            tocContainer[0].appendChild(listItem);
        });

        // 事件
        $('#isekai-offcanvas-cover').on('click', function() {
            closeOffcanvas();
        });
        
        $('#isekai-offcanvas-toc ul .list-item').on('click', function(e) {
            // 点击链接
            e.preventDefault();
            var target = $(this).data('id');
            if (target && target != '') {
                target = '#' + target;
                $('#isekai-offcanvas-toc ul .list-item').removeClass('active');
                $(this).addClass('active');
                scrollToAnchor(target);
                if (window.innerWidth < 550) { // 手机端,关闭抽屉
                    closeOffcanvas();
                }
            }
            return false;
        });

        $('#content').on('dblclick', function(e) {
            if (window._openOffcanvasTocViaDblclick) {
                openOffcanvas();
            }
        });
        
        window.addEventListener('scroll', throttle(updateActive, 500), { passive: true });

        updateActive();
    }
});