import MathUtil from "../../util/MathUtil";
import StringUtil from "../../util/StringUtil";
import baseTool from '../../util/baseTool';
import {dialogTpl, overlayTpl, footerTpl} from "./modalTpl";
import Dragable from "../../util/Dragable";
import MouseWheel from '../../util/MouseWheel';
import Tooltips from '../toast/tooltips';
const Modal = (($) => {
    const ESCAPE_KEYCODE = 27;
    const WIN_MODAL_CLOSE = 'winModalClose'; 
    const DefaultConfig = {
        node: "body",    
        title: "提示",
        content: "内容",
        iframeContent: "",  
        className: "",
        type: "normal",  
        width: 420,      
        height: "auto",    
        minWidth: 1100,
        minHeight: 600,
        maxWidth: null,
        maxHeight: null,
        titleBarheight: 50,  
        footerHeight: 66,    
        zIndex: null,
        initOpen: true,
        moveOpacity: 0.8,
        movePadding: 50,
        footer: {
            show: false,
            suctionBottom: false,    
            okLabel: "确定",
            cancelLabel: "取消",
            align: "center"
        },
        stopBubble: true,    
        draggable: true,    
        disableScroll: false,    
        showTitleBar: true,
        showCloseBtn: true,
        showOverlay: true, 
        helper: null,
        feedback: null,
        onRequestClose: (event) => {
            return false;
        },
        onReady: null,   
        onDomReady: null, 
        onPreClose: null,
        onClose: null,   
        beforeDispose: null, 
        newModalStyle: false  
    }
    class Modal {
        static ModalType = {
            TYPE_NORMAL: "normal",
            TYPE_FULL_SCREEN: "fullscreen"
        };
        static CloseType = {
            TYPE_CANCEL: 0,
            TYPE_OK: 1
        };
        constructor(config) {
            this.__name = "Modal";
            this._config = this._getConfig(config);
            this._parent = this._config.node || "body";
            this._$dialog = null;
            this._$titleBar = null;
            this._$overlay = $(overlayTpl);
            this._isShown = false;
            this._$ui = null;
            this.drag = null;
            this.mouseWheel = null;
            this.id = MathUtil.getUID();
            this.initUI();
            this.$dialog = this._$dialog;
            const {onReady} = this._config;
            if (onReady) {
                onReady(this._$dialog);
            }
            this._addEvent();
            if (this._config.initOpen) {
                this.open();
            }
        }
        
        _getConfig(config) {
            return $.extend(true, {}, DefaultConfig, config);
        }
        
        initUI() {
            const {footer} = this._config;
            let renderData = {
                title: this._config.title || "",
                content: this._config.content || "",
                className: this._config.className || "",
                newModalStyle: this._config.newModalStyle || "",
            };
            if(this._config.iframeContent){
                let url = this._config.iframeContent,
                    addPart = 'iframeId=' + this.id + '&domain=' + document.domain;
                if(url.match(/\?/)){
                    url = url.replace('?', '?' + addPart + '&');
                }else{
                    url += '?' + addPart;
                }
                renderData.content = `<iframe style="width: 100%; height: 100%;" frameborder="0" src="${url}"></iframe>`;
                footer.show = false;
            }
            let _style = this._getModalStyle();
            let renderText = template.render(dialogTpl, $.extend(renderData, _style));
            new Tooltips({});
            this._$dialog = $(renderText);
            this._$titleBar = this._$dialog.find(".J_titleBar");
            if (this._config.helper == undefined) {
                this._$dialog.find(".J_btnHelper").hide();
            }
            if (this._config.feedback == undefined) {
                this._$dialog.find(".J_btnFeedback").hide();
            }
            if (this._config.showTitleBar == false) {
                this._$titleBar.hide();
            }
            if (this._config.showCloseBtn == false) {
                this._$dialog.find(".J_btnClose").hide();
            }
            this._$dialog.find(".J_title").html(renderData.title);
            if (footer && footer.show) {
                this.renderFooter(footer, renderData.content, _style);
            }
            else {
                this._$dialog.find(".J_content").html(renderData.content);
            }
        }
        
        renderFooter(footer, content, style) {
            if (footer) {
                let alignCls = "";  
                if (footer.align == "right") {
                    alignCls = "cd-right";
                }
                else if (footer.align == "center") {
                    alignCls = "cd-center";
                }
                else if (footer.align == "left") {
                    alignCls = "cd-left";
                }
                let renderData = {
                    btnsClass: alignCls,
                    oklabel: footer.okLabel || DefaultConfig.footer.okLabel,
                    cancellabel: footer.cancelLabel || DefaultConfig.footer.cancelLabel,
                    contentMiddleStyle: style.contentMiddleStyle
                }
                let footerText = template.render(footerTpl, renderData);
                this._$dialog.find(".J_content").html(footerText);
                this._$dialog.find(".J_content-middle").html(content);
            }
        }
        onClickDocument = (event) => {
            event.stopPropagation();
            if (this._isShown) {
                if (this._$dialog) {
                    if (!this._$dialog.is(event.target) && this._$dialog.has(event.target).length === 0) {
                        const {onRequestClose} = this._config;
                        if (onRequestClose) {
                            if (onRequestClose(event)) {
                                this.beforeClose();
                            }
                        }
                    }
                }
            }
        }
        onKeyup = (event) => {
            if (event.keyCode == ESCAPE_KEYCODE || event.which == ESCAPE_KEYCODE) {
                const {onRequestClose} = this._config;
                if (onRequestClose) {
                    if (onRequestClose(event)) {
                        this.beforeClose();
                    }
                }
            }
        }
        
        onResize() {
            if (this._$dialog) {
            }
        }
        
        onMessage(event) {
            let response = JSON.parse(event.data);
            if(parseInt(response.id) === this.id){
                switch(response.message){
                    case 'dialogOk':
                        this._config.onClose && this._config.onClose(Modal.CloseType.TYPE_OK, this.id,response);
                        this.close();
                        break;
                    case 'dialogCancel':
                        this._config.onClose && this._config.onClose(Modal.CloseType.TYPE_CANCEL, this.id,response);
                        this.close();
                        break;
                    case 'dialogPreOk':
                        this._config.onPreClose && this._config.onPreClose(Modal.CloseType.TYPE_OK, this.id,response);
                        break;
                    case 'dialogPreCancel':
                        this._config.onPreClose && this._config.onPreClose(Modal.CloseType.TYPE_CANCEL, this.id,response);
                        break;
                }
            }
        }
        
        _addEvent() {
            document.removeEventListener("mouseup", this.onClickDocument);
            document.addEventListener("mouseup", this.onClickDocument);
            document.removeEventListener("keyup", this.onKeyup);
            document.addEventListener("keyup", this.onKeyup);
            if(this._config.iframeContent){
                window.top.addEventListener("message", this.onMessage.bind(this), false);
            }
            if (this._$dialog) {
                if (this._config.stopBubble) {
                    if (this._config.showOverlay == true) {
                        this._$overlay.on("click", (event) => {
                            event.stopPropagation();
                        });
                    }
                }
                if(this._config.disableScroll){
                    this.mouseWheel = new MouseWheel();
                }
                this._$dialog.on("click", ".J_btnClose", (event) => {
                    if (this._config.stopBubble) {
                        event.stopPropagation();
                    }
                    this.beforeClose();
                });
                if (this._config.helper) {
                    this._$dialog.on("click", ".J_btnHelper", (event) => {
                        this.doHelper();
                    });
                }
                if (this._config.feedback) {
                    this._$dialog.on("click", ".J_btnFeedback", (event) => {
                        this.doFeedback();
                    });
                }
                if (this._config.footer && this._config.footer.show) {
                    this._$dialog.on("click", ".J_btnOK", (event) => {
                        this.beforeClose(Modal.CloseType.TYPE_OK);
                    });
                    this._$dialog.on("click", ".J_btnCancel", (event) => {
                        this.beforeClose(Modal.CloseType.TYPE_CANCEL);
                    });
                }
                if (this._config.draggable == true) {
                    const {movePadding, moveOpacity} = this._config;
                    if (this.drag == null) {
                        this.drag = new Dragable({
                            target: this._$dialog[0],
                            handle: this._$titleBar[0],
                            moveOpacity: moveOpacity,
                            containment: this._config.node,
                        });
                    }
                }
            }
        }
        
        _completeUnit(obj) {
            for (let a in obj) {
                let val = obj[a] + '';
                obj[a] = val.match(/\d$/) ? val + 'px' : val;
            }
            return obj;
        }
        
        _getModalStyle() {
            let config = this._config;
            const {type, footer, showTitleBar, footerHeight, titleBarheight} = config;
            let ModalType = Modal.ModalType;
            let returnVal = {
                modalStyle: "",
                contentStyle: "",
                contentMiddleStyle: ""
            };
            if (type == ModalType.TYPE_NORMAL) {
                returnVal.modalStyle = JSON.stringify(this._completeUnit({
                    width: config.width,
                    height: config.height
                }));
            }
            else if (type == ModalType.TYPE_FULL_SCREEN) {
                if (!(config.width + '').match(/\d%$/)) {
                    config.width = '80%';
                }
                if (!(config.height + '').match(/\d%$/)) {
                    config.height = '80%';
                }
                let cssSet = {
                    width: config.width,
                    height: config.height,
                    'min-width': config.minWidth,
                    'min-height': config.minHeight
                };
                if(config.maxWidth){
                    cssSet['max-width'] = config.maxWidth;
                }
                if(config.maxHeight){
                    cssSet['max-height'] = config.maxHeight;
                }
                returnVal.modalStyle = JSON.stringify(this._completeUnit(cssSet));
                if (showTitleBar) {
                    returnVal.contentStyle = "height:calc(100% - " + titleBarheight + "px);";
                }
                else {
                    returnVal.contentStyle = "height:100%";
                }
                if (footer && footer.show && footer.suctionBottom) {
                    returnVal.contentMiddleStyle = "height:calc(100% - " + footerHeight + "px);";
                }
            }
            if (returnVal.modalStyle) {
                returnVal.modalStyle = returnVal.modalStyle.replace(/["{}]/g, '').replace(/,/g, ';');
            }
            return returnVal;
        }
        
        doHelper() {
            let helper = this._config.helper;
            if (helper) {
                if (StringUtil.isObject(helper)) {
                    if (helper.url) {
                        let target = helper.target;
                        if (target == undefined) {
                            target = "_self";
                        }
                        window.open(helper.url, target);
                    }
                }
                else if (StringUtil.isFunction(helper)) {
                    helper();
                }
            }
        }
        
        doFeedback() {
            let feedback = this._config.feedback;
            if (feedback) {
                if (StringUtil.isObject(feedback)) {
                    if (feedback.url) {
                        let target = feedback.target;
                        if (target == undefined) {
                            target = "_self";
                        }
                        window.open(feedback.url, target);
                    }
                }
                else if (StringUtil.isFunction(feedback)) {
                    feedback();
                }
            }
        }
        
        getDialog() {
            return this._$dialog;
        }
        
        open() {
            if (this._isShown == false) {
                this._isShown = true;
                if(this.mouseWheel){
                    this.mouseWheel.disableScroll();
                }
                if (this._$dialog && this._parent) {
                    if (this._config.node === 'body') {
                        this._$overlay.append(this._$dialog);
                        if(this._config.iframeContent && this._parent === 'body'){
                            this._parent = window.top.document.body;
                        }
                        this._$overlay.appendTo(this._parent);
                        this._$ui = this._$overlay;
                        if (this._config.showOverlay !== true) {
                            this._$ui.css({'background-color': 'transparent', 'pointer-events': 'none'});
                            this._$dialog.css('pointer-events', 'auto');
                        }
                    } else {
                        this._$dialog.appendTo(this._parent);
                        this._$ui = this._$dialog;
                    }
                    
                    let zIndex = parseInt(this._config.zIndex);
                    if (isNaN(zIndex) == false) {
                        this._$ui.css("z-index", zIndex);
                    }
                    else {
                        this._$ui.css('z-index', baseTool.getModalZIndex());
                    }
                    const {onDomReady} = this._config;
                    if (onDomReady) {
                        onDomReady(this._$dialog);
                    }
                }
            }
        }
        
        beforeClose(flag = 0) {
            const {onClose, onPreClose} = this._config;
            if (onPreClose != null) {
                onPreClose(flag, this.id);
            }
            else {
                if (onClose != null) {
                    onClose(flag, this.id);
                }
                this.close();
            }
        }
        
        close() {
            $(window).trigger(WIN_MODAL_CLOSE, this);
            if(this.mouseWheel){
                this.mouseWheel.enableScroll();
            }
            if (this._$ui) {
                this._$ui.remove();
            }
            this._isShown = false;
            this.dispose();
        }
        
        dispose() {
            if (this._config) {
                const {beforeDispose} = this._config;
                if (beforeDispose) {
                    beforeDispose();
                }
            }
            document.removeEventListener("mouseup", this.onClickDocument);
            document.removeEventListener("keyup", this.onKeyup);
            window.removeEventListener("message", this.onMessage);
            if (this._$dialog) {
                this._$dialog.off();
            }
            if (this._$overlay) {
                this._$overlay.off();
            }
            if (this._$titleBar) {
                this._$titleBar.off();
            }
            if (this.drag) {
                this.drag.dispose();
            }
            if(this.mouseWheel){
                this.mouseWheel.dispose();
            }
            this.mouseWheel = null;
            this.drag = null;
            this._$titleBar = null;
            this._$ui = null;
            this._config = null;
            this._parent = null;
            this._$dialog = null;
            this._$overlay = null;
        }
    }
    return Modal;
})($);
export default Modal;