import store from '@/store/store';
import { isRTLLanguage } from "@/helpers/common";
const shortCodes = window.wccBannerConfig._shortCodes;
// ****************Utility function***********//
/**
 * Search an element by it's data-tag attribute
 * 
 * @param {string} tag data-tag of an element. 
 * @returns {object}
 */
export function _wccGetElementByTag(tag) {
    const item = document.querySelector('[data-tag=' + tag + ']')
    return item ? item : false;
}

// ********************Banner functions*****************//
export function _wccToggleBanner(force = false) {
    const notice = _wccGetElementByTag('notice');
    const container = notice && notice.closest('.wcc-consent-container') || false;
    if (container) {
        force === true ? container.classList.add('wcc-hide') : container.classList.toggle('wcc-hide');
    }

}
export function _wccGetLaw() {
    return store.state.banners.current.properties.settings.applicableLaw;
}
export function _wccGetType() {
    const preferenceCenter = store.state.banners.current.properties.settings.preferenceCenter;
    return ( preferenceCenter !== 'push-down' ) ? store.state.banners.current.properties.settings.type : 'classic';
}
export function _wccGetBanner() {
    const notice = _wccGetElementByTag('notice');
    const container = notice && notice.closest('.wcc-consent-container') || false;
    return container && container || false;
}
export function _wccHideBanner() {
    const notice = _wccGetBanner();
    notice && notice.classList.add('wcc-hide');
}
export function _wccShowBanner() {
    const notice = _wccGetBanner();
    notice && notice.classList.remove('wcc-hide');
}
export function _wccHideOverLay() {
    const overlay = document.querySelector('.wcc-overlay');
    overlay && overlay.classList.add('wcc-hide');
}
export function _wccShowOverLay() {
    const overlay = document.querySelector('.wcc-overlay');
    overlay && overlay.classList.remove('wcc-hide');
}
export function _wccToggleOverLay() {
    const overlay = document.querySelector('.wcc-overlay');
    overlay && overlay.classList.toggle('wcc-hide');
}
export function _wccGetPreferenceCenter() {
    if (_wccGetType() === 'classic') {
        return _wccGetBanner();
    }
    const element = _wccGetLaw() === 'ccpa' ? _wccGetElementByTag("optout-popup") : _wccGetElementByTag("detail");
    return element && element.closest('.wcc-modal') || false;
}
export function _wccHidePreferenceCenter() {
    const element = _wccGetPreferenceCenter();
    element && element.classList.remove(_wccGetPreferenceClass());
    if (_wccGetType() !== 'classic') _wccHideOverLay();
}
export function _wccShowPreferenceCenter() {
    const element = _wccGetPreferenceCenter();
    element && element.classList.add(_wccGetPreferenceClass());
    if (_wccGetType() !== 'classic') _wccShowOverLay();

}
export function _wccTogglePreferenceCenter() {
    const element = _wccGetPreferenceCenter();
    element && element.classList.toggle(_wccGetPreferenceClass());
    if (_wccGetType() !== 'classic') _wccToggleOverLay();
}
export function _wccGetPreferenceClass() {
    return _wccGetType() === 'classic' ? 'wcc-consent-bar-expand' : 'wcc-modal-open';
}
export function _wccGetRevisit() {
    if (_wccGetLaw() === 'ccpa') return false;
    const revisit = _wccGetElementByTag('revisit-consent');
    return revisit && revisit || false;
}
export function _wccHideRevisit() {
    const revisit = _wccGetRevisit();
    revisit && revisit.classList.add('wcc-revisit-hide')
}
export function _wccShowRevisit() {
    const revisit = _wccGetRevisit();
    revisit && revisit.classList.remove('wcc-revisit-hide')
}

/**
 * Add a class based on the banner type and position. Eg: 'wcc-banner-top'
 * 
 * @returns {boolean}
 */
export function _wccAddPositionClass() {
    const notice = _wccGetElementByTag('notice');
    if (!notice) return false;
    const container = notice.closest('.wcc-consent-container');
    if (!container) return false;
    const preferenceCenter = store.state.banners.current.properties.settings.preferenceCenter;
    const type = ( preferenceCenter !== 'push-down' ) ? store.state.banners.current.properties.settings.type : 'classic';
    let position = store.state.banners.current.properties.settings.position;
    if (type === 'popup') {
        position = 'center';
         //Show overlay when popup visible
         _wccShowOverLay();
         //Add wcc-popup-overflow class to <body> to prevent scroll when layout type is popup
         document.body.classList.add('wcc-popup-overflow');
    }
    const noticeClass = 'wcc' + '-' + type + '-' + position;
    container.classList.add(noticeClass);
    const revisitConsent = _wccGetElementByTag('revisit-consent');
    if (!revisitConsent) return false;
    const revisitPosition = 'wcc-revisit-' + store.state.banners.current.properties.config.revisitConsent.position;
    revisitConsent.classList.add(revisitPosition);
}

