/**
 * Created by wangzhen on 2017/10/12.
 * Modified by wangzhen on 2018/3/6
 * 打印控件
 */
//import XLSX from 'xlsx'; // npm install xlsx@^0.11.5
var XLSX = require('styled-xlsx');//npm install styled-xlsx@^0.11.10
var html2canvas = require('./html2canvas');
var jsPDF = require('jspdf');//npm install jspdf@^1.3.5
!function ($) {
    'use strict';
    // SELECT CLASS DEFINITION
    // =========================
    var Print = function (element, option) {
        this._loadLock = false;
        this.init(element, option);
    }

    Print.VERSION = '1.0.0';
    Print.DEFAULTS = {
        id: null,
        blankLabel: "Print",
        type: "img",//img|html|excel|pdf
        downloadName: "",
        images: [],
        startX: 0,//canvas图片绘制起始X坐标
        startY: 0,//canvas图片绘制起始Y坐标
        watermark: "Teld",//水印
        fontStyle: "20px 黑体", //水印字体设置
        rotateAngle: -20 * Math.PI / 180, //水印字体倾斜角度设置
        fontColor: "rgba(255, 0, 0, 0.2)", //水印字体颜色设置
        firstLinePositionX: -20, //canvas第一行文字起始X坐标
        firstLinePositionY: 80, //Y
        SecondLinePositionX: 0, //canvas第二行文字起始X坐标
        SecondLinePositionY: 70,//Y
        htmlId: "",//HTML导出指定HtmlId
        // rowName:[],//excel导出自定义标题行
        // rowData:[],//excel导出数据
        pdfPageGap: [5],
        sheetData: [{
            sheetName: "",
            rowName: [],
            rowData: [],
            merges: [],
            style: {
                cellStyle: {},//"A1":s//s={fill:xxx,font:xxx,numFmt:xxx,alignment:xxx,border:xxx}
                rowStyle: {},//0:s,1:s
                colStyle: {},//0:s,1:s
                multiRowStyle: {}
            },
            enums: []
        }]
    };

    Print.prototype.XLSX = XLSX;
    Print.prototype.html2canvas = html2canvas;
    //Print.prototype.jsPDF = jsPDF;

    Print.prototype.getDefaults = function () {
        return Print.DEFAULTS;
    };
    Print.prototype.refreshState = function (isBusy) {
        if (isBusy) {
            var html = '<li class="selectlist select-highlighted teld-select-loading"><i class="teld-select-loading-orl"></i><p class="teld-select-loading-txt">读取中 ...</p></li>';
            $('#' + this.printMenuId).append(html);
        } else {
            $('#' + this.printMenuId).find("li.teld-select-loading:first").remove();
        }
    };
    // 初始化打印控件
    Print.prototype.init = function (element, option) {
        var that = this;
        if (option) {
            this.options = $.extend({}, this.getDefaults(), option);
            this.options.type = this.options.type ? this.options.type.toLowerCase() : "";
            this.options.downloadName = this.options.downloadName ? this.options.downloadName :
                (this.options.id + "-" + new Date().getTime());
            this._loadLock = this.options.loadLock;
        }
        if (element) {
            this.$element = $(element);
        }
        if (this._loadLock) {
            return;
        }
        if (!this.options.id) {
            alert("请定义打印控件id");
            return;
        }
        this.printId = this.options.id;
        this.printMenuId = this.printId + "Menu";
        this.blankLabel = this.options.blankLabel;

        this.$template = $(this.getTemplate()).clone();
        if (this.options.type != "excel") {
            this.$element.empty();
            this.$template.appendTo(this.$element);
        }

        if (this.options.type == "img") {
            this.drawImg();
        } else if (this.options.type == "html") {
            // if(window.html2canvas){
            //     this.html2canvas = window.html2canvas;
            // }else{
            //     console.log("no html2canvas");
            //     var $scriptTem = $("<script src='./src/js/html2canvas.js'></script>").clone();
            //     $scriptTem.appendTo(this.$element);
            //     this.html2canvas = window.html2canvas;
            if (!this.html2canvas) {
                throw new Error('打印控件print依赖于html2canvas');
                return;
            }
            // }
        } else if (this.options.type == "excel") {
            if (!this.XLSX) {
                throw new Error('打印控件print依赖于XLSX');
                return;
            }
        }
        this.initEvents();


        this.isBusy = false;
        if (this.disabled) {
            this.$element.find("#" + this.printId).prop("disabled", true);
        }
        //this.refreshState(true);
    };
    Print.prototype.loadLock = function (flg) {
        if (typeof flg === "undefined") {
            return this._loadLock;
        }
        this.options.loadLock = flg;
        if (this._loadLock && this._loadLock != flg) {
            this._loadLock = flg;
            //解锁状态
            this.init()
        } else {
            this._loadLock = flg;
        }
    }

    Print.prototype.getTemplate = function () {
        var watermarkHtml = "";
        if (this.options.type == "img") {
            watermarkHtml =
                '<canvas id="' + this.printId + '-watermark" width="160px"  height="100px" style="display:none"></canvas>' +
                '<canvas id="' + this.printId + '-repeat-watermark" style="display:none;"></canvas>';
        }
        var template = '<button id="' + this.printId + '-print" type="button" class="btn btn-default" data-action="print' + this.options.type + '">' +
            this.blankLabel + '</button>' + watermarkHtml;
        return template;
    };

    Print.prototype.drawImg = function () {
        var imgs = [];
        this.loadImg(imgs, 0, this.options.images.length)
    };
    Print.prototype.loadImg = function (imgs, n, length) {
        var self = this;
        if (n < length) {
            var img = new Image();
            img.src = self.options.images[n].src;
            img.onload = function () {
                var img1 = {
                    docWidth: img.width,
                    docHeight: img.height,
                    gapX: self.options.images[n].gapX ? self.options.images[n].gapX : 0,
                    gapY: self.options.images[n].gapY ? self.options.images[n].gapY : 0,
                    img: img
                };
                imgs.push(img1);
                self.loadImg(imgs, n + 1, length)
            }
        } else {
            self.draw(self.options.startX, self.options.startY, imgs);
        }
    };
    Print.prototype.drawSingleWatermark = function () {
        var self = this;
        var cw = document.getElementById(this.printId + "-watermark");
        if (cw) {
            var ctx = cw.getContext("2d");
            //清除小画布
            ctx.clearRect(0, 0, 160, 100);
            ctx.font = self.options.fontStyle;
            //文字倾斜角度
            ctx.rotate(self.options.rotateAngle);
            ctx.fillStyle = self.options.fontColor;
            //第一行文字
            ctx.fillText(self.options.watermark, self.options.firstLinePositionX, self.options.firstLinePositionY);
            //第二行文字
            //ctx.fillText(window.watermark.mobile, self.options.SecondLinePositionX, self.options.SecondLinePositionY);
            //坐标系还原
            ctx.rotate(-self.options.rotateAngle);
        }
        return cw;
    };
    Print.prototype.draw = function (startX, startY, imgs) {
        if (imgs && imgs.length > 0) {

            var crw = document.getElementById(this.printId + '-repeat-watermark');
            if (crw) {
                crw.height = 0;
                for (var i = 0; i < imgs.length; i++) {
                    crw.width = crw.width > imgs[i].docWidth ? crw.width : imgs[i].docWidth;
                    crw.height += imgs[i].docHeight + imgs[i].gapY;
                }
                var ctxr = crw.getContext("2d");
                //清除整个画布
                ctxr.clearRect(startX, startY, crw.width, crw.height);
                var startYnew = startY;
                for (var i = 0; i < imgs.length; i++) {
                    //console.log(imgs[i].gapX + "::" + imgs[i].gapY);
                    if (imgs[i].img) ctxr.drawImage(imgs[i].img, startX + imgs[i].gapX, startYnew + imgs[i].gapY);
                    startYnew += imgs[i].docHeight;
                }
                //平铺--重复小块的canvas
                var cw = this.drawSingleWatermark();
                var pat = ctxr.createPattern(cw, "repeat");
                ctxr.fillStyle = pat;
                ctxr.fillRect(startX, startY, crw.width, crw.height);
            }
        }
    };

    Print.prototype.initEvents = function () {
        var self = this;
        $("#" + self.printId + "-print").on("click", function () {
            var action = $(this).data("action");
            console.log(action);
            switch (action) {
                case "printimg":
                    var canvas = document.getElementById(self.printId + "-repeat-watermark");
                    if (canvas) {
                        self.DownLoadCanvas(canvas);
                    }
                    break;
                case "printhtml":
                    self.PrintHtml();
                    break;
                case "printpdf":
                    self.ExportPDF();
                    break;
                case "printexcel":
                    if (self.XLSX) {
                        self.ExportExcel();
                    }
                    break;
            }
        });
    };

    Print.prototype.DownLoadCanvas = function (canvas) {
        var self = this;
        if (canvas.msToBlob) {//IE9+浏览器
            var blob = canvas.msToBlob();
            window.navigator.msSaveBlob(blob, self.options.downloadName + ".png");
        } else {
            var dom = document.createElement("a");
            dom.href = canvas.toDataURL();
            dom.download = self.options.downloadName + ".png";
            dom.click();
        }
    };

    Print.prototype.PrintHtml = function () {
        var self = this;
        if (self.options.htmlId) {
            self.html2canvas($("#" + self.options.htmlId), {
                height: $("#" + self.options.htmlId).outerHeight() + 57,
                onrendered: function (canvas) {
                    if (canvas) {
                        self.DownLoadCanvas(canvas);
                    }
                }
            });
        }
    };

    Print.prototype.ExportExcel = function () {
        var self = this;
        var sheetData = self.options.sheetData;
        if (sheetData && sheetData.length > 0) {
            var tmpdataArr = [];
            for (var i = 0; i < sheetData.length; i++) {
                if (sheetData[i].rowData || sheetData[i].rowName) {
                    var rowDataNew = self.enumData(sheetData[i].rowData, sheetData[i].enums);
                    var keyMap = sheetData[i].rowName;
                    var tmpObj = { sheetName: sheetData[i].sheetName ? sheetData[i].sheetName : ("Sheet" + (i + 1)), tmpdata: [] };
                    var tmpdata = [];//用来保存转换好的json
                    var rowIndex = 1;
                    if (!sheetData[i].rowName) {
                        keyMap = [];
                        for (var key in rowDataNew[0]) {
                            var keyObj = {};
                            keyObj[key] = key;
                            keyMap.push(keyObj);
                        }
                    }
                    keyMap.map((k, j) => {
                        var position = (j > 25 ? self.getCharCol(j) : String.fromCharCode(65 + j)) + rowIndex;
                        tmpdata[position] = {
                            v: Object.values(k)[0],
                            s: sheetData[i] ? self.getStyle(sheetData[i].style, position, rowIndex - 1) : null
                        };
                    }
                    );
                    rowIndex++;
                    if (rowDataNew) {
                        rowDataNew.map(
                            (v, m) =>
                                keyMap.map((k, j) =>
                                    Object.assign({}, {
                                        v: v[Object.keys(k)[0]],
                                        position: (j > 25 ? self.getCharCol(j) : String.fromCharCode(65 + j)) + (m + rowIndex)
                                    })
                                )
                        ).reduce(
                            (prev, next) =>
                                prev.concat(next)
                            ).forEach(
                            (v, n) => {
                                tmpdata[v.position] = {
                                    v: v.v == null ? "" : v.v,
                                    s: sheetData[i] ? self.getStyle(sheetData[i].style, v.position) : null
                                }
                            }
                            );
                    }

                    tmpObj.tmpdata = tmpdata;
                    tmpObj.merges = sheetData[i].merges;
                    tmpdataArr.push(tmpObj);
                }
            }
            var tmpWB = {
                SheetNames: [], //保存的表标题
                Sheets: {}
            };
            for (var j = 0; j < tmpdataArr.length; j++) {
                var outputPos = Object.keys(tmpdataArr[j].tmpdata);
                tmpWB.SheetNames.push(tmpdataArr[j].sheetName);
                tmpWB.Sheets[tmpdataArr[j].sheetName] = Object.assign({},
                    tmpdataArr[j].tmpdata, //内容
                    {
                        '!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] //设置填充区域
                    });
                if (tmpdataArr[j].merges && tmpdataArr[j].merges.length > 0) {
                    var merges = [];
                    for (var k = 0; k < tmpdataArr[j].merges.length; k++) {
                        var span = tmpdataArr[j].merges[k];
                        if (span.indexOf(":") > 0 && span.indexOf(":") > 0) {
                            var merge = self.XLSX.utils.decode_range(span);
                            //合并单元格时设置第一个单元格居中
                            tmpWB.Sheets[tmpdataArr[j].sheetName][span.split(':')[0]]["s"] =
                                $.extend({},
                                    { alignment: { vertical: "center", horizontal: "center" } },
                                    tmpWB.Sheets[tmpdataArr[j].sheetName][span.split(':')[0]]["s"]
                                );
                            merges.push(merge);
                        }
                    }
                    tmpWB.Sheets[tmpdataArr[j].sheetName]["!merges"] = merges;//设置合并单元格
                }
                // tmpWB.Sheets[tmpdataArr[j].sheetName]["!merges"] = [{//合并第一行数据[B1,C1,D1,E1]
                //     s: {//s为开始
                //         c: 1,//开始列
                //         r: 0//开始取值范围
                //     },
                //     e: {//e结束
                //         c: 4,//结束列
                //         r: 0//结束范围
                //     }
                // }];
            }

            self.tmpDown = new Blob([self.s2ab(self.XLSX.write(tmpWB,
                {
                    bookType: (self.options.type == "excel" ? 'xlsx' : self.options.type),
                    bookSST: false,
                    compression: true,
                    type: 'binary',
                    cellStyles: true
                }//这里的数据是用来定义导出的格式类型
            ))], {
                    type: ""
                }); //创建二进制对象写入转换好的字节流
            debugger;
            if ('msSaveOrOpenBlob' in navigator) {
                // Microsoft Edge and Microsoft Internet Explorer 10-11
                window.navigator.msSaveOrOpenBlob(self.tmpDown, self.options.downloadName + ".xlsx");
            } else {
                var href = URL.createObjectURL(self.tmpDown); //创建对象超链接
                var dom = document.createElement("a");
                dom.href = href;//绑定a标签
                dom.download = self.options.downloadName + ".xlsx";
                dom.click();//模拟点击实现下载
                setTimeout(function () { //延时释放
                    URL.revokeObjectURL(self.tmpDown); //用URL.revokeObjectURL()来释放这个object URL
                }, 100);
            }
        }
    };

    Print.prototype.ExportPDF = function () {
        var self = this;
        if (self.options.htmlId) {
            self.html2canvas($("#" + self.options.htmlId), {
                height: $("#" + self.options.htmlId).outerHeight(),
                onrendered: function (canvas) {
                    if (canvas) {
                        var dpi = self.js_getDPI();
                        if (dpi && dpi[0] == 96) {
                            self.exportPdf96(canvas);
                        } else {
                            self.exportPdf72(canvas);
                        }
                    }
                },
                background: "#fff", //这里给生成的图片默认背景，不然的话，如果你的html根节点没有设置背景的话，会用黑色填充。
                // allowTaint: true  //避免一些不识别的图片干扰，默认为false，遇到不识别的图片干扰则会停止处理html2canvas
            });
        }
    };

    Print.prototype.enumData = function (rowData, enums) {
        var self = this;
        if (enums && enums.length) {
            var rowDataNew = rowData.concat();
            rowDataNew.map((k, j) => {
                enums.map((m, n) => {
                    if (k[m["key"]] || k[m["key"]] == 0) {
                        k[m["key"]] = m["value"][k[m["key"]]] != undefined ? m["value"][k[m["key"]]] : k[m["key"]];
                    }
                })
            });
            return rowDataNew;
        }
        return rowData;
    };
    // 获取单元格样式
    Print.prototype.getStyle = function (style, position, row) {
        var cssStyle = null;
        if (!row && position) {
            row = this.XLSX.utils.split_cell(position)[1] - 1;
        }
        if (style) {
            if (style.multiRowStyle && style.multiRowStyle.key) {
                if (style.multiRowStyle.key.indexOf(":") > -1) {
                    var rowArr = style.multiRowStyle.key.split(':');
                    if (parseInt(rowArr[0]) <= row && row <= parseInt(rowArr[1])) {
                        cssStyle = $.extend({}, cssStyle, style.multiRowStyle.value);
                    }
                }
            }
            if (style.rowStyle && style.rowStyle.hasOwnProperty(row)) {
                cssStyle = $.extend({}, cssStyle, style.rowStyle[row]);
            }
            if (style.cellStyle && style.cellStyle.hasOwnProperty(position)) {
                cssStyle = $.extend({}, cssStyle, style.cellStyle[position]);
            }
        }
        return cssStyle;
    };
    // 字符串转字符流
    Print.prototype.s2ab = function (s) {
        var buf = new ArrayBuffer(s.length);
        var view = new Uint8Array(buf);
        for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
        return buf;
    };
    // 将指定的自然数转换为26进制表示。映射关系：[0-25] -> [A-Z]。
    Print.prototype.getCharCol = function (n) {
        let temCol = '',
            s = '',
            m = 0;
        while (n > 0) {
            m = n % 26 + 1;
            s = String.fromCharCode(m + 64) + s;
            n = (n - m) / 26
        }
        return s;
    };
    // 将指定的字符串转为自然数表示。映射关系：[A-Z] -> [0-25]。
    Print.prototype.getNumberCol = function (n) {
        var num = -1;
        if (n.length > 0) {
            n = n.toUpperCase();
            var charArr = n.split('');
            for (var i = 0; i < charArr.length; i++) {
                num = (num + 1) * 26 + (charArr[i].charCodeAt('0') - 65);
            }
        }
        return num;
    };
    // 导出pdf
    Print.prototype.exportPdf72 = function (canvas) {
        var self = this;
        // var imgData = canvas.toDataURL('img/notice/png');
        // var doc = new jsPDF('p', 'px','a3');
        // //第一列 左右边距  第二列上下边距  第三列是图片左右拉伸  第四列 图片上下拉伸
        // doc.addImage(imgData, 'PNG', -9, 0,700,1500);
        // doc.addPage();
        // doc.addImage(imgData, 'PNG', -9, -910,700,1500);
        // doc.save('test.pdf');
        var contentWidth = canvas.width;
        var contentHeight = canvas.height;
        //一页pdf显示html页面生成的canvas高度;
        var pageHeight = contentWidth / 592.28 * 841.89;
        //未生成pdf的html页面高度
        var leftHeight = contentHeight + 6;
        //页面偏移
        var position = 0;
        //a4纸的尺寸[595.28,841.89]，html页面生成的canvas在pdf中图片的宽高
        var imgWidth = 595.28;
        var imgHeight = 595.28 / contentWidth * contentHeight;
        var pageData = canvas.toDataURL('image/png', 1.0);

        var pdf = new jsPDF('', 'pt', 'a4');
        //有两个高度需要区分，一个是html页面的实际高度，和生成pdf的页面高度(841.89)
        //当内容未超过pdf一页显示的范围，无需分页
        if (leftHeight < pageHeight) {
            pdf.addImage(pageData, 'png', 0, 0, imgWidth, imgHeight);
        } else {
            while (leftHeight > 0) {
                //arg3-->距离左边距;arg4-->距离上边距;arg5-->宽度;arg6-->高度
                pdf.addImage(pageData, 'png', 0, position, imgWidth, imgHeight);
                leftHeight -= pageHeight;
                position -= 841.89;
                //避免添加空白页
                if (leftHeight > 0) {

                    pdf.addPage();
                }
            }
        }
        pdf.save(self.options.downloadName + '.pdf');
    };
    // 导出pdf dpi = [96,96]
    Print.prototype.exportPdf96 = function (canvas) {
        var self = this;
        var contentHeight = canvas.height;
        var dpiX = 96;
        var dpiY = 96;
        //一页pdf显示html页面生成的canvas高度;
        var pageWidth = 794;
        var pageHeight = 1123;
        //未生成pdf的html页面高度
        var leftHeight = contentHeight;
        //页面偏移
        var position = 0;
        var pageData = canvas.toDataURL('image/png');
        //l:横向， p：纵向；单位： in:英寸，mm毫米；画布大小：a3,a4,leter,[]（当内容为数组时，为自定义大小）
        var pdf = new jsPDF('', 'in', [(pageWidth) / dpiX, (pageHeight) / dpiY]);//设置PDF宽高为要显示的元素的宽高，将像素转化为英寸
        //有两个高度需要区分，一个是html页面的实际高度，和生成pdf的页面高度(841.89)
        //当内容未超过pdf一页显示的范围，无需分页
        if (leftHeight < pageHeight) {
            //pdf.addImage(pageData, 'png', 0, 0, imgWidth,imgHeight);
            pdf.addImage(pageData, 'png', -154 / dpiX, 5 / dpiY);
        } else {
            var i = 0;
            while (leftHeight > 0) {
                //arg3-->距离左边距;arg4-->距离上边距;arg5-->宽度;arg6-->高度
                //pdf.addImage(pageData, 'png', 0, position,imgWidth, imgHeight);
                var pageGap = self.options.pdfPageGap[i] ? self.options.pdfPageGap[i] : 5;
                pdf.addImage(pageData, 'png', -154 / dpiX, position + pageGap / dpiY);
                leftHeight -= pageHeight;
                position -= (pageHeight) / dpiY;
                i++;
                //避免添加空白页
                if (leftHeight > 0) {
                    pdf.addPage();
                }
            }
        }
        pdf.save(self.options.downloadName + '.pdf');
    };
    //获取屏幕dpi
    Print.prototype.js_getDPI = function () {
        var arrDPI = new Array();
        if (window.screen.deviceXDPI != undefined) {
            arrDPI[0] = window.screen.deviceXDPI;
            arrDPI[1] = window.screen.deviceYDPI;
        }
        else {
            var tmpNode = document.createElement("DIV");
            tmpNode.style.cssText = "width:1in;height:1in;position:absolute;left:0px;top:0px;z-index:99;visibility:hidden";
            document.body.appendChild(tmpNode);
            arrDPI[0] = parseInt(tmpNode.offsetWidth);
            arrDPI[1] = parseInt(tmpNode.offsetHeight);
            tmpNode.parentNode.removeChild(tmpNode);
        }
        return arrDPI;
    };
    // HELPER PLUGIN DEFINITION
    // ==========================
    function Plugin(option) {
        if (typeof FileReader == "undefined") {
            //document.write("不支持FileReader");
            alert("不支持FileReader")
            return;
        } else {
            return this.each(function () {
                var $this = $(this);
                var data;
                // = $this.data('bs.print')
                //if (data) return;
                //if (!data)
                $this.data('bs.print', (data = new Print(this, option)));
                if (typeof option == 'string') data[option].call($this)
            })
        }
    }

    var old = $.fn.print;

    $.fn.print = Plugin;
    $.fn.print.Constructor = Print;

    // HELPER NO CONFLICT
    // ====================
    $.fn.print.noConflict = function () {
        $.fn.print = old;
        return this;
    };
}(jQuery);