/**
 * Javascript helper functions for banner related functions.
 *
 * @since 3.0.0
 * @author Sarath GP <sarath.gp@mozilor.com>
 *
 */

import store from '@/store/store';
import wccRest from "@/helpers/api";
import preview from "@/modules/banners/helpers/preview";
import translate from '@/plugins/translations'

let $i18n = translate;
const banners = {
    /**
     * Get all the banners from the store
     *
     * @since 3.0.0
     * @returns {Promise<string>|object} JSON
     */
    getBanners: async function () {
        let banners = store.state.banners.items || await store.dispatch('banners/reInit');
        banners = JSON.parse(JSON.stringify(store.state.banners.items));
        return banners;
    },
    /**
     * Get active banner from store
     *
     * @since 3.0.0
     * @returns {object|boolean} JSON
     */
    getCurrentBanner: async function () {
        let banner = store.state.banners.current;
        if (banner.id > 0) return banner;
        try {
            let banners = await this.getBanners();
            if (typeof banners === 'object') {
                banner = banners.find(function (banner) {
                    return banner.default == true;
                });
                if (!banner) {
                    banner = banners[0];
                }
            }
            if (banner) {
                await store.dispatch('banners/setCurrentBanner', banner)
                return store.state.banners.current;
            }
            return await this.getDefault();
        } catch (error) {
            console.log(error)
        }
        return banner;
    },
    getActiveBanner: async function () {
        let banner = {};
        let banners = await this.getBanners();
        if (typeof banners === 'object') {
            banner = banners.find(function (banner) {
                return banner.status == true;
            });
            if (!banner) {
                banner = banners[0];
            }
        }
        if (banner) {
            await store.dispatch('banners/setCurrentBanner', banner)
        }
        return banner;
    },
    getCurrentActiveBanner: async function ( currentLaw ) {
        let banner = {};
        let banners = await this.getBanners();
        if (typeof banners === 'object') {
            banner = banners.find(function (banner) {
                return banner.name == currentLaw;
            });
            if (!banner) {
                banner = banners[0];
            }
        }
        if (banner) {
            await store.dispatch('banners/setCurrentBanner', banner)
        }
        return banner;
    },
    getBannerById: async function (id) {
        let banner = {};
        let banners = await this.getBanners()
        if (typeof banners === 'object') {
            if (id && id > 0) {
                banner = banners.find(function (banner) {
                    return banner.id == id;
                });
            }
        }
        return banner;
    },
    getBannerByLaw: async function (law) {
        let banner = {};
        let banners = await this.getBanners()
        if (typeof banners === 'object') {
            if (law) {
                banner = banners.find(function (banner) {
                    return banner.properties.settings.applicableLaw == law;
                });
            }
        }
        return banner;
    },
    getBannerBySlug: async function (slug) {
        let banner = {};
        let banners = await this.getBanners()
        if (typeof banners === 'object') {
            if (slug && slug !== '') {
                banner = banners.find(function (banner) {
                    return banner.slug == slug;
                });
            }
        }
        return banner;
    },
    setCurrent: async function (banner) {
        if (banner) {
            await store.dispatch('banners/setCurrentBanner', banner)
        }
    },
    getDefault: async function () {
        let data = {
            name: "",
            properties: {
                settings: {},
                config: {},
            },
        };
        await this.loadConfigs();
        const configs = store.state.banners.configs;
        data.properties.config = configs.gdpr.config;
        data.properties.settings = configs.gdpr.settings;
        return data;
    },
    saveBanner: async function (currentLaw) {
        let currentlanguage = store.state.languages.current;
        let banner = await this.getCurrentActiveBanner(currentLaw);
        if (banner.name) {
            return await store.dispatch('banners/saveBanner', { 'banner': banner, 'params': { 'language': currentlanguage } });
        } else {
            return await this.createBanner(banner);
        }
    },
    save: async function () {
        let currentlanguage = store.state.languages.current;
        let banner = await this.getCurrentBanner();
        if (banner.id) {
            return await store.dispatch('banners/saveBanner', { 'banner': banner, 'params': { 'language': currentlanguage } });
        } else {
            return await this.createBanner(banner);
        }
    },
    createBanner: async function (data) {
        let success = false;
        await wccRest
            .post({
                path: `/banners`,
                data: data,
            })
            .then((response) => {
                if (response.id) success = true;
            });
        if (success === true) {
            await store.dispatch('banners/reInit');
        }
        return success;
    },
    deleteBanner: async function (bannerId) {
        if (bannerId) {
            let success = false;
            await wccRest
                .delete({
                    path: `/banners/${bannerId}`,
                })
                .then((response) => {
                    if (response) success = true;
                });
            if (success === true) {
                await store.dispatch('banners/reInit');
            }
            return success;
        }
    },
    updateBanner: async function (banner) {
        let bannerId = banner.id;
        if (bannerId) {
            let success = false;
            await wccRest
                .post({
                    path: `/banners/${bannerId}`,
                    data: banner
                })
                .then((response) => {
                    if (response) success = true;
                });
            if (success === true) {
                await store.dispatch('banners/reInit');
            }
            return success;
        }
    },
    /**
     * Generate preview based on banner values
     * 
     * @param {object} banner Banner object.
     * @param {boolean} render check if banner should be rendered or not.
     */
    generatePreview: async function () {
        await preview.generate();
    },
    clearTemplate: function () {
        preview.clearTemplate();
    },
    showPreview: async function (force = false) {
        await preview.showPreview(force);
    },
    forceShowPreview: async function () {
        preview.forceShowPreview();
    },
    forceRerenderPreview: async function () {
        await preview.forceRerenderPreview();
    },
    hidePreview: function () {
        preview.hidePreview();
    },
    closePreview: function (clear = true) {
        preview.closePreview(clear);
    },
    getLayouts: function () {
        let bannerTypes = [
            {
                type: "box",
                title: $i18n.__("Box Type", "webtoffee-cookie-consent"),
                positions: ["bottom-left", "bottom-right", "top-left", "top-right"],
                default: "bottom-left",
                preferenceCenter: ["center"],
            },
            {
                type: "banner",
                title: $i18n.__("Banner Type", "webtoffee-cookie-consent"),
                positions: ["bottom", "top"],
                default: "bottom",
                preferenceCenter: ["center", "push-down"],
            },
            {
                type: "popup",
                title: $i18n.__("Popup Type", "webtoffee-cookie-consent"),
                positions: ["center"],
                default: "center",
                preferenceCenter: ["center"],
            },
        ];
        return bannerTypes;
    },
    getContentSections: function (applicableLaw = "") {
        let contentSections = [];
        if (applicableLaw !== "") {
            switch (applicableLaw) {
                case 'ccpa':
                    contentSections = [
                        { id: "accordion-notice" },
                        { id: "accordion-opt-out-center" },
                        { id: "accordion-cookie-list" },
                        { id: "accordion-revisit-consent" },
                        { id: "accordion-blocked-content" },
                    ];
                    break;
                default:
                    contentSections = [
                        { id: "accordion-notice" },
                        { id: "accordion-preference" },
                        { id: "accordion-cookie-list" },
                        { id: "accordion-revisit-consent" },
                        { id: "accordion-blocked-content" },
                    ];
                    break;
            }
        }
        return contentSections;
    },

    // Deprecated functions
    loadPresets: async function () {
        const banner = store.state.banners.current;
        const versionID = banner && banner.properties.settings.versionID || '6.0.0';
        if (store.state.banners.presets.length <= 0) {
            await wccRest
                .get({
                    path: `/banners/presets/`,
                    params: { ver: versionID },
                })
                .then((response) => {
                    if (response) store.dispatch('banners/setPresets', response);
                });
        }
    },
    loadConfigs: async function () {
        let success = false;
        let response = [];
        if (store.state.banners.configs.length <= 0) {
            response = await wccRest
                .get({
                    path: `/banners/configs/`,
                })
                .then((response) => {
                    if (response) success = true;
                    return response;
                });
            if (success === true) await store.dispatch('banners/setConfigs', response);
        }
        return store.state.banners.configs
    },
    resetConfigs: function (law = 'gdpr') {
        const banner = store.state.banners.current;
        const configs = store.state.banners.configs;
        const properties = (configs[law] && configs[law]) ||
            (configs["gdpr"] && configs["gdpr"]) ||
            [];
        const config = properties.config;
        const settings = properties.settings;
        banner.properties.config = config;
        banner.properties.settings.type = settings.type;
    },
    checkForChanges: function (target, source) {
        if (target instanceof Object && source instanceof Object) {
            for (const key in source) {
                if (!target[key]) {
                    continue;
                }
                if (this.checkForChanges(target[key], source[key])) {
                    return true;
                }
            }
        } else {
            if (target.toUpperCase() !== source.toUpperCase()) {
                return true;
            }
        }
        return false;
    },
    resetTheme: function () {
        const banner = store.state.banners.current;
        if (!banner) return false;
        const theme = banner.properties.settings.theme;
        const preset = store.state.banners.presets.find((preset) => preset.name == theme);
        if (!preset) return false;
        const changed = this.checkForChanges(banner.properties.config, preset.settings);
        if (changed === true) {
            store.state.banners.current.properties.settings.theme = 'custom';
        }
    },
    resetPreset() {
        const banner = store.state.banners.current;
        if (!banner) return false;
        const theme = banner.properties.settings.theme;
        const preset = store.state.banners.presets.find((preset) => preset.name == theme);
        if (!preset) return false;
        const settings = preset.settings;
        banner.properties.config = this.arrayReplaceRecursive(banner.properties.config, settings);
    },
    arrayReplaceRecursive(arr) {
        let retObj = {},
            i = 0,
            p = '',
            argl = arguments.length;

        if (argl < 2) {
            throw new Error('There should be at least 2 arguments passed to arrayReplaceRecursive()');
        }
        // Although docs state that the arguments are passed in by reference, it seems they are not altered, but rather the copy that is returned (just guessing), so we make a copy here, instead of acting on arr itself
        for (p in arr) {
            retObj[p] = arr[p];
        }
        for (i = 1; i < argl; i++) {
            for (p in arguments[i]) {
                if (retObj[p] && typeof retObj[p] === 'object') {
                    retObj[p] = this.arrayReplaceRecursive(retObj[p], arguments[i][p]);
                } else {
                    retObj[p] = arguments[i][p];
                }
            }
        }
        return retObj;
    },
    loadTemplate: async function () {
        try {
            await preview.getTemplate(true);
        } catch (error) {
            console.error(error)
        }
    },
    updateContentPreview: async function () {
        if (store.state.banners.preview) await banners.showPreview(true);
        else {
            await preview.resetTemplate()
            await banners.loadTemplate();
        }
    },
    async bulkUpdate() {
        let banners = store.state.banners.items;
        const current = store.state.banners.current;
        banners.forEach(function (banner, index) {
            if (banner.id === current.id) {
                banner = current;
                banners[index] = banner;
            }
        });
        return await wccRest
            .post({
                path: `/banners/bulk`,
                data: { banners: banners }, 
            })
            .then(async (response) => {
                if (response.length > 0) await store.dispatch('banners/reInit');
            });
    },
    async toggleBanner(id = false) {
        const current = store.state.banners.current;
        if (!id || id === current.id) return;
        let banners = await this.getBanners();
        banners.forEach(function (banner, index) {
            if (banner.id === current.id) {
                banner = current;
                banner.status = true;
            }
            banner.status = !banner.status;
            banners[index] = banner;
        });
        await store.dispatch('banners/setBanners', banners);
        const banner = await this.getActiveBanner();
        await store.dispatch('banners/setCurrentBanner', banner)
    },
    hasErrors() {
        const errors = store.state.banners.errors;
        return !!Object.keys(errors).length
    },
    setErrors(errors) {
        store.dispatch('banners/setErrors', errors);
    },
    reset() {
        store.state.banners.items = false;
    }
}
export default banners;