function createElementFromHTML(htmlString) {
    const div = document.createElement('div');
    div.innerHTML = htmlString.trim();
    return div.firstChild;
}

function animate(callbackObj, duration) {
    const requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame;
    let startTime = 0;
    let percentage = 0;
    let
        animationTime = 0;

    duration = duration * 1000 || 1000;

    const animation = function ani(timestamp) {
        if (startTime === 0) {
            startTime = timestamp;
        } else {
            animationTime = timestamp - startTime;
        }

        if (typeof callbackObj.start === 'function' && startTime === timestamp) {
            callbackObj.start();

            requestAnimationFrame(animation);
        } else if (animationTime < duration) {
            if (typeof callbackObj.progress === 'function') {
                percentage = animationTime / duration;
                callbackObj.progress(percentage);
            }

            requestAnimationFrame(animation);
        } else if (typeof callbackObj.done === 'function') {
            callbackObj.done();
        }
    };
    return requestAnimationFrame(animation);
}

function easeInOutQuad(t) {
    return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}


const SmoothScroll = {
    init: () => {
        const offset = 50;
        const elements = document.querySelectorAll('a[href^="#"]');
        Array.prototype.forEach.call(elements, (el) => {
            el.addEventListener('click', (e) => {
                e.preventDefault();
                const href = el.getAttribute('href');
                const elementHref = document.getElementById(href.replace('#', ''));
                const bodyRect = document.body.getBoundingClientRect();
                const elemRect = elementHref.getBoundingClientRect();
                const posY = elemRect.top - bodyRect.top;

                if (href !== '#') {
                    window.scrollTo(0, posY - offset);
                }
            }, false);
        });
    },
};


const Carousel = {
    init: () => {
        const elements = document.getElementsByClassName('carousel');
        Array.prototype.forEach.call(elements, (el) => {
            const parent = el.parentNode;
            const theme = parent.getAttribute('class').split('theme-')[1];
            const right = createElementFromHTML(`<img class='s-icon x2 right' src='${Icons.right[theme]}' alt='Suivant'>`);
            const left = createElementFromHTML(`<img class='s-icon x2 left' src='${Icons.left[theme]}' alt='Précédent'>`);
            const scrollOffset = 305;
            parent.appendChild(right);
            parent.appendChild(left);
            let scroller = 0;
            right.addEventListener('click', (e) => {
                const sequenceObj = {};
                sequenceObj.progress = (function prog(percentage) {
                    el.scrollLeft = scroller + easeInOutQuad(percentage) * scrollOffset;
                });
                animate(sequenceObj, 0.5);
                scroller = el.scrollLeft;
            });
            left.addEventListener('click', (e) => {
                const sequenceObj = {};
                sequenceObj.progress = (function prog(percentage) {
                    el.scrollLeft = scroller - easeInOutQuad(percentage) * scrollOffset;
                });
                animate(sequenceObj, 0.5);
                scroller = el.scrollLeft;
            });
        });
    },
};

const Clicker = {
    init: () => {
        document.addEventListener('click', (e) => {
            const elements = document.querySelectorAll('*[data-clicker-child]');
            Array.prototype.forEach.call(elements, (el) => {
                el.style.display = 'none';
            });
        });

        const elements = document.querySelectorAll('*[data-clicker]');
        Array.prototype.forEach.call(elements, (el) => {
            el.addEventListener('click', (e) => {
                e.stopPropagation();
                const child = el.querySelectorAll('*[data-clicker-child]')[0];
                const childIsVisible = child.style.visibility !== 'hidden';
                const all = document.querySelectorAll('*[data-clicker-child]');

                Array.prototype.forEach.call(all, (ell) => {
                    ell.style.display = 'none';
                });
                if (childIsVisible) child.style.display = 'block';
            });
        });
    },
};

const Accordion = {
    init: () => {
        const accordion = document.getElementById('accordion');
        const accordionOpen = document.getElementById('accordion-open');
        const accordionClose = document.getElementById('accordion-close');

        if (accordion) {
            document.addEventListener('click', (e) => {
                accordion.style.left = '-100%';
            });

            accordionOpen.addEventListener('click', (e) => {
                e.stopPropagation();
                accordion.style.left = '0';
            });

            accordionClose.addEventListener('click', (e) => {
                e.stopPropagation();
                accordion.style.left = '-100%';
            });
        }
    },
};

const Lazy = {
    init: () => {
        const io = new IntersectionObserver(entries => entries.forEach((entry) => {
            if (entry.isIntersecting) {
                const element = entry.target;
                if (element.id.startsWith('block')) {
                    // background
                    element.style.backgroundImage = `url(${element.dataset.src})`;
                } else {
                    // classic
                    element.src = element.dataset.src;
                }
                io.unobserve(element);
            }
        }));
        document.querySelectorAll('.lazy').forEach(element => io.observe(element));
    },
};


const Collect = {
    init: () => {
        const collectBlock = document.getElementById('collect-block');
        const collectButton = document.getElementById('collect-btn');
        const haveAccepted = localStorage.getItem('collect');

        if (!(haveAccepted && haveAccepted === 'false')) {
            collectButton.addEventListener('click', (e) => {
                e.stopPropagation();
                collectBlock.style.display = 'none';
                localStorage.setItem('collect', 'false');
            });
        } else {
            collectBlock.style.display = 'none';
        }
    }
}

export default {
    Image,
    Carousel,
    SmoothScroll,
    Clicker,
    Accordion,
    Lazy,
    Collect,
};
