/**
 * 通用函数
 */
var config = require('./config.js');
var fun_aes = require('./aes.js');
const app = getApp();

/**
 * 时间戳转为 xxxx-xx-xx xx:xx:xx 格式
 */
function formatTime(time) {
    var dateTime = new Date(time * 1000);
    var year = dateTime.getFullYear();
    var month = dateTime.getMonth() + 1;
    var date = dateTime.getDate();
    var hour = dateTime.getHours();
    var minute = dateTime.getMinutes();
    var second = dateTime.getSeconds();
    abc();
    return year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second;
}

// 时间格式化
function DateFormat(date, fmt) {
    var o = {
        'M+': date.getMonth() + 1,
        'd+': date.getDate(),
        'H+': date.getHours(),
        'm+': date.getMinutes(),
        's+': date.getSeconds(),
        'S+': date.getMilliseconds()
    };
    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    for (var k in o) {
        if (new RegExp('(' + k + ')').test(fmt)) {
            fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(String(o[k]).length));
        }
    }
    return fmt;
}
function formatDateTime(time) {
    var dateTime = new Date(time);
    var year = dateTime.getFullYear();
    var month = ('00' + (dateTime.getMonth() + 1)).substr(String(dateTime.getMonth() + 1).length);
    var date = ('00' + dateTime.getDate()).substr(String(dateTime.getDate()).length);
    var hour = ('00' + dateTime.getHours()).substr(String(dateTime.getHours()).length);
    var minute = ('00' + dateTime.getMinutes()).substr(String(dateTime.getMinutes()).length);
    var second = ('00' + dateTime.getSeconds()).substr(String(dateTime.getSeconds()).length);
    return year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second;
}

/**
 * 格式化秒
 * @param int  value 总秒数
 * @return string result 格式化后的字符串
 */
function formatSeconds(value, tail = true) {
    var theTime = parseInt(value); // 需要转换的时间秒
    var theTime1 = 0; // 分
    var theTime2 = 0; // 小时
    var theTime3 = 0; // 天
    if (theTime === 0) {
        return parseInt(theTime) + '秒';
    }
    if (theTime > 60) {
        theTime1 = parseInt(theTime / 60);
        theTime = parseInt(theTime % 60);
        if (theTime1 > 60) {
            theTime2 = parseInt(theTime1 / 60);
            theTime1 = parseInt(theTime1 % 60);
            if (theTime2 > 24) {
                //大于24小时
                theTime3 = parseInt(theTime2 / 24);
                theTime2 = parseInt(theTime2 % 24);
            }
        }
    }
    var result = '';
    if (theTime > 0) {
        result = '' + parseInt(theTime) + '秒';
    }
    if (theTime1 > 0) {
        result = '' + parseInt(theTime1) + '分' + (tail ? result : '');
    }
    if (theTime2 > 0) {
        result = '' + parseInt(theTime2) + '小时' + (tail ? result : '');
    }
    if (theTime3 > 0) {
        result = '' + parseInt(theTime3) + '天' + (tail ? result : '');
    }
    return result;
}
function getFlatternDistance(lon1, lat1, lon2, lat2) {
    var DEF_PI = 3.14159265359; // PI
    var DEF_2PI = 6.28318530712; // 2*PI
    var DEF_PI180 = 0.01745329252; // PI/180.0
    var DEF_R = 6370693.5; // radius of earth
    var ew1;
    var ns1;
    var ew2;
    var ns2;
    var dx;
    var dy;
    var dew;
    var distance; // 角度转换为弧度
    ew1 = lon1 * DEF_PI180;
    ns1 = lat1 * DEF_PI180;
    ew2 = lon2 * DEF_PI180;
    ns2 = lat2 * DEF_PI180;
    // 经度差
    dew = ew1 - ew2; // 若跨东经和西经180 度,进行调整
    if (dew > DEF_PI) dew = DEF_2PI - dew;
    else if (dew < -DEF_PI) {
        dew = DEF_2PI + dew;
    }
    dx = DEF_R * Math.cos(ns1) * dew; // 东西方向长度(在纬度圈上的投影长度)
    dy = DEF_R * (ns1 - ns2); // 南北方向长度(在经度圈上的投影长度)
    // 勾股定理求斜边长
    distance = Math.sqrt(dx * dx + dy * dy).toFixed(0);
    return distance;
}

/**
 * js简单对象转为url查询字符串key=value&
 */
