/**
 * ease:
 * 'linear'  动画从头到尾的速度是相同的
 * 'ease'  动画以低速开始,然后加快,在结束前变慢
 * 'ease-in'  动画以低速开始
 * 
 * 'ease-in-out'  动画以低速开始和结束
 * 'ease-out'  动画以低速结束
 * 'step-start'  动画第一帧就跳至结束状态直到结束
 * 'step-end'  动画一直保持开始状态,最后一帧跳到结束状态
 */
let config = {
    size: {
        width: '560rpx',
        height: '560rpx'
    }, // 转盘宽高
    bgColors: ['#FFC53F', '#FFED97'], // 转盘间隔背景色 支持多种颜色交替
    fontSize: 12, // 文字大小
    fontColor: '#C31A34', // 文字颜色
    nameMarginTop: 12, // 最外文字边距
    nameLength: 6, // 最外文字个数
    iconWidth: 32, // 图标宽度
    iconHeight: 32, // 图标高度
    iconAndTextPadding: 4, // 最内文字与图标的边距
    duration: 3000, // 转盘转动动画时长
    rate: 1.5, // 由时长s / 圈数得到
    border: 'border: 10rpx solid #FEFAE4;', // 转盘边框
    ease: 'ease-out' // 转盘动画
};

let preAngle = 0; // 上一次选择角度
let preAngle360 = 0; // 上一次选择角度和360度之间的差
let retryCount = 10; // 报错重试次数
let retryTimer; // 重试setTimeout
let drawTimer; // 绘制setTimeout
Component({
    properties: {
        // 是否可用
        enable: {
            type: Boolean,
            value: true
        },
        // 数据
        gifts: {
            type: Array,
            value: []
        },
        //  中奖id
        prizeId: {
            type: String,
            value: ''
        },
        // 配置项 传入后和默认的配置进行合并
        config: {
            type: Object,
            value: {}
        },

        // 抽奖次数
        count: {
            type: Number,
            default: ""
        },

    },
    data: {
        lotteryCount: null,
        cost: null,
        turnCanvasInfo: { width: 0, height: 0 },
        size: config.size,
        giftModule: [],
        disable: false,
        canvasImgUrl: '',
        border: config.border,
        infos: []
    },
    methods: {
        async getCanvasContainerInfo(id) {
            return new Promise((resolve) => {
                const query = wx.createSelectorQuery().in(this);
                query.select(id).boundingClientRect(function (res) {
                    const { width, height } = res;
                    resolve({ width, height });
                }).exec();
            });
        },
        async init() {
            try {
                const info = await this.getCanvasContainerInfo('#turn');
                if (info.width && info.height) {
                    this.setData({
                        turnCanvasInfo: info
                    });
                    this.drawTurn();
                } else {
                    wx.showToast({
                        icon: 'nont',
                        title: '获取转盘宽高失败'
                    })
                }
            } catch (e) {
                if (retryCount <= 0) {
                    return;
                }
                retryCount--;
                if (retryTimer) {
                    clearTimeout(retryTimer);
                }
                retryTimer = setTimeout(async () => {
                    await this.init();
                }, 100);
            }
        },
        drawTurn() {
            const turnCanvasInfo = this.data.turnCanvasInfo;
            const giftModule = this.properties.gifts;
            const ctx = wx.createCanvasContext('turn', this);
            // 计算没个扇区弧度
            const radian = Number((2 * Math.PI / giftModule.length).toFixed(2));
            // 绘制扇区并记录每个扇区信息
            const infos = this.drawSector(radian, giftModule, ctx, turnCanvasInfo);
            // 记录旋转角度
            this.recordTheRotationAngle(infos);
            // 绘制扇区文本及图片
            this.drawTextAndImage(giftModule, ctx, turnCanvasInfo, radian);
            ctx.draw(false, () => {
                this.saveToTempPath(turnCanvasInfo);
            });
        },
        saveToTempPath(turnCanvasInfo) {
            if (drawTimer) {
                clearTimeout(drawTimer);
            }
            drawTimer = setTimeout(() => {
                wx.canvasToTempFilePath({
                    canvasId: 'turn',
                    quality: 1,
                    x: 0,
                    y: 0,
                    width: turnCanvasInfo.width,
                    height: turnCanvasInfo.height,
                    success: (res) => {
                        this.setData({
                            canvasImgUrl: res.tempFilePath
                        });
                    },
                    fail: (error) => {
                        console.log(error);
                    }
                }, this);
            }, 500);
        },
        drawSector(radian, giftModule, ctx, turnCanvasInfo) {
            const halfRadian = Number((radian / 2).toFixed(2));
            let startRadian = -Math.PI / 2 - halfRadian;
            const angle = 360 / giftModule.length;
            const halfAngle = angle / 2;
            let startAngle = -90 - halfAngle;
            const infos = [];
            // 绘制扇形
            for (let i = 0; i < giftModule.length; i++) {
                // 保存当前状态
                ctx.save();
                // 开始一条新路径
                ctx.beginPath();
                ctx.moveTo(turnCanvasInfo.width / 2, turnCanvasInfo.height / 2);
                ctx.arc(turnCanvasInfo.width / 2, turnCanvasInfo.height / 2, turnCanvasInfo.width / 2, startRadian, startRadian + radian);
                if (giftModule[i].bgColor) {
                    ctx.setFillStyle(giftModule[i].bgColor);
                } else {
                    ctx.setFillStyle(config.bgColors[i % config.bgColors.length]);
                }
                ctx.fill();
                ctx.closePath();
                ctx.restore();
                infos.push({
                    id: giftModule[i].objectId,
                    angle: (startAngle + startAngle + angle) / 2
                });
                startRadian += radian;
                startAngle += angle;
            }
            return infos;
        },
        drawTextAndImage(giftModule, ctx, turnCanvasInfo, radian) {
            let startRadian = 0;
            // 绘制扇形文字和logo
            for (let i = 0; i < giftModule.length; i++) {
                // 保存当前状态
                ctx.save();
                // 开始一条新路径
                ctx.beginPath();
                ctx.translate(turnCanvasInfo.width / 2, turnCanvasInfo.height / 2);
                ctx.rotate(startRadian);
                ctx.translate(-turnCanvasInfo.width / 2, -turnCanvasInfo.height / 2);
                if (giftModule[i].fontSize) {
                    ctx.setFontSize(giftModule[i].fontSize);
                } else {
                    ctx.setFontSize(config.fontSize);
                }
                ctx.setTextAlign('center');
                if (giftModule[i].fontColor) {
                    ctx.setFillStyle(giftModule[i].fontColor);
                } else {
                    ctx.setFillStyle(config.fontColor);
                }
                ctx.setTextBaseline('top');
                if (giftModule[i].name) {
                    ctx.fillText(giftModule[i].name, turnCanvasInfo.width / 2, config.nameMarginTop);
                }
                if (giftModule[i].subname) {
                    ctx.fillText(giftModule[i].subname ? giftModule[i].subname : '', turnCanvasInfo.width / 2, config.nameMarginTop + config.fontSize + 2);
                }
                if (giftModule[i].imgUrl) {
                    ctx.drawImage(giftModule[i].imgUrl,
                        turnCanvasInfo.width / 2 - config.iconWidth / 2,
                        config.nameMarginTop + config.fontSize * 2 + 2 + config.iconAndTextPadding,
                        config.iconWidth, config.iconHeight);
                }
                ctx.closePath();
                ctx.restore();
                startRadian += radian;
            }
        },
        recordTheRotationAngle(infos) {
            for (let i = infos.length - 1; i >= 0; i--) {
                infos[i].angle -= infos[0].angle;
                infos[i].angle = 360 - infos[i].angle;
            }
            // 记录id及滚动的角度
            this.setData({
                infos: infos
            });
        },
        luckDrawHandle() {
            if (this.data.disable || !this.data.canvasImgUrl) {
                return;
            }
            this.setData({
                disable: true
            });
            console.log('开始抽奖')
            this.triggerEvent('LuckDraw');
        },
        startAnimation(angle) {
            if (this.data.lotteryCount - this.data.cost < 0) {
                this.setData({
                    disable: false
                });
                this.triggerEvent('NotEnough', '积分不足!');
                return;
            }
            // 抽奖次数减一
            this.setData({
                lotteryCount: this.data.lotteryCount - this.data.cost
            });
            const currentAngle = preAngle;
            preAngle += Math.floor((config.duration / 1000) / config.rate) * 360 + angle + preAngle360;
            this.animate('#canvas-img', [
                { rotate: currentAngle, ease: 'linear' },
                { rotate: preAngle, ease: config.ease },
            ], config.duration, () => {
                this.setData({
                    disable: false
                });
                preAngle360 = 360 - angle;
                this.triggerEvent('LuckDrawFinish');
            });
        },

        downloadHandle(url) {
            return new Promise((resolve, reject) => {
                wx.downloadFile({
                    url: url, // 仅为示例,并非真实的资源
                    success: (res) => {
                        // 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
                        if (res.statusCode === 200) {
                            resolve(res.tempFilePath);
                        } else {
                            reject();
                        }
                    },
                    fail: () => {
                        reject();
                    }
                });
            });
        },
        async downloadImg(imgs) {
            let result;
            try {
                const downloadHandles = [];
                for (const url of imgs) {
                    if (this.isAbsoluteUrl(url)) { // 是网络地址
                        downloadHandles.push(this.downloadHandle(url));
                    } else {
                        downloadHandles.push(Promise.resolve(url));
                    }
                }
                result = await Promise.all(downloadHandles);
            } catch (e) {
                console.log(e);
                result = [];
            }
            return result;
        },
        clearTimeout() {
            if (retryTimer) {
                clearTimeout(retryTimer);
            }
            if (drawTimer) {
                clearTimeout(drawTimer);
            }
        },
        isAbsoluteUrl(url) {
            return /(^[a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
        },
        async initData(data) {
            let name;
            let subname;
            let imgUrls = [];
            if (this.properties.config) {
                config = Object.assign(config, this.properties.config);

            }
            for (const d of data) {
                name = d.name;
                imgUrls.push(d.imgUrl);
                d.imgUrl = '';
                if (name.length > config.nameLength) {
                    d.name = name.slice(0, config.nameLength);
                    subname = name.slice(config.nameLength);
                    if (subname.length > config.nameLength - 2) {
                        d['subname'] = subname.slice(0, config.nameLength - 2) + '...';
                    } else {
                        d['subname'] = subname;
                        /*   console.log('是否开启了概率???', that.data.probability);
                          //开启概率 probability这属性必须要传个ture
                          if (that.data.probability) {
                              r = that._openProbability();
                          } */
                    }
                }
            }
            imgUrls = await this.downloadImg(imgUrls);
            for (let i = 0; i < imgUrls.length; i++) {
                data[i].imgUrl = imgUrls[i];
            }
            this.setData({
                giftModule: data
            });
            await this.init();
        }
    },

    observers: {
        'gifts': async function (gifts) {
            if (!gifts || !gifts.length) {
                return;
            }
            await this.initData(gifts);
        },
        'enable': function (enable) {
            this.setData({
                disable: !enable
            });
        },
        'prizeId': function (id) {
            if (!id) {
                this.setData({
                    disable: false
                });
                return;
            }
            try {
                const infos = this.data.infos;
                console.log(infos, id)
                const info = infos.find((item) => item.id == id);
                console.log(info)
                this.startAnimation(info.angle);
            } catch (e) {
                this.setData({
                    disable: false
                });
            }
        },
        'count': function (lotteryCount) {
            console.log(lotteryCount)
            this.setData({
                lotteryCount
            });
        },
        // 'cost': function(cost) {
        //     console.log(cost)
        //     this.setData({
        //         cost
        //     });
        // },
    },


    lifetimes: {

        detached() {
            this.clearTimeout();
        }
    },
    pageLifetimes: {
        hide() {
            this.clearTimeout();
        }
    }
});