/* ═══════════════════════════════════════════════════════════════
   mkbooks Reader — Pagination Engine
   CSS multi-column based page-flip navigation
   ═══════════════════════════════════════════════════════════════ */
(function () {
    'use strict';

    var STORAGE_KEY = 'mkbooks-reader';
    var SWIPE_THRESHOLD = 40;

    // ── State ────────────────────────────────────────────────
    var state = loadState();
    var chapterCount = window.__BOOK_DATA__ ? window.__BOOK_DATA__.chapterCount : 0;
    var currentChapter = (state.chapter != null) ? state.chapter : -1;   // -1 = cover
    var currentPage = (state.page != null) ? state.page : 0;
    var totalPages = 0;
    var chapterPageCounts = [];  // pages per chapter (index 0 = chapter 0)
    var bookTotalPages = 0;     // sum of all chapter pages
    var barsVisible = true;

    // ── DOM refs ─────────────────────────────────────────────
    var viewport    = document.getElementById('readerViewport');
    var bar         = document.getElementById('readerBar');
    var footer      = document.getElementById('readerFooter');
    var barTitle    = document.getElementById('barTitle');
    var pageInfo    = document.getElementById('pageInfo');
    var progressFill = document.getElementById('progressFill');
    var tocDrawer   = document.getElementById('tocDrawer');
    var tocOverlay  = document.getElementById('tocOverlay');
    var btnToc      = document.getElementById('btnToc');
    var btnTocClose = document.getElementById('btnTocClose');
    var btnMode     = document.getElementById('btnMode');
    var btnTheme    = document.getElementById('btnTheme');
    var tapPrev     = document.getElementById('tapPrev');
    var tapNext     = document.getElementById('tapNext');
    var iconSingle  = document.getElementById('iconSingle');
    var iconSpread  = document.getElementById('iconSpread');
    var navPrev     = document.getElementById('navPrev');
    var navNext     = document.getElementById('navNext');

    // ── Init ─────────────────────────────────────────────────
    applyTheme(state.theme || 'light');
    applyMode(state.mode || detectDefaultMode());
    var savedPage = (state.page != null) ? state.page : 0;
    showSection(currentChapter);
    // Defer pagination measurement to after fonts + layout settle
    requestAnimationFrame(function () {
        setTimeout(function () {
            paginateAll();
            showSection(currentChapter);
            paginate();
            if (savedPage > 0) goToPage(Math.min(savedPage, totalPages - 1), true);
            updateUI();
        }, 100);
    });

    // ── TOC ──────────────────────────────────────────────────
    btnToc.addEventListener('click', openToc);
    btnTocClose.addEventListener('click', closeToc);
    tocOverlay.addEventListener('click', closeToc);

    var tocLinks = document.querySelectorAll('.toc-link');
    for (var i = 0; i < tocLinks.length; i++) {
        tocLinks[i].addEventListener('click', (function (link) {
            return function (e) {
                e.preventDefault();
                var idx = parseInt(link.getAttribute('data-chapter'), 10);
                goToChapter(idx);
                closeToc();
            };
        })(tocLinks[i]));
    }

    // ── Mode toggle ──────────────────────────────────────────
    btnMode.addEventListener('click', function () {
        var newMode = state.mode === 'spread' ? 'single' : 'spread';
        applyMode(newMode);
        paginateAll();
        showSection(currentChapter);
        paginate();
        goToPage(0, true);
        updateUI();
        saveState();
    });

    // ── Theme toggle ─────────────────────────────────────────
    btnTheme.addEventListener('click', function () {
        var newTheme = state.theme === 'dark' ? 'light' : 'dark';
        applyTheme(newTheme);
        saveState();
    });

    // ── Tap zones ────────────────────────────────────────────
    tapPrev.addEventListener('click', function (e) {
        e.stopPropagation();
        if (swipeHandled) { swipeHandled = false; return; }
        prevPage();
    });
    tapNext.addEventListener('click', function (e) {
        e.stopPropagation();
        if (swipeHandled) { swipeHandled = false; return; }
        nextPage();
    });

    // Visible nav buttons
    navPrev.addEventListener('click', function (e) {
        e.stopPropagation();
        prevPage();
    });
    navNext.addEventListener('click', function (e) {
        e.stopPropagation();
        nextPage();
    });

    // Center tap — toggle bars
    viewport.addEventListener('click', function (e) {
        if (swipeHandled) { swipeHandled = false; return; }
        var x = e.clientX;
        var w = window.innerWidth;
        var pct = x / w;
        // Only toggle if clicking the center 20% (between tap zones)
        if (pct > 0.30 && pct < 0.50) {
            toggleBars();
        }
    });

    // ── Keyboard ─────────────────────────────────────────────
    document.addEventListener('keydown', function (e) {
        if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
        switch (e.key) {
            case 'ArrowRight':
            case 'PageDown':
                e.preventDefault();
                nextPage();
                break;
            case 'ArrowLeft':
            case 'PageUp':
                e.preventDefault();
                prevPage();
                break;
            case 'Home':
                e.preventDefault();
                goToChapter(-1);
                break;
            case 'End':
                e.preventDefault();
                goToChapter(chapterCount - 1);
                goToPage(totalPages - 1, false);
                updateUI();
                break;
            case 'Escape':
                if (isTocOpen()) closeToc();
                break;
        }
    });

    // ── Touch / Swipe ────────────────────────────────────────
    // Listeners on document so swipes work over tap zones (z-index above viewport)
    var touchStartX = 0;
    var touchStartY = 0;
    var touchStartTime = 0;
    var isSwiping = false;
    var swipeHandled = false;

    document.addEventListener('touchstart', function (e) {
        if (e.touches.length !== 1) return;
        if (isTocOpen()) return;
        var t = e.target;
        if (t.closest && t.closest('.reader-bar, .reader-footer, .toc-drawer, .toc-overlay')) return;
        touchStartX = e.touches[0].clientX;
        touchStartY = e.touches[0].clientY;
        touchStartTime = Date.now();
        isSwiping = true;
        swipeHandled = false;
    }, { passive: true });

    document.addEventListener('touchmove', function (e) {
        if (!isSwiping) return;
        var dx = Math.abs(e.touches[0].clientX - touchStartX);
        var dy = Math.abs(e.touches[0].clientY - touchStartY);
        // Cancel if vertical scroll intent
        if (dy > dx * 1.2) {
            isSwiping = false;
        } else if (dx > 10) {
            // Prevent browser back/forward navigation on horizontal swipe
            e.preventDefault();
        }
    }, { passive: false });

    document.addEventListener('touchend', function (e) {
        if (!isSwiping) return;
        isSwiping = false;
        var endX = e.changedTouches[0].clientX;
        var dx = endX - touchStartX;
        var elapsed = Date.now() - touchStartTime;
        // Quick flick or long drag past threshold
        if (Math.abs(dx) > SWIPE_THRESHOLD || (Math.abs(dx) > 20 && elapsed < 200)) {
            swipeHandled = true;
            if (dx < 0) {
                nextPage();
            } else {
                prevPage();
            }
        }
    }, { passive: true });

    // ── Resize handler ───────────────────────────────────────
    var resizeTimer;
    window.addEventListener('resize', function () {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(function () {
            paginateAll();
            showSection(currentChapter);
            paginate();
            // Clamp current page
            if (currentPage >= totalPages) currentPage = Math.max(0, totalPages - 1);
            goToPage(currentPage, true);
            updateUI();
        }, 150);
    });

    // ── Persist state on mobile tab-switch / close ────────────
    document.addEventListener('visibilitychange', function () {
        if (document.visibilityState === 'hidden') saveState();
    });
    window.addEventListener('pagehide', function () {
        saveState();
    });

    // ═══════════════════════════════════════════════════════════
    // Functions
    // ═══════════════════════════════════════════════════════════

    function showSection(chapterIdx) {
        var sections = document.querySelectorAll('.reader-section');
        for (var i = 0; i < sections.length; i++) {
            var idx = parseInt(sections[i].getAttribute('data-chapter-index'), 10);
            sections[i].style.display = (idx === chapterIdx) ? '' : 'none';
        }
        currentChapter = chapterIdx;
        currentPage = 0;
        highlightTocLink();
        updateBarTitle();
    }

    function goToChapter(chapterIdx) {
        if (chapterIdx < -1) chapterIdx = -1;
        if (chapterIdx >= chapterCount) chapterIdx = chapterCount - 1;
        showSection(chapterIdx);
        paginate();
        chapterPageCounts[chapterIdx] = totalPages;
        goToPage(0, true);
        updateUI();
        saveState();
    }

    function paginate() {
        if (currentChapter < 0) {
            // Cover — single "page"
            totalPages = 1;
            return;
        }
        var cols = getColumnsEl();
        if (!cols) { totalPages = 1; return; }

        var section = cols.parentElement; // .reader-chapter
        var W = section.offsetWidth;
        if (W <= 0) { totalPages = 1; return; }

        // Horizontal margin on each side of the text
        var M = W < 600 ? 24 : (W < 1024 ? 40 : 48);
        var colWidth, gap, padL, padR;

        if (state.mode === 'spread') {
            // Two columns per page — gap acts as center gutter AND page margin
            gap = M * 2;
            colWidth = Math.floor((W - 4 * M) / 2);
            padL = M;
            padR = M;
        } else {
            // Single column, centered with max readable width
            var maxReadWidth = 680;
            colWidth = Math.min(W - 2 * M, maxReadWidth);
            gap = W - colWidth;
            padL = Math.floor(gap / 2);
            padR = gap - padL;
        }

        cols.style.columnWidth = colWidth + 'px';
        cols.style.columnGap = gap + 'px';
        cols.style.paddingLeft = padL + 'px';
        cols.style.paddingRight = padR + 'px';

        // Reset transform to measure natural scroll width
        cols.style.transform = 'translateX(0)';
        // Force layout reflow
        void cols.offsetHeight;

        var scrollW = cols.scrollWidth;
        totalPages = Math.max(1, Math.round(scrollW / W));
        chapterPageCounts[currentChapter] = totalPages;
    }

    function paginateAll() {
        // Measure page counts for every chapter so we can show cumulative page numbers
        var saved = currentChapter;
        chapterPageCounts = [];
        bookTotalPages = 0;
        for (var c = 0; c < chapterCount; c++) {
            showSection(c);
            paginate();
            chapterPageCounts[c] = totalPages;
            bookTotalPages += totalPages;
            // Reset transform after measuring
            var cols = getColumnsEl();
            if (cols) cols.style.transform = 'translateX(0)';
        }
        // Restore
        currentChapter = saved;
    }

    function goToPage(pageIdx, instant) {
        if (pageIdx < 0) pageIdx = 0;
        if (pageIdx >= totalPages) pageIdx = totalPages - 1;
        currentPage = pageIdx;

        if (currentChapter >= 0) {
            var cols = getColumnsEl();
            if (cols) {
                var section = cols.parentElement;
                var W = section.offsetWidth;
                var offset = -(pageIdx * W);
                if (instant) {
                    cols.style.transition = 'none';
                    cols.style.transform = 'translateX(' + offset + 'px)';
                    void cols.offsetWidth;
                    cols.style.transition = '';
                } else {
                    cols.style.transform = 'translateX(' + offset + 'px)';
                }
            }
        }

        updateUI();
        saveState();
    }

    function nextPage() {
        if (currentChapter < 0) {
            // From cover, go to first chapter
            goToChapter(0);
            return;
        }
        if (currentPage < totalPages - 1) {
            goToPage(currentPage + 1, false);
        } else if (currentChapter < chapterCount - 1) {
            // Next chapter
            goToChapter(currentChapter + 1);
        }
    }

    function prevPage() {
        if (currentChapter < 0) return; // Already at cover
        if (currentPage > 0) {
            goToPage(currentPage - 1, false);
        } else if (currentChapter > -1) {
            // Previous chapter (or cover)
            var prevIdx = currentChapter - 1;
            showSection(prevIdx);
            paginate();
            goToPage(totalPages - 1, true);
            updateUI();
            saveState();
        }
    }

    // ── UI updates ───────────────────────────────────────────

    function updateUI() {
        // Page info — cumulative across ALL chapters
        if (currentChapter < 0) {
            pageInfo.textContent = '';
            progressFill.style.width = '0%';
        } else {
            // Sum pages of all chapters before the current one
            var pagesBefore = 0;
            for (var c = 0; c < currentChapter; c++) {
                pagesBefore += (chapterPageCounts[c] || 0);
            }
            var globalPage = pagesBefore + currentPage + 1;
            pageInfo.textContent = 'Page ' + globalPage + ' of ' + bookTotalPages;
            var pct = bookTotalPages > 1 ? ((globalPage - 1) / (bookTotalPages - 1)) * 100 : 100;
            progressFill.style.width = pct + '%';
        }
    }

    function updateBarTitle() {
        if (currentChapter < 0) {
            barTitle.textContent = window.__BOOK_DATA__ ? window.__BOOK_DATA__.title : '';
        } else {
            var section = document.querySelector('[data-chapter-index="' + currentChapter + '"]');
            if (section) {
                var title = section.querySelector('.ch-title');
                barTitle.textContent = title ? title.textContent : '';
            }
        }
    }

    function highlightTocLink() {
        var links = document.querySelectorAll('.toc-link');
        for (var i = 0; i < links.length; i++) {
            var idx = parseInt(links[i].getAttribute('data-chapter'), 10);
            if (idx === currentChapter) {
                links[i].classList.add('active');
            } else {
                links[i].classList.remove('active');
            }
        }
    }

    // ── Mode ─────────────────────────────────────────────────

    function detectDefaultMode() {
        return window.innerWidth >= 768 ? 'spread' : 'single';
    }

    function applyMode(mode) {
        state.mode = mode;
        viewport.classList.remove('mode-single', 'mode-spread');
        viewport.classList.add('mode-' + mode);
        if (mode === 'spread') {
            iconSingle.style.display = 'none';
            iconSpread.style.display = '';
        } else {
            iconSingle.style.display = '';
            iconSpread.style.display = 'none';
        }
    }

    // ── Theme ────────────────────────────────────────────────

    function applyTheme(theme) {
        state.theme = theme;
        document.documentElement.setAttribute('data-theme', theme);
        // Toggle icon visibility
        var sunIcons = btnTheme.querySelectorAll('svg');
        if (theme === 'dark') {
            sunIcons[0].style.display = 'none';
            sunIcons[1].style.display = '';
        } else {
            sunIcons[0].style.display = '';
            sunIcons[1].style.display = 'none';
        }
    }

    // ── TOC helpers ──────────────────────────────────────────

    function openToc() {
        tocDrawer.classList.add('open');
        tocOverlay.classList.add('active');
    }

    function closeToc() {
        tocDrawer.classList.remove('open');
        tocOverlay.classList.remove('active');
    }

    function isTocOpen() {
        return tocDrawer.classList.contains('open');
    }

    // ── Bar toggling ─────────────────────────────────────────

    function toggleBars() {
        barsVisible = !barsVisible;
        if (barsVisible) {
            bar.classList.remove('hidden');
            footer.classList.remove('hidden');
        } else {
            bar.classList.add('hidden');
            footer.classList.add('hidden');
        }
    }

    // ── DOM helpers ──────────────────────────────────────────

    function getColumnsEl() {
        return document.getElementById('cols' + currentChapter);
    }

    // ── Persistence ──────────────────────────────────────────

    function loadState() {
        try {
            var s = JSON.parse(localStorage.getItem(STORAGE_KEY));
            if (s && typeof s === 'object') return s;
        } catch (e) { /* ignore */ }
        return {};
    }

    function saveState() {
        try {
            state.chapter = currentChapter;
            state.page = currentPage;
            localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
        } catch (e) { /* ignore */ }
    }

})();