function obj2UrlQuery(obj) {
    var urlQurey = '';
    for (var key in obj) {
        urlQurey += key + '=' + obj[key] + '&';
    }
    if (urlQurey != '') {
        urlQurey = urlQurey.substring(0, urlQurey.length - 1);
    }
    return urlQurey;
}
function getQueryObject(url) {
    url = url == null ? window.location.href : url;
    const search = url.substring(url.lastIndexOf('?') + 1);
    const obj = {};
    const reg = /([^?&=]+)=([^?&=]*)/g;
    search.replace(reg, (rs, $1, $2) => {
        const name = decodeURIComponent($1);
        let val = decodeURIComponent($2);
        val = String(val);
        obj[name] = val;
        return rs;
    });
    return obj;
}

/**
 * 去掉 undefined/null, 返回默认值
 */
function getDefaultValue(value, default_value) {
    if (value === undefined || value === null) {
        return default_value || '';
    }
    return value;
}

/**
 * 判断为空: undefined/null/空字符
 * 为空返回 true, 否则返回false
 */
function isEmpty(value) {
    if (value === undefined || value === null || value === '' || value.trim() === '') {
        return true;
    }
    return false;
}
function alert(title, content, successCallBack) {
    uni.showModal({
        title: title || '',
        content: content || '',
        showCancel: false,
        success: successCallBack
    });
}
function loading() {
    uni.showLoading({
        title: '正在加载数据 ...',
        mask: true
    });
}

/**
 * 成功提示
 */
function successToast(title, duration) {
    uni.showToast({
        title: title || '成功',
        icon: 'success',
        duration: duration || 1500,
        mask: true
    });
}

/**
 * 简单提示
 */
function simpleToast(title, duration) {
    uni.showToast({
        title: title || '成功',
        icon: 'none',
        duration: duration || 1500
    });
}

/**
 * 手机号验证 简单匹配
 */
function isPhone(phone) {
    return phone.match(/^1[0-9]{10}$/) != null;
}

/**
 * 检验字符串是否是纯数值  正数 小数
 */
function isDigital(num) {
    //return num.match(/^[1-9]?\d+[.]?\d+$/) != null;
    return num.match(/^[0-9]?\d+[.]?\d+$/) != null;
}

/**
 * 选择并上传图片
 */
function uploadImg(callback) {
    uni.chooseImage({
        count: 1,
        success: function (res) {
            var tempFilePaths = res.tempFilePaths;
            uni.uploadFile({
                url: config.API_UP_IMG_URL,
                filePath: tempFilePaths[0],
                name: 'imgFile',
                success: function (res1) {
                    var rtDataObj = JSON.parse(res1.data);
                    if (rtDataObj.code == 200) {
                        callback(rtDataObj.data[0].url);
                    } else {
                        uni.showModal({
                            title: '错误',
                            content: '上传图片错误[' + rtDataObj.message + ']'
                        });
                    }
                }
            });
        }
    });
}

/**
 * 选择并上传图片  七牛存储
 */
function upLoadImgQiNiu(callback) {
    const http = require('./http.js');
    uni.chooseImage({
        count: 1,
        success: function (res) {
            const tempFilePaths = res.tempFilePaths;
            loading();
            http.getApi(config.API_QINIU_UP_IMG_TOKEN, {}, function (response) {
                if (response.data.code === 200) {
                    const token = response.data.data.token;
                    uni.uploadFile({
                        url: config.QINIU_UPLOAD_SITE,
                        filePath: tempFilePaths[0],
                        name: 'file',
                        formData: {
                            token: token
                        },
                        success: function (res1) {
                            uni.hideLoading();
                            var rtDataObj = JSON.parse(res1.data);
                            const key = rtDataObj.key;
                            callback(config.QINIU_SITE + key);
                        },
                        fail: function (res) {
                            simpleToast('上传失败');
                            uni.hideLoading();
                        }
                    });
                } else {
                    simpleToast(response.data.msg);
                    uni.hideLoading();
                }
            });
        }
    });
}

/**
 * 判断一个元素是否在数组中
 */
