import { getSidebarCustomize, listenPanelExpanded, previewFactory, xssHtmlSanitize } from "@devowl-wp/customize";
import { applyQueryString } from "@devowl-wp/utils";

import { RootStore } from "../store/stores.js";

/**
 * Apply common callbacks in customize banner preview.
 */
function applyCustomizeBannerPreview() {
    const { customizeBannerStore, optionStore, checklistStore } = RootStore.get;
    const {
        others: {
            customizeIdsBanner: { panel, sections, settings },
        },
    } = optionStore;

    /**
     * We need to debounce all our bound events. Why? When you do a
     * page reload or navigation, the reference to the e. g. store is lost
     * and Chrome is stuck.
     */
    const debounce = (callback: (...args: any[]) => any) => setTimeout(callback, 0);

    // When hovering over "checkbox checked state" controls, simulate all checkboxes as checked
    const customize = getSidebarCustomize();
    const { group, sticky, texts } = settings;

    [group.checkboxActiveBg, group.checkboxActiveBorderColor, group.checkboxActiveColor].forEach((id) =>
        customize.control(id, ({ container }: { container: JQuery }) =>
            container.hover(
                () => debounce(() => customizeBannerStore.setPreviewCheckboxActiveState(true)),
                () => debounce(() => customizeBannerStore.setPreviewCheckboxActiveState(false)),
            ),
        ),
    );

    // Automatically open the individual privacy settings when opening the given sections
    [sections.individualLayout, sections.group, sections.saveButton, sections.individualTexts].forEach((sectionId) =>
        listenPanelExpanded(sectionId, (state) => {
            debounce(() => customizeBannerStore.setIndividualPrivacyOpen(state));
        }),
    );

    // Automatically hide the cookie banner and show the sticky legal links
    listenPanelExpanded(sections.sticky, (state) => {
        debounce(() => customizeBannerStore.setVisible(!state));
    });

    // Navigate to cookie policy page
    // See also https://make.xwp.co/2016/07/21/navigating-to-a-url-in-the-customizer-preview-when-a-section-is-expanded/
    listenPanelExpanded(sections.cookiePolicy, (state) =>
        customize.section(
            sections.cookiePolicy,
            ({
                params: {
                    customParams: { url },
                },
            }) => {
                const { previewUrl } = customize.previewer;
                const { href } = window.location;
                const customizePreviousUrl = new URL(href).searchParams.get("customizePreviousUrl");

                if (state && !customizePreviousUrl) {
                    previewUrl.set(
                        applyQueryString(new URL(url), {
                            customizePreviousUrl: href,
                        }).toString(),
                    );
                } else if (!state && customizePreviousUrl) {
                    previewUrl.set(customizePreviousUrl);
                }
            },
        ),
    );

    [
        sticky.bubbleMargin,
        sticky.bubbleHoverBg,
        sticky.bubbleHoverBorderColor,
        sticky.hoverIconColor,
        sticky.hoverIconCustom,
        sticky.hoverIconCustomRetina,
        sticky.menuFontSize,
        sticky.menuBorderRadius,
        sticky.menuItemSpacing,
        sticky.menuItemPadding,
    ].forEach((id) =>
        customize.control(id, ({ container }: { container: JQuery }) =>
            container.hover(
                () => debounce(() => customizeBannerStore.setPreviewStickyMenuOpenState(true)),
                () => debounce(() => customizeBannerStore.setPreviewStickyMenuOpenState(false)),
            ),
        ),
    );

    [texts.stickyChange, texts.stickyHistory, texts.stickyRevoke, texts.stickyRevokeSuccessMessage].forEach((id) =>
        customize.control(id, ({ container }: { container: JQuery }) =>
            container.hover(
                () =>
                    debounce(() => {
                        customizeBannerStore.setVisible(false);
                        customizeBannerStore.setPreviewStickyMenuOpenState(true);
                    }),
                () =>
                    debounce(() => {
                        customizeBannerStore.setVisible(true);
                        customizeBannerStore.setPreviewStickyMenuOpenState(false);
                    }),
            ),
        ),
    );

    previewFactory({
        immediateApply: {
            texts: settings.texts,
            individualTexts: settings.individualTexts,
        },
        onChange: [
            settings,
            (section, setting, newValue) =>
                debounce(() => {
                    const sanitizedValue =
                        ["individualTexts", "texts"].indexOf(`${section}`) > -1 ? xssHtmlSanitize(newValue) : newValue;
                    customizeBannerStore.setBannerFromCustomize(section as any, setting, sanitizedValue);
                }),
        ],
        onPanelChange: [
            panel,
            (state) =>
                debounce(() => {
                    const isCookiePolicyExpanded = customize.section(sections.cookiePolicy).expanded();
                    customizeBannerStore.setVisible(isCookiePolicyExpanded ? false : state);
                    state && checklistStore.toggleChecklistItem("customize-banner", true);
                }),
        ],
    });
}

export { applyCustomizeBannerPreview };
