import {merge} from 'lodash';
import {exportRows} from './helpers/exportUtils';
import {
    bodyCanScroll,
    dashboardState,
    makeBodyscrollabble,
    makeBodyUnscrollabble,
    onClassicSidebarMenuIsBeingHovered,
    onClassicSidebarMenuIsBeingUnhovered
} from './DashboardState';
import {getMainRows} from './Rows';
import {convertDiscountFilterRowsToExportedJSONColumns} from './conditionsOrFilters/Offer';
import {atomsStore, LastModelAtom, ModelAtom} from "@/tree/atoms";
import {CouponsPlus} from "@/globals";

export class DashboardManager
{
    state = {
        view: CouponsPlus.state.model === 'classic'? 'classic' : 'coupons+', // or 'classic'
        model: 'tree'
    };

    constructor(store)
    {
        var observer = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutationRecord) {
                if (!bodyCanScroll()) {
                    makeBodyUnscrollabble()
                }
            });
        });

        var target = document.body;
        observer.observe(target, { attributes : true, attributeFilter : ['style'] });

        $(window).on('load', () => setTimeout(this.preventWindowScrolling.bind(this), 100))
        this.preventWindowScrolling(true)

        // needs be added before any props are set
        $('#wpbody-content').append('<div id="coupons-plus"></div>');

        $('#adminmenuwrap').on('mouseenter', onClassicSidebarMenuIsBeingHovered)
                           .on('mouseleave', onClassicSidebarMenuIsBeingUnhovered)

        this.originalHeadingHTML = this.getHeadingRoot().html()

        const legacyButton = CouponsPlus?.compatibility?.legacy?.isLegacyInstallation? `<button class="cp-view-switch-to-coupons-plus-rows-legacy flex flex-col leading-5 items-start justify-center ml-6 h-10 px-4 rounded-4 bg-gray-700 text-gray-100">
                        <span class="font-light text-smaller-1 leading-[10px]">${__('Edit with',window.CouponsPlus.textDomain)}</span>
                        <span class="leading-4">Coupons+ (legacy)</span>
                </button>` : ''

        this.getHeadingRoot().html(`
            <div class="cp-woo-original-heading flex items-center">
                ${this.originalHeadingHTML}
                <button class="cp-view-switch-to-coupons-plus flex flex-col leading-5 items-start justify-center ml-6 h-10 px-4 rounded-4 bg-blue-normal text-gray-100">
                        <span class="font-light text-smaller-1 leading-[10px]">${__('Edit with',window.CouponsPlus.textDomain)}</span>
                        <span class="leading-4">Coupons+</span>
                </button>
                ${legacyButton}
            </div>
        `)
        this.store = store;
        this.couponsPlusElement = $('#coupons-plus');

        $(window).on('load', this.onLoad.bind(this));

        $('form#post').append(`
                                <input type="hidden" id="coupons-plus-rows" name="couponsplus_rows" value=""/>
                                <input type="hidden" id="coupons-plus-preconditions-column" name="couponsplus_preconditions" value=""/>
                                <input type="hidden" id="coupons-plus-coupon-auto-apply-is-enabled" name="couponsplus_coupon_auto_apply_is_enabled" value="${CouponsPlus.options.coupon_auto_apply_is_enabled? 'yes' : 'no'}"/>
                                <input type="hidden" id="coupons-plus-dashboard-nonce" name="couponsplus_dashboard_nonce" value="${CouponsPlus.security.nonces.dashboard}"/>
                            `);

        // Subscribe to ModelAtom changes
        atomsStore.sub(ModelAtom, () => {
            const modelValue = atomsStore.get(ModelAtom);
            if (modelValue === 'classic') {
                this.changeState({ view: 'classic' });
            } else if (modelValue === 'tree' || modelValue === 'rows') {
                this.changeState({ view: 'coupons+', model: modelValue });
            }
        });
    }

    getHeadingRoot()
    {
        return $('.woocommerce-layout__header-heading')
    }

    getOriginalHeadingContentElement()
    {
        return this.getHeadingRoot().find('.cp-woo-original-heading')
    }

    getCouponsPlusHeadingContentElement()
    {
        return this.getHeadingRoot().find('.cp-heading')
    }

    preventWindowScrolling(preventIt)
    {
        makeBodyUnscrollabble()
        /*$('body').css({
            height: preventIt? '100vh' : 'auto',
            'max-height': preventIt? '100vh' : 'auto',
            overflow: preventIt? 'hidden' : 'auto',
        })*/
    }
    onLoad() 
    {
        this.registerEvents();
        this.state.view !== "classic" && this.switchToCouponsPlus();
    }

    changeState(data) 
    {
        this.state = merge(this.state, data);

        this.onUpdate();
    }

    registerEvents() 
    {
        $('#coupons-plus-admin').on('click', 'button.cp-view-switch-to-classic', this.changeState.bind(this, {
            view: 'classic'
        })).on('click', 'button.cp-view-switch-to-coupons-plus', this.changeState.bind(this, {
            view: 'coupons+',
            model: 'tree'
        })).on('click', 'button.cp-view-switch-to-coupons-plus-rows-legacy', this.changeState.bind(this, {
            view: 'coupons+',
            model: 'rows'
        })).on('click', 'button.cp-save', this.onSave.bind(this))
           .on('change', 'input#cp-coupon-code-mirror', this.updateCodeInputValue.bind(this, {fieldToUpdate: 'classic'}))
           .on('click', 'button.cp-export', this.outputExportDev.bind(this))
        $('input#publish').on('click', this.updateModelInputField.bind(this))
    }

    onSave()
    {
        this.updateRowsInputField();
        $('input#publish').trigger('click');
    }

    updateRowsInputField()
    {
        const state = this.store.getState()
        const mainRows = getMainRows(state.rows)
        const convertedRows = convertDiscountFilterRowsToExportedJSONColumns(mainRows)

        console.log('convertedRows', convertedRows)

        $('input#coupons-plus-rows').val(
            JSON.stringify({...state, rows: convertedRows})
        )

        this.updateModelInputField()
    }
    updateModelInputField() {
        const model = this.state.view === 'classic' ? 'classic' : atomsStore.get(ModelAtom);
        $('form#post').append(`
                                <input type="hidden" id="coupons-plus-model" name="couponsplus_model" value="${model}"/>                                <input type="hidden" id="coupons-plus-dashboard-nonce" name="couponsplus_dashboard_nonce" value="${CouponsPlus.security.nonces.dashboard}"/>
                            `);
    }

    onUpdate() 
    {
        switch (this.state.view) {
            case 'classic':
                this.switchToClassic();
                this.preventWindowScrolling(false)
            break;

            case 'coupons+':
                window.scrollTo(0, 0)
                this.preventWindowScrolling(true);
                this.switchToCouponsPlus();
            break;
        }
    }

    switchToCouponsPlus() 
    {
        if (this.state.model === 'tree') {
            atomsStore.set(ModelAtom, 'tree');
        } else {
            atomsStore.set(ModelAtom, 'rows');
        }
        dashboardState.isOpened = true
        makeBodyUnscrollabble()

        this.getOriginalHeadingContentElement().css('display', 'none')
        this.getCouponsPlusHeadingContentElement().css('display', 'flex')
        this.couponsPlusElement.css('display', 'block');

        const heading = this.getHeadingRoot();

        if(!this.getCouponsPlusHeadingContentElement().length) {
            heading.append(`
                <div class="cp-heading flex flex-row items-center self-stretch">
                    <button class="cp-view-switch-to-classic flex flex-row items-center space-x-2 px-5 ml-[calc(var(--large-gap)*-1)] h-full border-r-px border-gray-200">
                        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
                        </svg>
                        <span style="display: none">
                            ${__('Back to Classic',window.CouponsPlus.textDomain)}
                        </span>
                    </button>
                    <div class="flex flex-row relative ml-5 items-center space-x-1 bg-gray-200 rounded-3 h-10 px-1">
                        <span class="flex flex-row items-center uppercase text-smaller-1 bg-gray-100 text-gray-450 h-7 px-1 rounded-4">${__('Code',window.CouponsPlus.textDomain)}</span>
                        <input type="text" id="cp-coupon-code-mirror" class="border-none shadow-none bg-transparent"/>
                    </div>
                    <div class="cp-after-code ml-4"></div>
                    <button class="cp-save flex flex-row space-x-2 leading-5 items-center ml-6 h-9 px-3 rounded-3 bg-blue-normal ring-blue-shade-200 text-gray-100 capitalize font-light ring ring-[4px]">
                        <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01" />
                        </svg>
                        <span>${ __('save',window.CouponsPlus.textDomain) }</span>
                    </button>
                </div>
            `)

            if (process.env.NODE_ENV === "development") {
                /**
                 * Only available in the dev builds, 
                 * but it is very likey to be added to production
                 * builds when we introduce import & export functionality
                 */
                this.getCouponsPlusHeadingContentElement().append(`
                    <button class="cp-export">Export</button>
                `)
            }
        }

        this.updateCodeInputValue({fieldToUpdate: 'coupons+'});
    }

    updateCodeInputValue({fieldToUpdate}) 
    {
        switch(fieldToUpdate) {
            case 'coupons+':
                $('#cp-coupon-code-mirror').val($('input[name="post_title"]').val());
            break;
            case 'classic':
                let mirrorCodevalue;

                if (mirrorCodevalue = $('#cp-coupon-code-mirror').val()) {
                    $('input[name="post_title"]').val(mirrorCodevalue)
                }
            break;
        }
    }

    switchToClassic() 
    {
        dashboardState.isOpened = false

        setTimeout(makeBodyscrollabble, 100)
        // needs be called before we replace the html with the classic header
        this.updateCodeInputValue({fieldToUpdate: 'classic'});
        this.updateRowsInputField();

        // Change discount_type to percentage if it's currently "coupons+"
        const discountTypeSelect = $('#discount_type');
        if (discountTypeSelect.val() === 'coupons+') {
            discountTypeSelect.val('percent').trigger('change');
        }

        this.couponsPlusElement.css('display', 'none');
        this.getOriginalHeadingContentElement().css('display', 'flex')
        this.getCouponsPlusHeadingContentElement().css('display', 'none')
        /*
        this.getHeadingRoot().html(`
            ${this.originalHeadingHTML}
            <button class="cp-view-switch-to-coupons-plus flex flex-col leading-5 items-start justify-center ml-6 h-10 px-4 rounded-4 bg-blue-normal text-gray-100">
                        <span class="font-light text-smaller-1 leading-[10px]">${__('Edit with',window.CouponsPlus.textDomain)}</span>
                        <span class="leading-4">Coupons+</span>
                </button>
        `)*/

    }

    outputExportDev() 
    {
        console.log('Exported:');
        console.log(exportRows(this.store));
    }
}