function inArray(elem, arrayData) {
    for (var i = 0; i < arrayData.length; i++) {
        if (elem == arrayData[i]) {
            return true;
        }
    }
    return false;
}
function compareVersion(v1, v2) {
    v1 = v1.split('.');
    v2 = v2.split('.');
    const len = Math.max(v1.length, v2.length);
    while (v1.length < len) {
        v1.push('0');
    }
    while (v2.length < len) {
        v2.push('0');
    }
    for (let i = 0; i < len; i++) {
        const num1 = parseInt(v1[i]);
        const num2 = parseInt(v2[i]);
        if (num1 > num2) {
            return 1;
        } else if (num1 < num2) {
            return -1;
        }
    }
    return 0;
}
function groupListToTreeRecursion(user, userlist, device) {
    user.children = [];
    user.children_device_cnt = 0;
    user.own_device_cnt = parseInt(user.device_sum);
    var n = userlist.findIndex((x) => {
        return parseInt(x.parent_id) === parseInt(user.id);
    });
    while (n !== -1) {
        var childrenUser = userlist[n];
        userlist.splice(n, 1);
        childrenUser = groupListToTreeRecursion(childrenUser, userlist, device);
        user.children_device_cnt += childrenUser.all_device_cnt;
        user.children.push(childrenUser);
        n = userlist.findIndex((x) => {
            return parseInt(x.parent_id) === parseInt(user.id);
        });
    }
    user.all_device_cnt = user.own_device_cnt + user.children_device_cnt;
    user.children_cnt = user.children.length;
    user.leaf = user.children_cnt === 0;
    return user;
}

// 集团列表转树
function groupListToTree(userlist, id) {
    var user = userlist.find((x) => {
        return parseInt(x.id) === parseInt(id);
    });
    if (user === undefined) {
        return null;
    }
    return groupListToTreeRecursion(user, userlist.concat(), null);
}

// 集团树展开
function groupTreeLeaf(groupTree, grouplist = []) {
    groupTree.children.forEach((p) => {
        grouplist = groupTreeLeaf(p, grouplist);
    });
    groupTree.children = [];
    grouplist.push(groupTree);
    return grouplist;
}

// 点是否在多边形内
function isPointInPolygon(point, polygon) {
    var N = polygon.length;
    var boundOrVertex = true; // 如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
    var intersectCount = 0; // cross points count of x
    var precision = 2e-10; // 浮点类型计算时候与0比较时候的容差
    var p1;
    var p2; // neighbour bound vertices
    var p = point; // 测试点

    p1 = polygon[0]; // left vertex
    for (var i = 1; i <= N; ++i) {
        // check all rays
        if (p[0] === p1[0] && p[1] === p1[1]) {
            return boundOrVertex; // p is an vertex
        }
        p2 = polygon[i % N]; // right vertex
        if (p[1] < Math.min(p1[1], p2[1]) || p[1] > Math.max(p1[1], p2[1])) {
            // ray is outside of our interests
            p1 = p2;
            continue; // next ray left point
        }
        if (p[1] > Math.min(p1[1], p2[1]) && p[1] < Math.max(p1[1], p2[1])) {
            // ray is crossing over by the algorithm (common part of)
            if (p[0] <= Math.max(p1[0], p2[0])) {
                // x is before of ray
                if (p1[1] === p2[1] && p[0] >= Math.min(p1[0], p2[0])) {
                    // overlies on a horizontal ray
                    return boundOrVertex;
                }
                if (p1[0] === p2[0]) {
                    // ray is vertical
                    if (p1[0] === p[0]) {
                        // overlies on a vertical ray
                        return boundOrVertex;
                    } else {
                        // before ray
                        ++intersectCount;
                    }
                } else {
                    // cross point on the left side
                    var xinters = ((p[1] - p1[1]) * (p2[0] - p1[0])) / (p2[1] - p1[1]) + p1[0]; // cross point of x
                    if (Math.abs(p[0] - xinters) < precision) {
                        // overlies on a ray
                        return boundOrVertex;
                    }
                    if (p[0] < xinters) {
                        // before ray
                        ++intersectCount;
                    }
                }
            }
        } else {
            // special case when ray is crossing through the vertex
            if (p[1] === p2[1] && p[0] <= p2[0]) {
                // p crossing over p2
                var p3 = polygon[(i + 1) % N]; // next vertex
                if (p[1] >= Math.min(p1[1], p3[1]) && p[1] <= Math.max(p1[1], p3[1])) {
                    // p[1] lies between p1[1] & p3[1]
                    ++intersectCount;
                } else {
                    intersectCount += 2;
                }
            }
        }
        p1 = p2; // next ray left point
    }
    if (intersectCount % 2 === 0) {
        // 偶数在多边形外
        return false;
    } else {
        // 奇数在多边形内
        return true;
    }
}

