function encodePickedPath(p) {
    if (p === '/' || p === '') return '/';
    return '/' + p.replace(/^\/+/, '').split('/').map(encodeURIComponent).join('/');
}

// postReplace POSTs to action with the optional form body, then loads target
// into the current history entry — so the action and its result occupy one
// entry instead of two, and back-navigation skips past the stale pre-mutation
// snapshot in bfcache. body may be null for empty POSTs.
//
// We can't just call window.location.replace(target): when target differs from
// the current URL only by fragment, the browser updates the URL bar without
// re-fetching, so a server-side mutation wouldn't be reflected. Instead,
// rewrite the current entry's URL via history.replaceState, then reload — the
// reload always re-fetches and preserves the (new) URL including its fragment.
function navigateReplace(target) {
    window.history.replaceState(null, '', target);
    window.location.reload();
}

function postReplace(action, body, target) {
    var init = { method: 'POST', redirect: 'manual' };
    if (body) {
        init.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
        init.body = body;
    }
    fetch(action, init).then(function (res) {
        if (res.type === 'opaqueredirect' || res.ok) {
            navigateReplace(target);
            return;
        }
        return res.text().then(function (msg) {
            alert(msg || ('Request failed (' + res.status + ')'));
        });
    }).catch(function () {
        alert('Network error');
    });
}

function promptPageName(title, initial, confirmLabel, onName) {
    var input = document.createElement('input');
    input.type = 'text';
    input.className = 'input';
    input.placeholder = 'Page name';
    if (initial) input.value = initial;
    openModal({
        title: title,
        body: input,
        confirm: {
            label: confirmLabel,
            onConfirm: function () {
                var name = input.value.trim();
                if (!name) return;
                onName(name);
            }
        }
    });
}

function newPage() {
    var current = decodeURIComponent(window.location.pathname).replace(/\/+$/, '') || '/';
    openTreePicker({
        title: 'New page — where?',
        mode: 'folder',
        initialPath: current,
        preselect: current,
        hideFiles: true,
        confirmLabel: 'NEXT',
        onSelect: function (parentPath) {
            promptPageName('New page — name?', '', 'CREATE', function (name) {
                var base = parentPath === '/' ? '/' : encodePickedPath(parentPath) + '/';
                window.location.href = base + encodeURIComponent(name) + '/?edit';
            });
        }
    });
}

// submitMove POSTs a move and navigates on success. When the server reports
// the destination folder already exists but can be merged (the source carries
// a page and the destination has none), it asks the user to confirm and
// retries the same move with &merge=1.
function submitMove(action, target) {
    fetch(action, { method: 'POST', redirect: 'manual' }).then(function (res) {
        if (res.type === 'opaqueredirect' || res.ok) {
            navigateReplace(target);
            return;
        }
        if (res.status === 409 && res.headers.get('X-Merge-Available') === '1') {
            openModal({
                title: 'Merge folders?',
                body: 'The destination folder already exists but has no page of its own. Merge this page and its contents into it?',
                confirm: {
                    label: 'MERGE',
                    onConfirm: function () {
                        closeModal();
                        submitMove(action + '&merge=1', target);
                    }
                }
            });
            return;
        }
        return res.text().then(function (msg) {
            alert(msg || ('Request failed (' + res.status + ')'));
        });
    }).catch(function () {
        alert('Network error');
    });
}

function movePage() {
    var current = decodeURIComponent(window.location.pathname).replace(/\/+$/, '');
    if (!current) return;
    var segs = current.split('/').filter(Boolean);
    var currentName = segs[segs.length - 1] || '';
    var parent = '/' + segs.slice(0, -1).join('/');
    if (parent === '/') parent = '/';

    openTreePicker({
        title: 'Move — new parent?',
        mode: 'folder',
        initialPath: parent,
        preselect: parent,
        hideFiles: true,
        confirmLabel: 'NEXT',
        onSelect: function (newParent) {
            var input = document.createElement('input');
            input.type = 'text';
            input.className = 'input';
            input.placeholder = 'Page name';
            input.value = currentName;

            var linksCheckbox = document.createElement('input');
            linksCheckbox.type = 'checkbox';
            linksCheckbox.id = 'move-update-links';

            var linksLabel = document.createElement('label');
            linksLabel.htmlFor = linksCheckbox.id;
            linksLabel.className = 'row';
            linksLabel.appendChild(linksCheckbox);
            linksLabel.appendChild(document.createTextNode('Update links'));

            var body = document.createDocumentFragment();
            body.appendChild(input);
            body.appendChild(linksLabel);

            openModal({
                title: 'Move — new name?',
                body: body,
                confirm: {
                    label: 'MOVE',
                    onConfirm: function () {
                        var name = input.value.trim();
                        if (!name) return;
                        var dest = (newParent === '/' ? '' : newParent) + '/' + name;
                        var action = window.location.pathname + '?move=' +
                            encodeURIComponent(dest);
                        if (linksCheckbox.checked) action += '&links=1';
                        var target = encodePickedPath(dest) + '/';
                        closeModal();
                        submitMove(action, target);
                    }
                }
            });
        }
    });
}

function deletePage() {
    var decodedPath = decodeURIComponent(window.location.pathname);

    openModal({
        title: 'Delete page',
        body: 'Delete ' + decodedPath + ' and everything inside it?',
        confirm: {
            label: 'DELETE',
            danger: true,
            enterConfirms: false,
            onConfirm: function () {
                var p = window.location.pathname.replace(/\/+$/, '');
                var idx = p.lastIndexOf('/');
                var parent = idx > 0 ? p.substring(0, idx + 1) : '/';
                closeModal();
                postReplace(window.location.pathname + '?delete=1', null, parent);
            }
        },
        cancel: { autofocus: true },
        swapButtons: true
    });
}

