import BaseComponent from "../BaseComponent";
import UserUtil from "../../Utils/UserUtil";
import AppData from "../../Common/AppData";
import EventBus, { Events, Event } from "../../Events/EventBus";
import Utils from "../../Utils/Utils";
import { fetchData } from "../../Utils/Fetch";
import Player from "../../BackgroundJobs/Player";


class Background {
    init() {
        if (!jQuery('.background-ui')[0]) {
            return;
        }
        if (jQuery('.background-ui').data('initializied') !== 'true') {
            new BackgroundHandler(jQuery('.background-ui'));
        }
    }
}

class BackgroundHandler extends BaseComponent {

    _currentBackgroundId;
    _currentPlaylistId;

    constructor(component_base_ui) {
        super(component_base_ui);
        const default_background = AppData.getInstance().get('default_background');
        if (!default_background) {
            console.warn('Missing default background 1');
        }
        this._handleEvents();
        this._animateBackground(jQuery('.app-background'));
    }

    _handleEvents() {
        const defaultBackgroundChange = new Event(
            Events.DEFAULT_BACKGROUND_CHANGE,
            (payload) => {
                const { bid } = payload;
                this._handleDefaultBackgroundChange(bid, {
                    saveDefault: true
                });
            }
        );
        EventBus.getInstance().registerEvent(defaultBackgroundChange);

        const deployPlaylistBackground = new Event(
            Events.DEPLOY_PLAYLIST_BACKGROUND,
            (payload) => {
                const { playlistData } = payload;
                this._currentPlaylistId = playlistData?.id;
                const playlistBackgroundId = playlistData?.backgroundId;
                const playingPlaylistId = Player.getInstance().getPlaylistId();
                const areSoundsPlaying = Player.getInstance().areSoundsPlaying();
                if (playingPlaylistId === this._currentPlaylistId && areSoundsPlaying) {
                    if (!playlistBackgroundId || playlistBackgroundId === '-1') {
                        this._handleDefaultBackgroundChange(-1);
                    }
                    if (playlistBackgroundId && playlistBackgroundId !== '-1') {
                        this._handleDefaultBackgroundChange(playlistBackgroundId);
                    }
                }
            }
        );
        EventBus.getInstance().registerEvent(deployPlaylistBackground);

        const removePlaylistBackground = new Event(
            Events.REMOVE_PLAYLIST_BACKGROUND,
            (payload) => {
                const { playlistData } = payload;
                this._currentPlaylistId = playlistData?.id;
                const playingPlaylistId = Player.getInstance().getPlaylistId();
                const areSoundsPlaying = Player.getInstance().areSoundsPlaying();
                if (!areSoundsPlaying) {
                    // restore to default background
                    this._handleDefaultBackgroundChange(-1);
                }
            }
        );
        EventBus.getInstance().registerEvent(removePlaylistBackground);
    }

    _handleDefaultBackgroundChange(bid, options = {}) {
        const { saveDefault } = options;
        const allBackgrounds = AppData.getInstance().get('all_backgrounds');
        if (!Array.isArray(allBackgrounds)) {
            console.warn('Missing backgrounds');
            return;
        }

        let template = '';
        let foundBackgroundId = null;
        let background = null;
        let default_background;

        if (!bid || bid === -1 || bid === "-1") {
            if (UserUtil.isLoggedIn()) {
                const userbackgroundid = UserUtil.getUserMetaByKey('userbackgroundid');
                if (userbackgroundid && userbackgroundid !== -1 && userbackgroundid !== '-1') {
                    default_background = allBackgrounds.find(item => item.id === Number(userbackgroundid));
                }
            }

            // change to sys default
            if (!default_background || default_background === '-1' || default_background === -1) {
                default_background = AppData.getInstance().get('default_background');
            }
            if (!default_background) {
                console.warn('Missing default background 2');
            }
            
            if (saveDefault) {
                this._updateDefaultUserBackground(bid);
            }
            foundBackgroundId = default_background?.id;
            background = default_background;
            template = this._getBackgroundTemplate(default_background);
        } else {
            const foundBackground = allBackgrounds.find(item => item.id === Number(bid));
            if (foundBackground) {
                foundBackgroundId = foundBackground?.id;
                background = foundBackground;
                template = this._getBackgroundTemplate(foundBackground);
                if (saveDefault) {
                    this._updateDefaultUserBackground(bid);
                }
            }
        }

        const show_backgrounds_credits = AppData.getInstance().get('show_backgrounds_credits');
        const background_credits_label = background?.background_credits_label || '';
        const background_credits_url = background?.background_credits_url || '';

        if (background && show_backgrounds_credits && background_credits_label !== '' && background_credits_url !== '') {
            jQuery('.credits-ui').removeClass('hidden');
            jQuery('.credits-link').attr('href', background_credits_url);
            jQuery('.credits-link').html(background_credits_label);
        } else {
            jQuery('.credits-ui').addClass('hidden');
        }

        if (this._currentBackgroundId === foundBackgroundId) {
            return;
        }

        this._currentBackgroundId = foundBackgroundId;
        
        // set new background
        if (template === '') {
            console.warn('Invalid background template', bid);
            return;
        }

        const backgroundUI = jQuery(template);
        const htmlId = jQuery(backgroundUI).attr('id');
        
        backgroundUI.appendTo(this._component_base_ui);
        setTimeout(() => {
            this._animateBackground(backgroundUI);
        }, 50);
    }

    _animateBackground(backgroundUI) {
        backgroundUI.removeClass('opacity-0').addClass('opacity-100');
        backgroundUI.removeClass('scale-105').addClass('scale-100');
        if (this._backgroundTimeout) {
            clearTimeout(this._backgroundTimeout);
        }
        this._backgroundTimeout = setTimeout(() => {
            
            backgroundUI.removeClass('scale-100').addClass('scale-102');
            backgroundUI.css('transition-timing-function', 'ease-in-out');

            const count = this._component_base_ui.children().length;

            jQuery('.app-background').each(function(index) {
                if (jQuery(this).attr('id') !== backgroundUI.attr('id')) {
                    jQuery(this).remove();
                }
            })
        }, 1500)
    }

    _getBackgroundTemplate(backgroundData) {
        const { id, type, video_url, image_url_full } = backgroundData;
        const guid = Utils.guid();
        switch (type) {
            case 'image':
                return `
                    <div id="${guid}" class="absolute inset-0 w-full h-full top-0 left-0 bg-cover bg-center transform scale-105 opacity-0 transition-all duration-[1500ms] ease-out app-background" style="background-image: url('${image_url_full}'); transition-property: opacity, transform; transition-duration: 1000ms, 3500ms;"></div>
                `;
            case 'video':
                return `
                    <div id="${guid}" class="absolute inset-0 w-full h-full top-0 left-0 opacity-0 scale-105 transition-all duration-[1500ms] ease-out app-background" style="transition-property: opacity, transform; transition-duration: 1000ms, 1500ms;">
                        <video class="w-full h-full object-cover" autoplay loop muted playsinline>
                            <source src="${video_url}" type="video/mp4">
                        </video>
                    </div>
                `;
        }
    }

    async _updateDefaultUserBackground(bid) {
        const isLoggedIn = UserUtil.isLoggedIn();
        if (!isLoggedIn) {
            return;
        }
        const result = await fetchData('user-background', 'PUT', { background: { bid } }, true, true, true);
    }


}

export default Background;