// 加密
function aesEncrypt(code, key = [32, 87, 47, 82, 54, 75, 63, 71, 48, 80, 65, 88, 17, 99, 45, 43]) {
    //key和code需要使用十进制的数组表示
    var that = this;
    var o = key; //key的密钥10进制
    var t = fun_aes.CryptoJS.enc.int8array.parse(o);
    var r = fun_aes.CryptoJS.enc.int8array.parse(code);
    var n =
        (r.toString(fun_aes.CryptoJS.enc.Base64),
        fun_aes.CryptoJS.AES.encrypt(r, t, {
            iv: [],
            mode: fun_aes.CryptoJS.mode.ECB,
            padding: fun_aes.CryptoJS.pad.NoPadding
        }));
    var w = fun_aes.CryptoJS.enc.int8array.stringify(n.ciphertext);
    return w;
}
function neInt2hex(num, len) {
    var hex = (num & 65535).toString(16);
    if (len) {
        while (hex.length < len) hex = '0' + hex;
    }
    return hex;
}
function aesDecrypt(code, key = [32, 87, 47, 82, 54, 75, 63, 71, 48, 80, 65, 88, 17, 99, 45, 43]) {
    var that = this;
    var l = code;
    var o = key;
    var t = fun_aes.CryptoJS.enc.int8array.parse(o);
    var r = fun_aes.CryptoJS.enc.int8array.parse(l).toString(fun_aes.CryptoJS.enc.Base64);
    var n = fun_aes.CryptoJS.AES.decrypt(r, t, {
        iv: [],
        mode: fun_aes.CryptoJS.mode.ECB,
        padding: fun_aes.CryptoJS.pad.NoPadding
    });
    n = fun_aes.CryptoJS.enc.int8array.stringify(n);
    return n;
}
function completArray(arr, n) {
    for (var i = n - arr.length; i > 0; i--) {
        arr.push((Math.random() * 255) | 0);
    }
    return arr;
}
function toArrayBuffer(arr) {
    var buffer = new ArrayBuffer(arr.length);
    var view = new Int8Array(buffer);
    for (var i = 0; i < arr.length; i++) {
        view[i] = arr[i];
    }
    return buffer;
}
function getHexData(data) {
    var hexStr = '';
    for (var i = 0; data.length > i; i++) {
        var hex = data[i].toString(16);
        if (hex.length === 1) {
            hex = '0' + hex;
        }
        hexStr = hexStr + hex;
    }
    return hexStr;
}
function arrayToIntHex(array) {
    var total = 0;
    for (var i = 0; array.length > i; i++) {
        total += array[i];
    }
    return dec2hex(total, 8);
}
function dec2hex(dec, len) {
    //10进制转16进制补0
    var hex = '';
    while (dec) {
        var last = dec & 15;
        hex = String.fromCharCode((last > 9 ? 55 : 48) + last) + hex;
        dec >>= 4;
    }
    if (len) {
        while (hex.length < len) hex = '0' + hex;
    }
    return hex;
}
function hexToList(str) {
    var val = [];
    for (var i = 0; i < str.length / 2; i++) {
        val.push(parseInt(str.substring(0 + i * 2, 2 + i * 2), 16));
    }
    return val;
}
function reportBluetooth(macid, functionList1, functionList2, functionList3, functionList4) {
    var functionList_1 = [];
    var functionList_2 = [];
    var functionList_3 = [];
    var functionList_4 = [];
    for (var i = 0; functionList1.length > i; i++) {
        functionList_1.push(parseInt(functionList1[i]));
    }
    for (var i = 0; functionList2.length > i; i++) {
        functionList_2.push(parseInt(functionList2[i]));
    }
    for (var i = 0; functionList3.length > i; i++) {
        functionList_3.push(parseInt(functionList3[i]));
    }
    for (var i = 0; functionList4.length > i; i++) {
        functionList_4.push(parseInt(functionList4[i]));
    }
    const http = require('./http.js');
    var list = [
        {
            code: 30,
            data: JSON.stringify(functionList_1)
        },
        {
            code: 31,
            data: JSON.stringify(functionList_2)
        },
        {
            code: 32,
            data: JSON.stringify(functionList_3)
        },
        {
            code: 9,
            data: JSON.stringify(functionList_4)
        }
    ];
    const pData = {
        macid: macid,
        data: JSON.stringify(list)
    };
    http.postApi(config.API_REPORT_BLUETOOTH, pData, function (response) {
        if (response.data.code === 200) {
        } else {
        }
    });
}
var repeatTime = 0;
function reportBms(macid, data, successCallBack) {
    var pData = {
        macid: macid,
        data: getHexData(data)
    };
    const http = require('./http.js');
    var endTime = new Date().getTime();
    if (endTime - repeatTime > 3000) {
        //防止多条数据重发
        repeatTime = endTime;
        http.postApi(config.API_REPORT_BMS, pData, function (response) {
            if (response.data.code === 200) {
                successCallBack(response);
            }
        });
    }
}
function getQVConfig(macid, successCallBack) {
    var pData = {
        macid: macid
    };
    const http = require('./http.js');
    http.postApi(config.API_QV_CONFIG, pData, function (response) {
        if (response.data.code === 200) {
            successCallBack(response);
        }
    });
}
function bluetoothGetCtlData() {
    const http = require('./http.js');
    // const accountInfo = uni.getAccountInfoSync();
    const app = getApp();
    http.postApi(
        config.API_GET_CTL,
        {
            appid: "wxddbcc3709026525e"
        },
        (resp) => {
            if (resp.data.code === 200) {
                app.globalData.bluetoothConfig = resp.data.data;
            }
        }
    );
}
function completArrayCRC(arr, n = 16) {
    if (arr[0] == 8) {
        console.log(n);
        console.log(n - arr.length);
    }
    for (var i = n - arr.length; i > 1; i--) {
        if (arr[0] == 8) {
        }
        arr.push(0);
    }
    arr.push(arr.reduce((p, c) => p + c) % 256);
    if (arr[0] == 8) {
        console.log(arr);
    }
    return arr;
}
function bluetoothBaud(device, bluetooth, successCallBack) {
    const http = require('./http.js');
    //const accountInfo = uni.getAccountInfoSync();
    const pData = {
        macid: device.mac_id,
        appid: "wxddbcc3709026525e"
    };
    if (device.bt_type === 'ZXBTS') {
        http.postApi(config.API_GET_BPS, pData, (resp) => {
            if (resp.data.code === 200) {
                var baudList = [4800, 9600, 14400, 38400, 56000, 57600, 115200];
                for (var i = 0; baudList.length > i; i++) {
                    if (resp.data.data.bps === baudList[i]) {
                        successCallBack(i);
                    }
                }
                bluetooth.queryBaud(
                    device.mac_id,
                    (res) => {},
                    (res) => {}
                );
            }
        });
    }
}
function bluetoothSetBaud(device, bleBaud, baud, bluetooth) {
    if (bleBaud != baud) {
        bluetooth.setBaud(
            device.mac_id,
            baud,
            (res) => {
                console.log('设置波特率成功');
                console.log(res);
                setTimeout(function () {
                    bluetooth.stateUpdate(
                        device.mac_id,
                        (res) => {},
                        (res) => {}
                    );
                }, 500);
            },
            (res) => {}
        );
    }
}
module.exports = {
    formatTime: formatTime,
    formatDateTime: formatDateTime,
    formatSeconds: formatSeconds,
    obj2UrlQuery: obj2UrlQuery,
    getQueryObject: getQueryObject,
    getDefaultValue: getDefaultValue,
    isEmpty: isEmpty,
    alert: alert,
    isPhone: isPhone,
    loading: loading,
    successToast: successToast,
    simpleToast: simpleToast,
    isDigital: isDigital,
    uploadImg: uploadImg,
    upLoadImgQiNiu: upLoadImgQiNiu,
    inArray: inArray,
    compareVersion: compareVersion,
    groupListToTree: groupListToTree,
    isPointInPolygon: isPointInPolygon,
    DateFormat: DateFormat,
    groupTreeLeaf: groupTreeLeaf,
    aesEncrypt: aesEncrypt,
    aesDecrypt: aesDecrypt,
    arrayToIntHex: arrayToIntHex,
    dec2hex: dec2hex,
    hexToList: hexToList,
    completArray: completArray,
    toArrayBuffer: toArrayBuffer,
    getFlatternDistance: getFlatternDistance,
    bluetoothGetCtlData: bluetoothGetCtlData,
    reportBluetooth: reportBluetooth,
    completArrayCRC: completArrayCRC,
    reportBms: reportBms,
    getQVConfig: getQVConfig,
    bluetoothBaud: bluetoothBaud,
    bluetoothSetBaud: bluetoothSetBaud,
    neInt2hex: neInt2hex
};