/**
 * SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
 * SPDX-License-Identifier: AGPL-3.0-only
 */

function ready(fn) {
    if (document.readyState !== 'loading') {
        fn();
    } else {
        document.addEventListener('DOMContentLoaded', fn);
    }
}

ready(function () {
    const snackBar = Object.assign(document.body.appendChild(document.createElement('section')), {
        id: 'snackbar',
    });

    const errorMessage = snackBar.appendChild(document.createElement('div'));
    errorMessage.setAttribute('role', 'alert');

    const openClass = 'open';
    const toasts = [];
    let timeoutId = null;

    function showError(message) {
        toasts.push(message);
        popUp();
    }

    function popUp() {
        if (toasts.length === 0) {
            return;
        }
        if (errorMessage.classList.contains(openClass)) {
            dismiss();
            return;
        }
        if (errorMessage.innerText !== "") {
            // it will show after remove calls popUp again.
            return;
        }
        errorMessage.innerText = toasts[0];
        errorMessage.classList.add(openClass);
        timeoutId = setTimeout(dismiss, 4000);
    }

    function dismiss() {
        if (!errorMessage.classList.contains(openClass)) {
            // already dismissed
            return;
        }
        errorMessage.classList.remove(openClass);
        clearTimeout(timeoutId);
        timeoutId = setTimeout(remove, 350);
    }

    function remove() {
        clearTimeout(timeoutId);
        toasts.splice(0, 1);
        errorMessage.innerText = "";
        popUp();
    }

    document.body.addEventListener('htmx:error', function (evt) {
        const errorInfo = evt.detail.errorInfo;
        const error = errorInfo.xhr && errorInfo.xhr.responseText || errorInfo.error;
        showError(error);
    });
})

ready(function () {
    const textareas = document.querySelectorAll('textarea.html');
    if (textareas.length > 0) {
        const language = document.documentElement.getAttribute('lang');
        const csrfHeader = JSON.parse(document.querySelector('meta[name="csrf-header"]').getAttribute('content'));
        const script = document.head.appendChild(Object.assign(document.createElement('script'), {
            src: '/static/ckeditor5@40.2.0/ckeditor.js',
        }));
        if (language !== 'en') {
            document.head.appendChild(Object.assign(document.createElement('script'), {
                src: '/static/ckeditor5@40.2.0/translations/' + language + '.js',
            }));
        }
        const editorConfig = {
            language,
            image: {
                toolbar: [
                    'imageTextAlternative',
                    'toggleImageCaption',
                    '|',
                    'imageStyle:inline',
                    'imageStyle:wrapText',
                    'imageStyle:breakText',
                    '|',
                    'resizeImage',
                ],
            },
            simpleUpload: {
                uploadUrl: '/admin/media',
                headers: Object.assign(csrfHeader, {
                    Accept: 'application/vnd.ckeditor+json',
                }),
            },
        };
        script.addEventListener('load', function () {
            for (const textarea of textareas) {
                const canvas = document.createElement('div');
                textarea.parentNode.insertBefore(canvas, textarea.nextSibling);
                textarea.style.display = 'none';

                ClassicEditor
                    .create(canvas, editorConfig)
                    .then(editor => {
                        const xml = document.createElement('div');
                        const serializer = new XMLSerializer();
                        editor.setData(textarea.value);
                        editor.ui.focusTracker.on('change:isFocused', (event, name, focused) => {
                            if (!focused) {
                                xml.innerHTML = editor.getData();
                                let text = serializer.serializeToString(xml);
                                text = text.replace('&nbsp;', '&#xA0;');
                                text = text.substring(text.indexOf('>') + 1, text.lastIndexOf('<'));
                                textarea.value = text;
                            }
                        });
                    })
                    .catch(error => {
                        console.error(error);
                    });
            }
        });
    }
})

