/* eslint no-unused-vars: warn */
/* eslint max-len: ["error", { "code": 160 }] */
/* eslint-disable no-trailing-spaces */
/* eslint-disable no-console */
/* eslint-env es6*/
import PortalVue from '../portal-vue/portal-vue.esm';
import Debugger from './debugger';
let debug = new Debugger("p-sidebar");


let wrapper;
let contentwrapper;
let resizeObserver;
/**
 * Create a new wrapper Around the  
 * @param {String} target Query string to select root element next to which the sidebar will be placed. 
 * Defaults to body
 * @param {String} offsetref Query string to select element that should appear above the sidebar. 
 * Defaults to none
 */
function createPortalTarget(target, offsetref) {
    let initializeWrapperContent = false;
    debug.info("Creating portal target");
    // First check if the sidebar wrapper already exists. 
    // Creating the wrappers over and over again is a recipe for disaster.
    wrapper = document.querySelector("#p-sidebar-wrapper");
    if (!wrapper) {
        initializeWrapperContent = true;
        // Otherwise, create it.
        wrapper = document.createElement("div");
        wrapper.setAttribute("id", "p-sidebar-wrapper");
    }
    // First check if the contentwrapper already exists
    contentwrapper = document.querySelector("#p-sidebar-contentwrapper");
    if (!contentwrapper) {
        initializeWrapperContent = true;
        // Otherwise, create it.
        contentwrapper = document.createElement("div");
        contentwrapper.setAttribute("id", "p-sidebar-contentwrapper");
        wrapper.appendChild(contentwrapper);
    }

    if (initializeWrapperContent) {
        // Find containing target (otherwise use body)
        let targetEl = document.querySelector(target);
        if (!targetEl || targetEl.nodeType == "HTML") {
            targetEl = document.querySelector("body");
        }
        console.info(`Targeting '${target}' to `, targetEl);
        
        // Move all target content parts to content wrapper....
        while (targetEl.childNodes.length > 0) {
            contentwrapper.appendChild(targetEl.childNodes[0]);
        }
        // Add sidebar wrapper to target Element
        targetEl.appendChild(wrapper);
    }
    // The actual target is created in a reposition call
    rePosition(false);
    // The 
    setOffset(offsetref);
}

/**
 * Position a (new) sidebar element on the left or right 
 * @param {Boolean} right Set to true to put the sidebar on the right
 */
function rePosition(right) {
    // Place the portal target on the right place in the DOM.
    // Find or create the portal target.
    let el = document.querySelector(`#p-sidebar-mount`);
    if (!el) {
        el = document.createElement("div");
        el.setAttribute("id", `p-sidebar-mount`);

        // Initialize a resizeObser
        resizeObserver = new ResizeObserver(() => {
            let wx = 0 - el.getBoundingClientRect().width;
            wx += (wx != 0) ? "px" : "";
            el.style.setProperty("--p-sidebar-hideoffset", wx);
        });
        resizeObserver.observe(el);

    }
    if (right) {
        wrapper.insertBefore(el, contentwrapper.nextSibling);
    } else {
        wrapper.insertBefore(el, contentwrapper);
    }
}

/**
 * Set the proper offset from the top on the sidebar related to the reference element 
 * @param {String} reference Reference target for setting view height
 */
function setOffset(reference) {
    const ref = reference ? document.querySelector(reference) : null;
    if (ref) {
        let offsetTop = (ref ? ref.offsetTop : 0);
        offsetTop += (offsetTop != 0) ? "px" : "";
        const el = document.querySelector(`#p-sidebar-mount`);
        if (el) {
            el.style.height = `calc( 100vh - ${offsetTop})`;
            el.style.marginTop = offsetTop;
        }
    }
}

export default {
    install(Vue /* ,options */) {
        Vue.use(PortalVue);
        /*  Create the portal target on initialization.
            Defaults to body. Offset and final position set through sidebar parameter.
        */
        if (document.readyState === 'ready' || document.readyState === 'complete') {
            debug.info("Page already loaded");
            createPortalTarget();
        } else {
            window.addEventListener("load", () => {
                debug.info("Page not yet loaded");
                createPortalTarget();
            });
        }

        Vue.component('p-easeinout', {
            template: `
            <transition name="p-easeinout"
                ><slot></slot>
            </transition>`
        });

        Vue.component('p-sidebar', {
        props: {
            value: {
                type: Boolean,
                'default': true,
            },
            right: {
                type: Boolean,
                'default': false,
            },
            shadow: {
                type: Boolean,
                'default': false,
            },
            target: {
                type: String,
                'default': 'body',
            },
            offsetRef: {
                type: String,
                'default': '',
            }
        },
        data() {
            return {
                wrapper: null,
                contentwrapper: null,
                resizeobserver: null,
            };
        },
        computed: {
        },
        methods: {
        },
        watch: {
            right(newVal) {
                rePosition(newVal);
            },
            offsetRef(reference) {
                setOffset(reference, this.$refs.portal);
            }
        },
        mounted() {
            debug.info("OffsetRef", this.offsetRef);
            setOffset(this.offsetRef);
            debug.info("Right", this.right);
            rePosition(this.right);
        },
        template: `
        <div
        ><mounting-portal ref='portal'
            mount-to="#p-sidebar-mount"
            class="(right?'p-sidebar-right ':'')"
            append
            transition="p-easeinout"
            ><div ref='container' v-if="value"
                    :class="'p-sidebar ' + (right?'p-sidebar-right ':'') + (shadow?'p-sidebar-shadow ':'')"
                ><slot></slot></div
            ></mounting-portal>
        </div>
        `,
        });
    },
};