// ********************Event Registers******************//
/**
 * Register event handler for all the action elements.
 */
export function _wccRegisterListeners() {
    _wccAttachListener("settings-button", () => _wccTogglePreferenceCenter());
    _wccAttachListener("detail-close", () => _wccHidePreferenceCenter());
    _wccAttachListener("optout-cancel-button", () => _wccHidePreferenceCenter());
    _wccAttachListener("optout-confirm-button", () => _wccHidePreferenceCenter());
    _wccAttachListener("donotsell-button", () => _wccShowPreferenceCenter());
    _wccAttachListener("optout-close", () => _wccHidePreferenceCenter());
    _wccInitiAccordionTabs();
}
/**
 * Bind click event to banner elements.
 * 
 * @param {string} tag data-tag of the element
 * @param {function} fn callback function
 */
export function _wccAttachListener(tag, fn) {
    document.querySelectorAll('[data-tag=' + tag + ']').forEach(item => {
        item && item.addEventListener("click", fn);
    })
}
/**
 * Bind click event to banner inner elements.
 * 
 * @param {string} selector selector of the element
 * @param {function} fn callback function
 */
export function _wccAttachClickEventListener(selector, fn) {
    const item = _wccFindElement(selector);
    item && item.addEventListener("click", fn);
}
// ***************Accordion functions****************//
/**
 * Add support for accordion tabs on the privacy overview screen.
 */
export function _wccInitiAccordionTabs() {
    const banner = store.state.banners.current;
    if (!banner.properties.config.auditTable.status) return;

    const categoryItems = store.state.cookies.items;

    // Extract slugs from categoryItems
    const categoryNames = categoryItems.map(category => category.slug);
    categoryNames.map((category) => {
        const selector = `#wccDetailCategory${category}`;
        _wccAttachClickEventListener(selector, ({ target: { id } }) => {
            if (
                id === `wccSwitch${category}` ||
                !_wccClassToggle(selector, "wcc-accordion-active", false)
            ) {
                return;
            }

            categoryNames
                .filter((categoryName) => categoryName !== category)
                .map((filteredName) =>
                    _wccClassRemove(
                        `#wccDetailCategory${filteredName}`,
                        "wcc-accordion-active",
                        false
                    )
                );
        });
    });
}
export function _wccClassRemove() {
    return _wccClassAction("remove", ...arguments);
}
export function _wccClassToggle() {
    return _wccClassAction("toggle", ...arguments);
}
export function _wccClassAction(action, selector, className, forParent = true) {
    const item = _wccFindElement(selector, forParent);
    return item && item.classList[action](className);
}
export function _wccFindElement(selector, forParent) {
    let createdSelector = selector;
    switch (true) {
        case selector.startsWith("="):
            createdSelector = `[data-tag="${selector.substring(1)}"]`;
            break;
        default:
            break;
    }
    const element = document.querySelector(createdSelector);
    if (!element || (forParent && !element.parentElement)) return null;
    return forParent ? element.parentElement : element;
}
// *****************Toggle Show more / less function *************//
export function _wccSetShowMoreLess() {
    const activeLaw = _wccGetLaw();
    const showCode = shortCodes.find(
        (code) => code.key === "wcc_show_desc"
    );
    const hideCode = shortCodes.find(
        (code) => code.key === "wcc_hide_desc"
    );

    if (!showCode || !hideCode) return;
    const hideButtonContent = hideCode.content;
    const showButtonContent = showCode.content;

    const contentLimit = window.innerWidth < 376 ? 150 : 300;
    const element = document.querySelector(
        `[data-tag="${activeLaw === "gdpr" ? "detail" : "optout"}-description"]`
    );
    const content = element.textContent;
    if (content.length < contentLimit) return;
    const contentHTML = element.innerHTML;
    const htmlDoc = new DOMParser().parseFromString(contentHTML, "text/html");
    const innerElements = htmlDoc.querySelectorAll("body > p");
    if (innerElements.length <= 1) return;
    let strippedContent = ``;
    for (let index = 0; index < innerElements.length; index++) {
        if (index === innerElements.length - 1) return;
        const element = innerElements[index];
        if (`${strippedContent}${element.outerHTML}`.length > contentLimit)
            element.insertAdjacentHTML("beforeend", `...&nbsp;${showButtonContent}`);
        strippedContent = `${strippedContent}${element.outerHTML}`;
        if (strippedContent.length > contentLimit) break;
    }
    function showMoreHandler() {
        element.innerHTML = `${contentHTML}${hideButtonContent}`;
        _wccAttachListener("hide-desc-button", showLessHandler);
    }
    function showLessHandler() {
        element.innerHTML = strippedContent;
        _wccAttachListener("show-desc-button", showMoreHandler);
    }
    showLessHandler();
}
/**
 * Toggle show more or less on click event.
 * 
 * @param {object} object Object containing toggle buttons and texts.
 * @param {*} element Target element.
 */
