import EventBus from "../util/EventBus";
import EventTypes from "../util/EventTypes";

var BrickPreviewer = function () {
    return {
        iframe: null,
        previewerComp: null,
        focused: null,
        focusedBar: null,
        targetBrick: null,
        targetTopPosition: null,
        reloadIframeInterval: null,
        mouseoutTimeoutHandle: null,
        init: function (previewerComp, iframe) {
            this.previewerComp = previewerComp;
            this.previewerComp.triggerDelayMouseoutTimeout = this.delayMouseoutTimeout;
            this.iframe = iframe;

            console.log('initializing brick preview');

            var self = this;

            var mode = 'default'; // add possibility to toggle default/all
            var selectors = {
                default: '[data-brick-id]:not(.section):not(.row):not(.col)',
                all: '[data-brick-id]',
            }

            this.iframe.contentWindow.addEventListener('DOMContentLoaded', function () {
                // TODO: not fuckin rendering till visible on screen, so no height !
                var doc = self.iframe.contentWindow.document;

                var iframeScrollHeight = Math.max.apply(null, [
                    doc.querySelector('html').scrollHeight,
                    doc.querySelector('body').scrollHeight
                ]);
                self.iframe.style.height = iframeScrollHeight + 'px';
                console.log('iframeScrollHeight', iframeScrollHeight);
            })

            this.iframe.addEventListener('load', function (e) {
                var selector = selectors[mode];
                var doc = self.iframe.contentWindow.document;
                doc.querySelectorAll(selector).forEach(function (el) {
                    el.addEventListener('mouseenter', self.brickPreviewMouseEnter.bind(self));
                    el.addEventListener('mouseleave', self.brickPreviewMouseLeave.bind(self));
                });
                console.log('should i scroll');
                console.log(self);

                if (self.targetTopPosition) {
                    doc.querySelector('html').scrollTo({
                        top: self.targetTopPosition,
                        behavior: 'smooth'
                    });
                }
            });
            // this.iframe.addEventListener('mouseleave', function (e) {
            //     if (e.target !== this.iframe) {
            //         return;
            //     }
            //     this.focused = null;
            //     this.focusedBar = null;
            //     this.refreshInterface();
            // }.bind(this));
        },
        reloadIframe: function () {
            // TODO: retrieve scroll height before reload and
            if (typeof this.targetBrick != 'undefined'
                && this.iframe.contentDocument
                && this.iframe.contentDocument.querySelector('html')
                && this.iframe.contentDocument.querySelector('body')
            ) {
                this.targetTopPosition = Math.max(
                    this.iframe.contentDocument.querySelector('html').scrollTop,
                    this.iframe.contentDocument.querySelector('body').scrollTop
                );
            }

            if (this.iframe.offsetParent === null) {
                // iframe is hidden, use interval to reload when iframe is visible again
                var self = this;
                if (this.reloadIframeInterval) {
                    clearInterval(this.reloadIframeInterval);
                }
                this.reloadIframeInterval = setInterval(function () {
                    if (self.iframe.offsetParent === null) {
                        return;
                    }
                    clearInterval(self.reloadIframeInterval);
                    self.iframe.src = '' + self.iframe.src;
                }, 200);
            } else {
                // simply reassign src to force reload
                this.iframe.src = '' + this.iframe.src;
            }
        },
        brickPreviewMouseEnter (e) {
            if (e.target.classList.contains('.brick-edit-bar') || e.target.closest('.brick-edit-bar') !== null) {
                this.focusedBar = e.target;
                return;
            }
            this.focused = e.target;

            e.stopPropagation();
            this.refreshInterface();
        },
        brickPreviewMouseLeave(e) {
            if (this.focusedBar !== null) {
                return;
            }

            if (e.target.classList.contains('.brick-edit-bar') || e.target.closest('.brick-edit-bar') !== null) {
                this.delayMouseoutTimeout();

                return;
            }

            this.delayMouseoutTimeout();
            e.stopPropagation();
            this.refreshInterface();
        },
        delayMouseoutTimeout() {
            if (this.mouseoutTimeoutHandle) {
                clearTimeout(this.mouseoutTimeoutHandle);
            }
            this.mouseoutTimeoutHandle = setTimeout(() => {
                this.focusedBar = null;
                this.focused = null;

                this.previewerComp.updatePreviewBounds({
                    bounds: null,
                    brick: null,
                });
            }, 1000);
        },
        refreshInterface: function () {
            var doc = this.iframe.contentWindow.document;

            var iframeScrollTop = Math.max.apply(null, [
                doc.querySelector('html').scrollTop,
                doc.querySelector('body').scrollTop
            ]);
            console.log(
                Math.max.apply(
                    null, [
                        doc.querySelector('html').scrollTop,
                        doc.querySelector('body').scrollTop
                    ]
                )
            );
            console.log('doc', doc);
            console.log('iframeScrollTop', iframeScrollTop);
            // var bar = this.resolveActionBar();
            var outline = this.resolveOutline();

            if (this.focused === null) {
                // bar.style.display = 'none';
                outline.style.display = 'none';
                return;
            } else {
                // bar.style.display = 'block';
                outline.style.display = 'block';
            }

            var relatedBrickId = this.focused.attributes['data-brick-id'].value;
            var relatedBrick = document.querySelector('.brick-builder .root-brick .brick[data-brick-id="' + relatedBrickId + '"]');
            this.builderBrickReference = relatedBrick;

            var bodyRect = doc.body.getBoundingClientRect();
            var iframeRect = this.iframe.getBoundingClientRect();
            var focusedRect = this.focused.getBoundingClientRect();
            var offset = {
                top: focusedRect.top - bodyRect.top,
                left: focusedRect.left - bodyRect.left,
            };
            // var barStyle = bar.style;
            // barStyle.top = offset.top - 40 + 'px';
            // barStyle.left = offset.left - 5/* border width */ + 'px';

            var outlineBounds = {
                top: offset.top - 5,
                left: offset.left - 5,
                height: focusedRect.height + 10,
                width: focusedRect.width + 10,
            };

            var outlineStyle = outline.style;
            outlineStyle.top = outlineBounds.top + 'px';
            outlineStyle.left = outlineBounds.left + 'px';
            outlineStyle.height = outlineBounds.height + 'px';
            outlineStyle.width = outlineBounds.width + 'px';

            var outsideIframeBrickBounds = {
                top: Math.max(outlineBounds.top + iframeRect.y - iframeScrollTop, iframeRect.y),
                left: outlineBounds.left + iframeRect.x,
                height: outlineBounds.height,
                width: outlineBounds.width,
            };

            this.previewerComp.updatePreviewBounds({
                bounds: outsideIframeBrickBounds,
                brick: this.previewerComp.builder.getBrick(relatedBrickId),
            });
        },
        // resolveActionBar: function () {
        //     var doc = this.iframe.contentWindow.document;
        //
        //     var existant = doc.querySelector('.brick-edit-bar');
        //     if (existant !== null) {
        //         return existant;
        //     }
        //
        //     var bar = doc.createElement('div');
        //     bar.style.position = 'absolute';
        //     bar.style.zIndex = '1000';
        //     bar.style.paddingBottom = '20px';
        //     bar.classList.add('brick-edit-bar');
        //     bar.addEventListener('mouseenter', function (e) {
        //         this.focusedBar = e.target;
        //     }.bind(this));
        //     bar.addEventListener('mouseleave', function (e) {
        //         this.focusedBar = e.target;
        //     }.bind(this));
        //
        //     this.createActionBarBtns(doc, bar)
        //
        //     doc.body.appendChild(bar);
        //
        //     return bar;
        // },
        // createActionBarBtns: function (doc, bar) {
        //     var btns = [
        //         {
        //             label: '👁 Identifier',
        //             cssClasses: 'brick-identify',
        //             callback: (e) => {
        //                 console.log('brick-identify');
        //                 console.log(this);
        //                 window.activateTab(0);
        //                 if (this.builderBrickReference) {
        //                     this.builderBrickReference.classList.add('flash')
        //                     zenscroll.intoView(this.builderBrickReference);
        //                     setTimeout(function () {
        //                         this.builderBrickReference.classList.remove('flash')
        //                     }.bind(this), 1500);
        //                 }
        //             },
        //         },
        //         {
        //             label: '🖉 Modifier',
        //             cssClasses: 'brick-modify',
        //             callback: (e) => {
        //                 if (this.focused === null) {
        //                     return;
        //                 }
        //
        //                 console.log('current brick hovered in click handler');
        //                 console.log(this.focused);
        //
        //                 var brickId = this.focused.attributes['data-brick-id'].value;
        //                 // var editBrickSelector = '.brick-builder .root-brick .btn.brick-edit[data-brick-id="' + brickId + '"]';
        //                 // console.log(editBrickSelector);
        //                 // console.log(brickEditBtnEl);
        //                 // var brickEditBtnEl = document.querySelector(editBrickSelector);
        //                 // if (brickEditBtnEl) {
        //                 //     this.targetBrick = this.focused;
        //                 //     var evt = new MouseEvent('click', {bubbles: true, cancelable: true,});
        //                 //     brickEditBtnEl.dispatchEvent(evt);
        //                 // }
        //                 var brick = this.previewerComp.builder.getBrick(brickId);
        //                 console.log(brick);
        //                 EventBus.emitEvent(EventTypes.BRICK_UPDATE, brick.vueComponent);
        //             },
        //         },
        //     ];
        //     btns.forEach(function (btnConfig, i) {
        //         var btn = doc.createElement('button');
        //         btnConfig.cssClasses.split(' ').forEach(function (currentClass) {
        //             btn.classList.add(currentClass);
        //         });
        //         btn.innerHTML = btnConfig.label;
        //         btn.style.backgroundColor = '#fcba41';
        //         btn.style.color = '#ffffff';
        //         btn.style.border = 'none';
        //         btn.style.padding = '5px 10px';
        //         if (i < btns.length - 1) {
        //             btn.style.borderRight = '3px solid rgba(255,255,255,.4)';
        //         }
        //         btn.addEventListener('click', btnConfig.callback);
        //         bar.appendChild(btn);
        //     });
        // },
        resolveOutline: function () {
            var doc = this.iframe.contentWindow.document;

            var existant = doc.querySelector('.brick-edit-bar-outline');
            if (existant !== null) {
                return existant;
            }

            var outline = doc.createElement('div');

            outline.classList.add('brick-edit-bar-outline');
            outline.style.position = 'absolute';
            outline.style.zIndex = '999';
            outline.style.border = '5px solid rgba(78,115,223,.25)';
            outline.style.background = 'rgba(78,115,223,.25)';
            outline.style.touchAction = 'none';
            outline.style.pointerEvents = 'none';
            outline.style.borderRadius = '5px';

            doc.body.appendChild(outline);

            return outline;
        },
    }
};


export default BrickPreviewer;