export function camperUploadForm(el) {
    const progress = el.querySelector('progress');
    htmx.on(el, 'drop', function (evt) {
        evt.preventDefault();
        [...evt.dataTransfer.items].forEach(function (i) {
            console.log(i);
            i.getAsString(console.log)
        });
    });
    htmx.on(el, 'dragover', function (evt) {
        evt.preventDefault();
    });
    htmx.on(el, 'dragleave', function (evt) {
        evt.preventDefault();
    });
    htmx.on(el, 'htmx:xhr:progress', function (evt) {
        if (progress && evt.detail.lengthComputable) {
            progress.setAttribute('value', evt.detail.loaded / evt.detail.total * 100);
        }
    });
}

export function setupCampgroundMap(map) {
    if (!map) {
        return;
    }
    const prefix = "cp_";
    for (const campsite of Array.from(map.querySelectorAll(`[id^="${prefix}"]`))) {
        const label = campsite.id.substring(prefix.length);
        if (!label) {
            continue;
        }
        const link = document.createElementNS('http://www.w3.org/2000/svg', 'a');
        link.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '/admin/campsites/' + label);
        link.append(...campsite.childNodes);
        campsite.appendChild(link);
    }
}

export function setupIconInput(icon) {
    if (!icon) {
        return;
    }
    const input = icon.querySelector('input[type="hidden"]')
    if (!input) {
        return;
    }
    const buttons = Array.from(icon.querySelectorAll('button[data-icon-name]'));
    const updateValue = function (iconName) {
        input.value = iconName;
        for (const button of buttons) {
            button.setAttribute('aria-pressed', button.dataset.iconName === iconName);
        }
    }
    for (const button of buttons) {
        button.addEventListener('click', function (e) {
            updateValue(e.target.dataset.iconName);
        })
    }
    updateValue(input.value);
}

export function setupCalendar(calendar) {
    const startDate = calendar.querySelector('input[name="start_date"]');
    const endDate = calendar.querySelector('input[name="end_date"]');
    const days = Array.from(calendar.querySelectorAll('time'));
    const dialog = calendar.querySelector('dialog');

    const clear = function () {
        startDate.value = endDate.value = "";
        days.forEach((e) => e.removeAttribute('aria-checked'));
    }

    dialog.addEventListener('close', clear);
    dialog.querySelector('button').addEventListener('click', function (e) {
        e.preventDefault();
        dialog.close();
    });

    const selectDate = function (e) {
        e.preventDefault();
        const date = e.currentTarget.dateTime;
        if (!date) {
            return;
        }
        if (!startDate.value) {
            startDate.value = date;
            e.currentTarget.setAttribute('aria-checked', true);
            return;
        } else if (startDate.value > date) {
            endDate.value = startDate.value;
            startDate.value = date;
        } else {
            endDate.value = date;
        }
        for (const day of days) {
            if (day.dateTime >= startDate.value && day.dateTime <= endDate.value) {
                day.setAttribute('aria-checked', true);
            } else {
                day.removeAttribute('aria-checked');
            }
        }
        dialog.showModal();
    }

    for (const day of days) {
        day.addEventListener('click', selectDate);
    }

    clear();
}

htmx.onLoad((target) => {
    if (target.tagName === 'DIALOG') {
        target.showModal();
    }
})

htmx.onLoad((content) => {
    const sortables = Array.from(content.querySelectorAll('.sortable table tbody'));
    for (const sortable of sortables) {
        const sortableInstance = new Sortable(sortable, {
            animation: 150,
            draggable: '>tr',
            handle: '.handle',
            onMove: (evt) => evt.related.className.indexOf('htmx-indicator') === -1,
            onEnd: function () {
                this.option('disabled', true);
            },
        });

        sortable.addEventListener('htmx:afterSwap', function () {
            sortableInstance.option('disabled', false);
        });
    }
})

htmx.on('htmx:configRequest', function (e) {
    const element = e.detail.elt;
    if (element && element.nodeName === 'FORM') {
        let submitter = e.detail.triggeringEvent.submitter;
        if (submitter) {
            const action = submitter.attributes['formaction'];
            if (action && action.value) {
                e.detail.path = action.value;
            }
            const method = submitter.attributes['formmethod'];
            if (method && method.value) {
                e.detail.verb = method.value;
            }
        }
    }
})