export function _wccToggleMoreLess(object, element) {
    let {
        currentTarget,
    } = element;
    const ariaExpanded = currentTarget.getAttribute('aria-expanded');
    const trimmed = ariaExpanded === 'false';
    let btn = object.btnTrim;
    let text = object.originalText;
    if (!trimmed) {
        btn = object.btnExpand;
        text = object.truncatedText;
    }
    currentTarget.innerHTML = `${text}&nbsp;${btn}`;
    currentTarget.ariaExpanded = trimmed;
}


/**
 * Replace src attribute with asset's URL.
 * 
 * @param {object} $doc Dom node.
 * @param {string} $tag data-tag of the element.
 * @returns 
 */
export function _wccReplaceSrcAttribute($doc, $tag) {
    const element = $doc.querySelector('[data-tag=' + $tag + ']');
    if (!element) return false;
    let target = element;
    let src = ''

    if (!element.getAttribute('src')) {
        target = element.querySelector('img');
    }

    src = target.src;
    const lastIndex = src.lastIndexOf('/');
    const icon = src.substring(lastIndex + 1);
    target.src = window.wccGlobals.assetsURL + icon;
}
/**
 * Replace footer shadow with current preference center background.
 * 
 * @param {object} $doc Dom node.
 * @returns 
 */
export function _wccSetFooterShadow($doc) {
    const footer = $doc.querySelector('[data-tag="detail"] .wcc-footer-shadow');
    const preference = $doc.querySelector('[data-tag="detail"]');
    if (!footer) return;
    const background = preference && preference.style.backgroundColor || '#ffffff';
    footer.style.background = `linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, ${background
        } 100%)`;
}
// *****************Category checkbox functions*****************//
export function _wccSetPreferenceCheckBoxStates(revisit = false) {
    const categories = store.state.cookies.items;
    const banner = store.state.banners.current;
    let toggle = banner.properties.config.preferenceCenter.elements.categories.elements.toggle;
    _wccSetToggleColor(
        'wccSwitch',
        toggle
    );
    toggle = banner.properties.config.categoryPreview.elements.toggle;
    if (toggle) {
        _wccSetToggleColor(
            'wccCategoryDirect',
            toggle
        );
    }

    for (const category of categories) {
        const checked = category.prior_consent || category.slug === 'necessary';
        const disabled = category.slug === 'necessary';
        _wccSetCheckboxes(
            category,
            checked,
            disabled,
            revisit
        );
        _wccSetPreferenceState(category);
    }
}
function _wccSetCheckboxes(
    category,
    checked,
    disabled,
    revisit = false
) {
    const banner = store.state.banners.current;
    const toggle = banner.properties.config.preferenceCenter.elements.categories.elements.toggle;
    const activeColor = toggle.states.active.styles['background-color'];
    const inactiveColor = toggle.states.inactive.styles['background-color'];

    [`wccCategoryDirect`, `wccSwitch`].map((key) => {
        const boxElem = document.getElementById(`${key}${category.slug}`);
        if (!boxElem) return;
        _wccSetCategoryToggle(
            boxElem,
            category);
        boxElem.checked = checked;
        boxElem.disabled = disabled;
        boxElem.style.backgroundColor = checked ? activeColor : inactiveColor;
        if (revisit) return;
        boxElem.addEventListener("change", ({ currentTarget: elem }) => {
            const isChecked = elem.checked;
            elem.style.backgroundColor = isChecked ? activeColor : inactiveColor;
        });
    });
}
export function _wccSetToggleColor(element, toggle) {
    const activeColor = toggle.states.active.styles['background-color'];
    const inactiveColor = toggle.states.inactive.styles['background-color'];
    document.querySelectorAll(`[id^="${element}"]`).forEach(function (item) {
        let checked = item.checked;
        item.addEventListener("change", ({ currentTarget: elem }) => {
            const isChecked = elem.checked;
            elem.style.backgroundColor = isChecked ? activeColor : inactiveColor;
        });
        item.style.backgroundColor = checked ? activeColor : inactiveColor;
    });
}
export function _wccSetCategoryToggle(element, category = {}) {
    if (element.parentElement.getAttribute('data-tag') === 'detail-category-toggle') {
        _wccSetCategoryPreferenceToggle(element, category);
    } else if (element.parentElement.getAttribute('data-tag') === 'detail-category-preview-toggle') {
        _wccSetCategoryPreview(element, category);
    }
}
export function _wccSetCategoryPreferenceToggle(element, category) {
    const banner = store.state.banners.current;
    let toggleContainer = element.closest('.wcc-accordion-item');
    if (!toggleContainer) return;
    const toggleSwitch = toggleContainer.querySelector('.wcc-switch');
    const necessaryText = toggleContainer.querySelector('.wcc-always-active');
    if (category.slug === 'necessary') {
        toggleSwitch && toggleSwitch.remove();
    } else {
        necessaryText && necessaryText.remove();
        if (_wccGetType() === 'classic' && banner.properties.config.categoryPreview.status || (category.cookie_list && category.cookie_list.length === 0)) {
            toggleSwitch && toggleSwitch.remove();
        }
    }
}
function _wccSetPreferenceState(category) {
    const banner = store.state.banners.current;
    if (banner.properties.config.auditTable.status === false) {
        const tableElement = document.querySelector(
            `#wccDetailCategory${category.slug} [data-tag="audit-table"]`
        );
        tableElement && tableElement.remove();
        const chevronElement = document.querySelector(
            `#wccDetailCategory${category.slug} .wcc-accordion-chevron`
        );
        chevronElement && chevronElement.classList.add("wcc-accordion-chevron-hide");
    }
}
export function _wccSetCategoryPreview(element, category) {
    if ((category.cookie_list && category.cookie_list.length === 0) && category.slug !== 'necessary')
        element.parentElement.parentElement.remove();
}
//*****************Readmore functionality */
// Custom shortcodes functionality.

