import {getThumb, isAudioType} from "../../../includes/functions";

const {useRef, useEffect} = React;

export default function PlayerComponent({
                                            file,
                                            isPlaying,
                                            setIsPlaying,
                                            playNext,
                                            playPrev,
                                            handleDownload,
                                            nextPrevious,
                                            rewindForward,
                                            download,
                                            playableItems,
                                            playlistAutoplay,
                                            showPlaylist,
                                            isLoop,
                                            isOpenPlaylist,
                                            setIsOpenPlaylist,
                                            isShuffle,
                                            setIsLoop,
                                            setIsShuffle,
                                            shortcodeId,
                                            nonce,
                                        }) {
    const playerElementRef = useRef(null);
    const playerRef = useRef(null);
    const {id, accountId} = file || {};
    const isAudio = file && isAudioType(file);
    const src = `${igd.ajaxUrl}?action=igd_stream&id=${id}&account_id=${accountId}&shortcodeId=${shortcodeId}&nonce=${nonce}`;
    const poster = file && getThumb(file, 'large');

    const i18n = wp.i18n;
    const settingsOptions = {
        loop: {
            label: i18n.__('Loop', 'integrate-google-drive'),
            state: isLoop,
            setState: setIsLoop,
        },
        shuffle: {
            label: i18n.__('Shuffle', 'integrate-google-drive'),
            state: isShuffle,
            setState: setIsShuffle,
        },
        playlist: {
            label: i18n.__('Playlist', 'integrate-google-drive'),
            state: isOpenPlaylist,
            setState: setIsOpenPlaylist,
        },
    };

    const options = {
        controls: [
            'play-large',
            ...(rewindForward ? ['rewind'] : []),
            'play',
            ...(rewindForward ? ['fast-forward'] : []),
            'current-time', 'progress', 'duration',
            'mute', 'volume',
            'captions', 'settings', 'pip', 'airplay', 'fullscreen'
        ],
        settings: ['speed', 'loop', 'shuffle', 'playlist'],
        speed: {selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 2]},
        i18n: {
            shuffle: settingsOptions.shuffle.label,
            loop: settingsOptions.loop.label,
            playlist: settingsOptions.playlist.label,
        },
        keyboard: {focused: true, global: true},
        disableContextMenu: !download,
    };

    useEffect(() => {
        const $ = jQuery;
        const playerElement = playerElementRef.current;
        if (!playerElement) return;

        const media = playerElement.querySelector('video, audio');

        playerRef.current = new Plyr(media, options);

        // Wait for media to be ready
        media.addEventListener('loadedmetadata', () => {

            const savedTime = parseFloat(sessionStorage.getItem(`igd_playback_time_${shortcodeId}_${id}`));
            if (!isNaN(savedTime) && savedTime > 0 && savedTime < media.duration) {
                playerRef.current.currentTime = savedTime;
            }

        }, {once: true});

        // Save current time periodically
        playerRef.current.on('timeupdate', () => {
            const currentTime = playerRef.current.currentTime;
            sessionStorage.setItem(`igd_playback_time_${shortcodeId}_${id}`, currentTime);
        });

        // Clean up session storage on player events
        playerRef.current.on('ended pause error', () => {
            sessionStorage.removeItem(`igd_playback_time_${shortcodeId}_${id}`);
        });

        if (nextPrevious && playableItems.length > 1) {
            addNextPreviousButtons($, playerElement, playPrev, playNext);
        }

        const menuContainer = $(playerElement).find('.plyr__menu__container > div > div:first-child [role="menu"]');
        const menuIdNumber = menuContainer.parent().attr('id')?.match(/(\d+)/)?.[0];

        if (!showPlaylist || $(playerElement).find('[data-plyr-menu="playlist"]').length) {
            delete settingsOptions.playlist;
        }

        Object.entries(settingsOptions).forEach(([key, {label, state, setState}]) => {
            addToggleMenu($, playerElement, menuContainer, key, label, state, setState, menuIdNumber);
        });

        if (download) {
            addDownloadButton($, playerElement, menuContainer, handleDownload);
        }

        playerRef.current.on('ended', () => {
            if (isLoop || playlistAutoplay) {
                playNext(true);
            }
        });

        return () => {
            playerRef.current?.destroy();
        };

    }, [file]);

    useEffect(() => {
        if (!playerRef.current) return;

        if (isPlaying) {

            playerRef.current.play().catch(() => {
                setIsPlaying(false);
            });

            sessionStorage.setItem(`igd_playback_${shortcodeId}`, id);
        } else {
            playerRef.current.pause();
            sessionStorage.removeItem(`igd_playback_${shortcodeId}`);
        }

    }, [isPlaying, file]);

    const mediaHtml = isAudio
        ? `<audio src="${src}" controls preload="none"></audio>`
        : `<video class="igd-player-media-video" src="${src}" width="100%" height="100%" controls poster="${poster}" preload="none"></video>`;

    return (
        <div className="igd-player-media-wrap" ref={playerElementRef} dangerouslySetInnerHTML={{__html: mediaHtml}}/>
    );
}

