import { observable, runInAction, set } from "mobx";

import { getSanitizedControlValue, getSidebarCustomize } from "@devowl-wp/customize";

import type { CustomizeBannerStore } from "../store/customizeBanner.js";
import type { RootStore } from "../store/stores.js";
import type { ResponseRoutePresetsBannerGet } from "../wp-api/presetsBanner.get.js";

class BannerPreset {
    @observable
    public id: string;

    @observable
    public name: string;

    @observable
    public needsPro?: boolean;

    @observable
    public description?: string;

    @observable
    public tags?: Array<[string, string]>;

    @observable
    public settings: {
        [setting: string]: any;
    };

    public readonly store: CustomizeBannerStore;

    /**
     * When hover the preview card we need to save the available settings.
     */
    public resetPreviewInUiSettings: {
        // key: [section, setting, value]
        [setting: string]: [string, string, any];
    };

    public constructor(preset: Partial<ResponseRoutePresetsBannerGet["items"][0]>, store: CustomizeBannerStore) {
        runInAction(() => set(this, preset));
        this.store = store;
    }

    public static getIframeStore() {
        try {
            return ((document.querySelector("#customize-preview > iframe") as HTMLIFrameElement).contentWindow as any)
                .realCookieBanner_customize_banner.RootStore.get as RootStore;
        } catch (e) {
            // Element does not yet exist
            return undefined;
        }
    }

    public applyInUi() {
        // Check if pro
        if (!this.store.rootStore.optionStore.others.isPro && this.needsPro) {
            return false;
        }

        const customize = getSidebarCustomize();

        // First, save all in our store so the paint is done correctly
        this.previewInUi();

        // Afterwards, save in customize state
        setTimeout(() => {
            this.store.presetDefaults.forEach((defaultValue, key) => {
                const setting = customize(key);

                // Apply it
                setting.set(this.settings[key] === undefined ? defaultValue : this.settings[key]);
            });
        }, 100);
        return true;
    }

    public previewInUi() {
        const { presetDefaults } = this.store;
        const { settings } = this.store.rootStore.optionStore.others.customizeIdsBanner as any;
        const batchUpdates: Array<[string, string, any]> = [];

        // Make it restorable
        this.resetPreviewInUiSettings = {};

        for (const section of Object.keys(settings)) {
            const sectionSettings = settings[section];

            for (const setting of Object.keys(sectionSettings)) {
                const customizeKey = (sectionSettings as any)[setting] as string;
                if (!presetDefaults.has(customizeKey)) {
                    continue;
                }

                const val = getSanitizedControlValue(customizeKey, presetDefaults.get(customizeKey));

                if (val !== null) {
                    this.resetPreviewInUiSettings[customizeKey] = [section, setting, val];
                    const newValue = Object.prototype.hasOwnProperty.call(this.settings, customizeKey)
                        ? this.settings[customizeKey]
                        : presetDefaults.get(customizeKey);

                    batchUpdates.push([section, setting, newValue]);
                }
            }
        }

        BannerPreset.getIframeStore().customizeBannerStore.setBannerFromPreset(batchUpdates as any);
    }

    public resetPreviewInUi() {
        if (this.resetPreviewInUiSettings) {
            BannerPreset.getIframeStore().customizeBannerStore.setBannerFromPreset(
                Object.values(this.resetPreviewInUiSettings) as any,
            );

            this.resetPreviewInUiSettings = {};
        }
    }
}

export { BannerPreset };
