import { useEffect, useState } from "react";
import { useDebounce } from "react-use";

const breakpoints = {
    xs: 360,
    sm: 576,
    md: 768,
    lg: 1024,
    xl: 1280,
    xxl: 2559,
}

function mediaQueryTo(breakpoint) {
    return `@media screen and (max-width: ${breakpoint}px)`;
}

function mediaQueryFrom(breakpoint) {
    return `@media screen and (min-width: ${breakpoint + 1}px)`;
}

const respondTo = {
    xs: mediaQueryTo(breakpoints.xs),
    sm: mediaQueryTo(breakpoints.sm),
    md: mediaQueryTo(breakpoints.md),
    lg: mediaQueryTo(breakpoints.lg),
    xl: mediaQueryTo(breakpoints.xl),
    xxl: mediaQueryTo(breakpoints.xxl),
}

const respondFrom = {
    xs: mediaQueryFrom(breakpoints.xs),
    sm: mediaQueryFrom(breakpoints.sm),
    md: mediaQueryFrom(breakpoints.md),
    lg: mediaQueryFrom(breakpoints.lg),
    xl: mediaQueryFrom(breakpoints.xl),
    xxl: mediaQueryFrom(breakpoints.xxl),
}

function isMobile() {
    const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    const isIPadOS = navigator?.maxTouchPoints > 2 && /Intel Mac/.test(navigator.userAgent);
    return isMobile || isIPadOS;
}

const useMediaSelectTo = (breakpoint) => {
    // 必須在首次 render 就讀取 matchMedia，若初始為 false，
    // <VideoWrapper> 等元件會先掛上桌面版 src，瀏覽器已開始下載，之後再換成手機版會變成載入兩份。
    const [matched, setMatched] = useState(() => {
        if (typeof window === "undefined") return false;
        return window.matchMedia(`(max-width: ${breakpoint}px)`).matches;
    });

    useEffect(() => {
        function handler(x) {
            setMatched(x.matches);
        }
        const x = window.matchMedia(`(max-width: ${breakpoint}px)`)
        handler(x);
        x.addEventListener('change', handler);

        return () => {
            x.removeEventListener('change', handler);
        }
    }, [breakpoint])

    return matched;
}

const useDebouncedResizing = (callback, interval = 300) => {
    const [windowWidth, setWindowWidth] = useState(window.innerWidth);

    useDebounce(() => {
        callback?.();
    }, interval, [windowWidth, interval]);

    useEffect(() => {
        function handleResize() {
            setWindowWidth(window.innerWidth);
        }

        window.addEventListener('resize', handleResize);

        return () => {
            window.removeEventListener('resize', handleResize);
        }
    }, [])
}

export {
    respondTo,
    respondFrom,
    breakpoints,
    isMobile,
    useMediaSelectTo,
    useDebouncedResizing,
};
