// import mergeImages from "./mergeImages";

export default {
    data(){
        return {
            system_info:{}, //system info
            canvas_width:0, //canvas width px
            canvas_height:0, //canvas height px
            ctx:null, //canvas object
            canvas_id:null, //canvas id
            hidden:false, //Whether to hide canvas
            scale:1, //canvas scale
            r_canvas_scale:1,
            if_ctx:true
        }
    },
    methods:{
        /**
         * Compatibility px
         * @param {Object} size
         */
        compatibilitySize(size) {
            let canvasSize = (parseFloat(size) / 750) * this.system_info.windowWidth
            canvasSize = parseFloat(canvasSize * 2)
            return canvasSize
        },
        /**
         * Restore compatibility px
         * @param {Object} size
         */
        resetCompatibilitySize(size) {
            return (parseFloat(size / 2) / this.system_info.windowWidth) * 750
        },
        async init(config){
            if(config.path){
                // 存一下实际图片大小 用于缩放比
                this.imagesConfig = await this.scaleImageInfo(config.path);
            }

            return new Promise(async (resolve,reject)=>{
                if(!config.canvas_id){
                    reject("Canvas ID cannot be empty, please refer to the usage example")
                    return;
                }
                this.hidden = config.hidden
                this.canvas_id = config.canvas_id
                let system_info = await uni.getSystemInfoSync()
                this.system_info = system_info
                this.scale = config.scale && parseFloat(config.scale)>0?parseInt(config.scale):1
                this.canvas_width = (config.canvas_width ? this.compatibilitySize(config.canvas_width) : system_info.windowWidth) * this.scale
                this.canvas_height = (config.canvas_height ? this.compatibilitySize(config.canvas_height) : system_info.windowHeight) * this.scale,
                    this.r_canvas_scale = 1/this.scale
                this.ctx = uni.createCanvasContext(this.canvas_id,this)
                resolve()
            })
        },

        draw(callback){
            return new Promise((resolve,reject)=>{
                let stop = setTimeout(()=>{
                    this.ctx.draw(false,setTimeout(()=>{
                        uni.canvasToTempFilePath({
                            canvasId: this.canvas_id,
                            quality: 1,
                            success: (res)=>{
                                // console.log("--draw--"+ this.canvas_id)
                                resolve(res)
                                callback && callback(res)
                            },
                            fail:(err)=>{
                                reject(JSON.stringify(err)|| "Failed to generate poster:101")
                            }
                        },this)
                    },300))
                    clearTimeout(stop)
                },300)
            })
        },
        clearCanvas(callback){
            return new Promise(async (resolve,reject)=>{
                if(!this.ctx){
                    reject("canvas is not initialized:101")
                    return
                }else{
                    this.ctx.clearRect(0,0,
                        parseFloat(this.canvas_width)*this.scale,
                        parseFloat(this.canvas_height)*this.scale
                    )
                    this.ctx.draw(false,callback)
                    resolve()
                }
            })
        },

        readFile(url){
            return new Promise((resolve, reject) => {
                plus.io.resolveLocalFileSystemURL(url,(obj)=>{
                    obj.file((file)=>{
                        let fileReader = new plus.io.FileReader()
                        fileReader.onload = (res)=>{
                            resolve(res.target.result)
                        }
                        fileReader.onerror = (err)=>{
                            reject(err)
                        }
                        fileReader.readAsDataURL(file)
                    }, (err)=>{
                        reject(err)
                    })
                },(err)=>{
                    reject(err)
                })
            })
        },
        // 下载图片资源
        downLoadNetworkFile(url){
            // #ifdef APP-PLUS
            if(url.indexOf('http') > -1){
                return new Promise((resolve,reject)=>{
                    uni.downloadFile({
                        url,
                        success:(res)=>{
                            // console.log(res.tempFilePath)
                            if(res.statusCode == 200){
                                resolve(res.tempFilePath)
                            }else{
                                reject("Download Image Fail:102")
                            }
                        },
                        fail:(err)=>{
                            reject("Download Image Fail:101")
                        }
                    })
                })
            }else{
                return this.readFile(url);
            }
            // #endif

            // #ifdef H5
            return new Promise((resolve,reject)=>{
                uni.downloadFile({
                    url,
                    success:(res)=>{
                        // console.log(res.tempFilePath)
                        if(res.statusCode == 200){
                            resolve(res.tempFilePath)
                        }else{
                            reject("Download Image Fail:102")
                        }
                    },
                    fail:(err)=>{
                        reject("Download Image Fail:101")
                    }
                })
            })
            // #endif
        },
        urlToBase64(config){
            return new Promise(async (resolve,reject)=>{
                if (typeof window != 'undefined') {
                    await this.downLoadNetworkFile(config.url).then(res=>{ // two function
                        resolve(res)
                    }).catch(err=>{
                        reject(err)
                    })
                }else if (typeof plus != 'undefined') {
                    plus.io.resolveLocalFileSystemURL(config.url,(obj)=>{
                        obj.file((file)=>{
                            let fileReader = new plus.io.FileReader()
                            fileReader.onload = (res)=>{
                                resolve(res.target.result)
                            }
                            fileReader.onerror = (err)=>{
                                reject(err)
                            }
                            fileReader.readAsDataURL(file)
                        }, (err)=>{
                            reject(err)
                        })
                    },(err)=>{
                        reject(err)
                    })
                }else if(typeof wx != 'undefined'){
                    wx.getFileSystemManager().readFile({
                        filePath: config.url,
                        encoding: 'base64',
                        success: function(res) {
                            resolve('data:image/png;base64,' + res.data)
                        },
                        fail: function(error) {
                            reject(error)
                        }
                    })
                }
            })
        },


        mergeImageByColor(image,color,borderWidth = 0){
            let ctx = this.ctx;
            const dArr = [-1, -1, 0, -1, 1, -1, -1, 0, 1, 0, -1, 1, 0, 1, 1, 1]; // offset array
            // 平移图像
            for (let i = 0; i < dArr.length; i += 2)
                ctx.drawImage(image, dArr[i] * borderWidth, dArr[i + 1] * borderWidth);
            // 填充描边色
            ctx.globalCompositeOperation = "source-in";
            ctx.fillStyle = color;
            ctx.globalAlpha = 1;
            ctx.fillRect(0, 0, this.canvas_width,this.canvas_height);

            // 添加原图
            ctx.globalCompositeOperation = "source-atop";
            ctx.drawImage(image, 0, 0);
            ctx.draw();
        },
        async mergeImageByImg(item,target){
            let ctx = this.ctx;
            ctx.globalCompositeOperation = "source-over";
            let fileList = [
                await this.downLoadNetworkFile(item),
                await this.downLoadNetworkFile(target),
            ]
            let options = this.getScaleOptions();
            return new Promise((resolve, reject) => {
                    resolve(
                        Promise.all(fileList)
                            .then((images) =>{
                                const borderWidth = 0;
                                const dArr = [-1, -1, 0, -1, 1, -1, -1, 0, 1, 0, -1, 1, 0, 1, 1, 1]; // offset array
                                // 平移图像
                                for (let i = 0; i < dArr.length; i += 4)
                                    ctx.drawImage(images[0], dArr[i] * borderWidth, dArr[i + 1] * borderWidth,this.canvas_width, this.canvas_height);
                                // 填充描边色
                                ctx.globalCompositeOperation = "source-in";
                                ctx.fillRect(0, 0, this.canvas_width, this.canvas_height);

                                // // 添加原图
                                ctx.globalCompositeOperation = "source-atop";
                                ctx.drawImage(images[1], 0, 0,options.width, options.height);
                                ctx.draw();

                            })
                    )
            })
        },
        mergeImages(sources = []){
            let options = this.getScaleOptions();
            return new Promise((resolve,reject) =>{
                // Load sources
                let fileList = sources.map((source) => {
                    return this.downLoadNetworkFile(source);
                });
                resolve(
                    Promise.all(fileList)
                        .then((images) =>{
                            // Draw images to canvas

                            images.forEach((image) => {
                                this.ctx.globalAlpha = image.opacity ? image.opacity : 1;
                                return this.ctx.drawImage(image,  0, 0 ,options.width,options.height);
                                // return this.ctx.drawImage(image,  0, 0 , this.canvas_width,this.canvas_height);
                            });
                            this.ctx.draw();
                        })
                )
            })
        },
        scaleImageInfo(src){
            return new Promise((resolve,reject) =>{
                uni.getImageInfo({
                    src: src,
                    success(res){
                        resolve(res);
                    },
                    fail:(error) =>{
                        reject(JSON.stringify(error))
                    }
                })
            })
        },
        getScaleOptions(){
            let {
                width,height
            } = this.imagesConfig;
            if(width > height){
                return {
                    width: 375,
                    height: Number(parseFloat(this.canvas_height * (this.canvas_width / width)).toFixed(2))
                }
            }else{
                return {
                    width: Number(parseFloat(this.canvas_width * (this.canvas_height / height)).toFixed(2)),
                    height: 375,
                }
            }
        },

        drawImage(config){
            return new Promise(async (resolve,reject)=>{
                if(config.url){
                    let type = 0 // 1、network image  2、native image  3、base64 image
                    let image_url
                    let reg = /^https?/ig;
                    if(reg.test(config.url)){
                        type = 1
                    }else{
                        if((config.url.indexOf("data:image/png;base64") != -1) || config.url.indexOf("data:image/jpeg;base64") != -1){
                            type = 3
                        }else{
                            type = 2
                        }
                    }
                    if(type == 1){
                        // network image
                        await this.downLoadNetworkFile(config.url).then(res=>{ // two function
                            image_url = res
                        }).catch(err=>{
                            reject(err)
                            return;
                        })
                    }else if(type == 2){
                        // native image
                        const imageInfoResult = await uni.getImageInfo({
                            src: config.url
                        });

                        try{
                            if(imageInfoResult.length <= 1){
                                reject(imageInfoResult[0].errMsg + ':404')
                                return
                            }
                        }catch(e){
                            reject(e+':500')
                            return
                        }
                        let base64 = await this.urlToBase64({url:imageInfoResult[1].path})
                        // #ifdef MP-WEIXIN
                        await this.base64ToNative({url:base64}).then(res=>{
                            image_url = res
                        }).catch(err=>{
                            reject(JSON.stringify(err)+":501")
                            return;
                        })
                        // #endif
                        // #ifndef MP-WEIXIN
                        image_url = base64
                        // #endif

                    }else if(type == 3){
                        // #ifdef MP-WEIXIN
                        await this.base64ToNative({url:config.url}).then(res=>{
                            image_url = res
                        }).catch(err=>{
                            reject(JSON.stringify(err)+":500")
                            return;
                        })
                        // #endif
                        // #ifndef MP-WEIXIN
                        image_url = config.url
                        // #endif
                    }else{
                        reject("Other Type Errors:101")
                        return
                    }
                    if(config.border_width){
                        let border_radius = 0
                        if(config.border_radius){
                            let multiple = config.w / config.border_radius
                            border_radius = (parseFloat(config.w) + parseFloat(config.border_width)) / multiple
                        }
                        // drawRect
                        await this.drawRect({
                            x:parseFloat(config.x) - parseFloat(config.border_width)/2,
                            y:parseFloat(config.y) - parseFloat(config.border_width)/2,
                            w:parseFloat(config.w) + parseFloat(config.border_width),
                            h:parseFloat(config.h) + parseFloat(config.border_width),
                            color:config.border_color,
                            border_radius:border_radius,
                            border_width:config.border_width,
                            is_radius:config.is_radius
                        })
                    }



                    if(config.border_radius){
                        this.setNativeBorderRadius(config)
                    }else if(config.is_radius){
                        //已废弃 is_radius
                        this.ctx.setStrokeStyle("rgba(0,0,0,0)")
                        this.ctx.save()
                        this.ctx.beginPath()
                        this.ctx.arc(this.compatibilitySize(parseFloat(config.x)*this.scale+parseFloat(config.w)*this.scale/2), this.compatibilitySize(parseFloat(config.y)*this.scale+parseFloat(config.h)*this.scale/2), this.compatibilitySize(parseFloat(config.w)*this.scale/2), 0, 2 * Math.PI, false)
                        this.ctx.stroke();
                        this.ctx.clip()
                    }

                    await this.ctx.drawImage(image_url,this.compatibilitySize(parseFloat(config.x)*this.scale),this.compatibilitySize(parseFloat(config.y)*this.scale),this.compatibilitySize(parseFloat(config.w)*this.scale),this.compatibilitySize(parseFloat(config.h)*this.scale))

                    this.ctx.restore() //Restore previously saved drawing context
                    resolve()
                }else{
                    let err_msg = "Links cannot be empty:101"
                    reject(err_msg)
                }
            })
        },

        exportImg(){
            return new Promise((resolve,reject) => {
                setTimeout(() =>{
                    uni.canvasToTempFilePath({
                        canvasId: this.canvas_id,
                        quality: 1,
                        success: (res)=>{
                            // console.log('res',res.tempFilePath)
                            resolve(res.tempFilePath)
                        },
                        fail:(err)=>{
                            reject(JSON.stringify(err)|| "Failed to generate poster:101")
                        }
                    },this)
                },1200)
            })

        }
    }
}