function addNextPreviousButtons($, playerElement, playPrev, playNext) {
    const prevButton = $('<button type="button" class="plyr__controls__item plyr__control" aria-label="Previous" data-plyr="prev"><svg width="18" height="18" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z"/></svg></button>').on('click', playPrev);
    const nextButton = $('<button type="button" class="plyr__controls__item plyr__control" aria-label="Next" data-plyr="next"><svg width="18" height="18" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z"/></svg></button>').on('click', playNext);

    const insertBefore = $(playerElement).find('.plyr__controls [data-plyr="rewind"]').length
        ? $(playerElement).find('.plyr__controls [data-plyr="rewind"]')
        : $(playerElement).find('.plyr__controls [data-plyr="play"]');

    const insertAfter = $(playerElement).find('.plyr__controls [data-plyr="fast-forward"]').length
        ? $(playerElement).find('.plyr__controls [data-plyr="fast-forward"]')
        : $(playerElement).find('.plyr__controls [data-plyr="play"]');

    prevButton.insertBefore(insertBefore);
    nextButton.insertAfter(insertAfter);
}

function addToggleMenu($, playerElement, menuContainer, key, label, isEnabled, setEnabled, menuIdNumber) {
    if ($(playerElement).find(`[data-plyr-menu="${key}"]`).length) return;

    const enableText = 'playlist' === key ? wp.i18n.__('Show', 'integrate-google-drive') : wp.i18n.__('Enable', 'integrate-google-drive');
    const disableText = 'playlist' === key ? wp.i18n.__('Hide', 'integrate-google-drive') : wp.i18n.__('Disable', 'integrate-google-drive');

    const toggleButton = $(`
        <button data-plyr="settings" type="button" class="plyr__control plyr__control--forward" role="menuitem" data-plyr-menu="${key}" aria-haspopup="true">
            <span>${label}<span class="plyr__menu__value">${isEnabled ? enableText : disableText}</span></span>
        </button>
    `).on('click', () => {
        $(`#plyr-settings-${menuIdNumber}-home`).prop('hidden', true);
        $(`#plyr-settings-${menuIdNumber}-${key}`).prop('hidden', false);
    });

    menuContainer.append(toggleButton);

    const enableBtn = $(`<button type="button" role="menuitemradio" class="plyr__control" aria-checked="${isEnabled}" value="enable"><span>${enableText}</span></button>`)
        .on('click', function () {
            setEnabled(true);
            $('.plyr__control.plyr__control--back').click();
            toggleButton.find('.plyr__menu__value').text(enableText);
            $(this).attr('aria-checked', 'true').siblings().attr('aria-checked', 'false');
        });

    const disableBtn = $(`<button type="button" role="menuitemradio" class="plyr__control" aria-checked="${!isEnabled}" value="disable"><span>${disableText}</span></button>`)
        .on('click', function () {
            setEnabled(false);
            $('.plyr__control.plyr__control--back').click();
            toggleButton.find('.plyr__menu__value').text(disableText);
            $(this).attr('aria-checked', 'true').siblings().attr('aria-checked', 'false');
        });

    $(`#plyr-settings-${menuIdNumber}-${key} [role="menu"]`).append(enableBtn).append(disableBtn);
}

function addDownloadButton($, playerElement, menuContainer, handleDownload) {
    if ($(playerElement).find('[data-plyr-menu="download"]').length) return;

    const downloadBtn = $(`
        <button data-plyr="settings" type="button" class="plyr__control" role="menuitem" data-plyr-menu="download" aria-haspopup="true">
            <span>${wp.i18n.__('Download', 'integrate-google-drive')}</span>
        </button>
    `).on('click', () => {
        $(playerElement).find('.plyr__controls__item > [data-plyr="settings"]').click();
        handleDownload();
    });

    menuContainer.append(downloadBtn);
}