export function _wccAttachReadMore(parent) {
    const banner = store.state.banners.current;
    const language = store.state.languages.current;
    const readMoreButton = shortCodes.find(
        (code) => code.key === "wcc_readmore"
    );
    if (parent.querySelector('[data-tag="readmore-button"]')) return;
    if (banner.properties.config.notice.elements.buttons.elements.readMore.status === false) return;
    const content = readMoreButton.content;
    const readMoreElement = parent.querySelector(
        '[data-tag="description"]'
    );
    if (!readMoreElement) return;
    const doc = new DOMParser().parseFromString(content, 'text/html');
    const element = doc.querySelector('[data-tag="readmore-button"]');
    if (!element) return false;
    element.innerHTML = banner.contents[language].notice.elements.buttons.elements.readMore;
    if (readMoreElement.childNodes.length > 1) {
        const innerElement = parent.querySelector(
            '[data-tag="description"] p:last-child'
        );
        innerElement && innerElement.insertAdjacentHTML(
            "beforeend",
            `&nbsp;${doc.body.innerHTML}`
        );
    } else {
        readMoreElement.insertAdjacentHTML(
            "beforeend",
            `&nbsp;${doc.body.innerHTML}`
        );
    }
}

export function _wccAddRtlClass() {
    if (!isRTLLanguage()) return;
    const rtlElements = ['notice', 'detail', 'optout-popup', 'revisit-consent', 'video-placeholder']
    rtlElements.forEach(function (item) {
        _wccGetElementByTag(item) && _wccGetElementByTag(item).classList.add('wcc-rtl');
    });
}
export function _wccSetPoweredBy() {
    let position = 'flex-end';
    ['detail-powered-by', 'optout-powered-by'].map((key) => {
        const element = document.querySelector(
            `[data-tag="${key}"]`
        );
        if (!element) return;
        element.style.display = "flex";
        element.style.justifyContent = position;
        element.style.alignItems = "center";
    });

}
export function _wccSetCCPAOptions() {
    const item = _wccGetElementByTag("optout-option");
    if (!item) return;
    item.classList.remove('wcc-disabled');
    const banner = store.state.banners.current;
    const toggle = banner.properties.config.optoutPopup.elements.optOption.elements.toggle;
    const activeColor = toggle.states.active.styles['background-color'];
    const inactiveColor = toggle.states.inactive.styles['background-color'];
    const boxElem = document.getElementById(`wccCCPAOptOut`);
    if (!boxElem) return;
    _wccAttachListener("optout-option-title", () => boxElem.click());
    boxElem.style.backgroundColor = inactiveColor;
    boxElem.addEventListener("change", ({ currentTarget: elem }) => {
        const isChecked = elem.checked;
        elem.style.backgroundColor = isChecked ? activeColor : inactiveColor;
    });
}