//  从数据库获取数据

const Seq = require('sequelize')
var mysql = require('mysql2'),
    extend = require('extend'),
    moment = require('moment'),
    rp = require('request-promise'),
    log = console.log.bind(console),
    error = console.error.bind(console),
    config = require('config'),
    utils = require('./utils'),
    dbConfig = config.get('dbConfig')

const sequelize = new Seq({
    database: dbConfig.database,
    username: dbConfig.user,
    password: dbConfig.password,
    host: dbConfig.host,
    dialect: 'mysql',
    pool: {
        max: 20,
        min: 2,
        acquire: 30000,
        idle: 10000
    },
    define: {
        timestamps: false // 默认为 true
    },
    dialectOptions: {
        dateStrings: 'DATETIME',
    },
    isParse: false,
    timezone: '+08:00'
});


const Task = sequelize.define('zmop_task', {
    app_id: {type: Seq.STRING,},
    app_key: {type: Seq.STRING},
    order_id: {type: Seq.STRING},
    success: {type: Seq.INTEGER},
    error_msg: {type: Seq.STRING},
    open_id: {type: Seq.STRING},
    cert_no: {type: Seq.STRING},
    cert_name: {type: Seq.STRING},
    cert_phone: {type: Seq.STRING},
    access_token: {type: Seq.STRING},
    platform: {type: Seq.STRING},
    redirect: {type: Seq.STRING},
    create_time: {type: Seq.DATE},
    finish_time: {type: Seq.DATE},
}, {
    freezeTableName: true
})
Task.removeAttribute('id')

//
async function create(params, table) {
    try {
        params.create_time = moment().format('YYYY-MM-DD HH:mm:ss')
        let keys = Object.keys(params).join('`,`')
        let values = Object.values(params).join('","')
        let sql = 'INSERT INTO ' + table + ' (`' + keys + '`) VALUES("' + values + '")'
        let ret = await sequelize.query(sql, {replacements: [keys, values]})
        console.log(ret)
    } catch (e) {
        throw e
    }
}


async function create_watch_list(row) {
    try {
        let sql = 'INSERT INTO zmop_watch_list (`id`,`open_id`,`platform`,`is_matched`,`details`,`create_time`) VALUES(?,?,?,?,?,?)'
        let ret = await sequelize.query(sql,
            {replacements: [row.id, row.open_id, row.platform, row.is_matched, row.details, row.create_time]})
        console.log(ret)
    } catch (e) {
        throw e
    }
}


async function bill_record(app_key, order_id, cert_no, data1, data2, method = 'score', refresh=0,type) {
    try {
        return await sequelize.transaction(async function (t) {
            let sql = 'SELECT `score_price` as price, `balance` FROM `zmop_partner` WHERE `app_key` = ? AND `using` = 1'
            let bill = 'INSERT INTO zmop_bill_score (`app_key`, `order_id`, `create_time`, `cert_no`, `score`, `which_month`, `refresh`,`method`) VALUES(?,?,?,?,?,?,?,?)'
            if (method == 'watch_list') {
                sql = 'SELECT `watch_list_price` as price, `balance` FROM `zmop_partner` WHERE `app_key` = ? AND `using` = 1'
                bill = 'INSERT INTO zmop_bill_watch_list (`app_key`, `order_id`, `create_time`, `cert_no`, `details`, `is_matched`, `refresh`,`method`) VALUES(?,?,?,?,?,?,?,?)'
            }
            let ret = await sequelize.query(sql, {replacements: [app_key], type: sequelize.QueryTypes.SELECT})
            if (ret.length != 1) {
                throw new Error('无效的appKey')
            }
            log(ret[0])
            let price = Number(ret[0].price)
            if (price > Number(ret[0].balance)) {
                throw new Error('您的余额不足, 请充值')
            }
            sql = 'UPDATE zmop_partner SET balance = balance - ? where `app_key` = ?'
            await sequelize.query(sql, {replacements: [price, app_key], transaction: t})

            return await sequelize.query(bill, {
                replacements: [app_key, order_id, new Date().toLocaleString(), cert_no, data1, data2, refresh,type],
                transaction: t
            })
        })
    } catch (e) {

        throw e
    }
}

async function brief_bill_record(app_key, order_id, cert_no,cert_name, data1, data2, app_id, method = 'score', refresh=0) {
    try {
        return await sequelize.transaction(async function (t) {
            let sql = 'SELECT `score_price` as price, `balance` FROM `zmop_partner` WHERE `app_key` = ? AND `using` = 1'
            let bill = 'INSERT INTO zmop_bill_brief_score (`app_key`, `order_id`, `create_time`, `cert_no`, `cert_name`, `admit_score`, `is_admittance`, `app_id`, `refresh`) VALUES(?,?,?,?,?,?,?,?,?)'
            if (method == 'watch_list') {
                sql = 'SELECT `score_price` as price, `balance` FROM `zmop_partner` WHERE `app_key` = ? AND `using` = 1'
                bill = 'INSERT INTO zmop_bill_brief_watch_list (`app_key`, `order_id`, `create_time`, `cert_no`, `cert_name`,`level`, `var1`, `app_id`, `refresh`) VALUES(?,?,?,?,?,?,?,?,?)'
            }
            let ret = await sequelize.query(sql, {replacements: [app_key], type: sequelize.QueryTypes.SELECT})
            if (ret.length != 1) {
                throw new Error('无效的appKey')
            }
            log(ret[0])
            let price = Number(ret[0].price)
            if (price > Number(ret[0].balance)) {
                throw new Error('已达到接口调用限制次数')
            }
            sql = 'UPDATE zmop_partner SET balance = balance - ? where `app_key` = ?'
            await sequelize.query(sql, {replacements: [price, app_key], transaction: t})

            return await sequelize.query(bill, {
                replacements: [app_key, order_id, new Date().toLocaleString(), cert_no,cert_name, data1, data2, app_id, refresh],
                transaction: t
            })
        })
    } catch (e) {

        throw e
    }
}


async function get_auth(app_key) {
    try {
        let sql = 'SELECT `app_key`, `get_score`, `get_watch_list`,`get_brief_score`, `get_brief_watch_list`, ' +
            '`balance`, `score_price` FROM zmop_partner WHERE app_key = ? AND `using` = 1'
        let row = await sequelize.query(sql, {replacements: [app_key], type: sequelize.QueryTypes.SELECT})
        if (row.length != 1) {
            throw new Error('无效的appKey')
        }
        return row[0]
    } catch (e) {
        error(e)
        throw e
    }
}


//  最新的任务
async function task(order_id) {
    try {
        let sql = 'SELECT open_id, platform, create_time, app_id, cert_no, access_token FROM zmop_task  WHERE success = 1 and order_id = ?'
        let ret = await sequelize.query(sql, {
            replacements: [order_id,],
            type: sequelize.QueryTypes.SELECT
        })
        if (ret.length == 0) {
            log('API-[ last_task ]: 无此订单号', order_id)
            throw new Error('无此订单号')
        }
        return ret[0]
    } catch (e) {
        error(e)
        throw e
    }
}

//获取最新查询参数
async function openId(task) {
    try{
        let sql = 'SELECT open_id, access_token,app_id,platform FROM zmop_open_id WHERE open_id = ? ORDER BY create_time DESC';
        let ret = await sequelize.query(sql, {
            replacements: [task.open_id],
            type:sequelize.QueryTypes.SELECT
        })
        if (ret.length == 0){
            log('API-[ last_task ]: 无此订单号', JSON.stringify(task));
            throw new Error('无此订单号')
        }
        return ret[0]
    }catch (e){
        error(e)
        throw e
    }
}

//  最新的任务
async function bill(order_id, data_type = 'score') {
    try {
        let sql = 'SELECT order_id, cert_no, create_time, score, which_month FROM zmop_bill_score WHERE order_id = ? order by create_time DESC'
        if (data_type == 'watch_list') {
            sql = 'SELECT order_id, cert_no, create_time, details, is_matched FROM zmop_bill_watch_list WHERE order_id = ? order by create_time DESC'
        }
        let ret = await sequelize.query(sql, {
            replacements: [order_id,],
            type: sequelize.QueryTypes.SELECT
        })
        if (ret.length == 0) {
            log('API-[ last_task ]: 无此订单号', order_id)
            return false
        }
        return ret[0]
    } catch (e) {
        error(e)
        throw e
    }
}


//  最新的普惠版账单
async function brief_bill(order_id, data_type = 'score') {
    try {
        let sql = 'SELECT order_id, cert_no, create_time, admit_score, is_admittance FROM zmop_bill_brief_score WHERE order_id = ? order by create_time DESC'
        if (data_type == 'watch_list') {
            sql = 'SELECT order_id, cert_no, create_time, level FROM zmop_bill_brief_watch_list WHERE order_id = ? order by create_time DESC'
        }
        let ret = await sequelize.query(sql, {
            replacements: [order_id,],
            type: sequelize.QueryTypes.SELECT
        })
        if (ret.length == 0) {
            log('API-[ last_task ]: 无此订单号', order_id)
            return false
        }
        return ret[0]
    } catch (e) {
        error(e)
        throw e
    }
}

// setTimeout(async function () {
//     try {
//         log(await payload_brief('650', ''))
//     } catch (e) {
//         log(e)
//     }
// })


async function create_api_task(params) {
    try {
        let sql = 'INSERT INTO zmop_api_task (`transaction_id`, `resp`, `open_id`, `create_time`, `method`, `platform`) VALUES (?,?,?,?,?,?)'
        await sequelize.query(sql, {
            replacements: [params.transaction_id, params.resp, params.open_id, new Date().toLocaleString(), params.method, params.platform]
        })
    } catch (e) {
        throw e
    }
}

async function get_score(task) {
    try {
        let sql = 'SELECT score, which_month, create_time FROM zmop_score WHERE platform = ? and open_id = ?' +
            ' ORDER BY create_time DESC'
        let rows = await sequelize.query(sql, {
            replacements: [task.platform, task.open_id],
            type: sequelize.QueryTypes.SELECT
        })
        if (rows.length > 0 && utils.test_month(rows[0].create_time)) {
            //  直接通知任务成功
            return rows[0]
        }
        return false
    } catch (e) {
        error('orm-get_score error : ', e)
        return false
    }
}


async function cert_info(order_id) {
    try {
        let sql = 'SELECT cert_no, cert_name FROM zmop_task WHERE success = 1 and order_id = ?'
        let ret = await sequelize.query(sql, {replacements: [order_id], type: sequelize.QueryTypes.SELECT})
        if (ret.length > 0) {
            return ret[0]
        }
        throw new Error('无效的order_id')
    } catch (e) {
        error(e)
        throw e
    }
}


async function check_order_id(order_id) {
    try {
        let sql = 'SELECT order_id FROM zmop_task WHERE order_id = ?'
        let ret = await sequelize.query(sql, {replacements: [order_id], type: sequelize.QueryTypes.SELECT})
        if (ret.length > 0) {
            throw new Error('重复的订单号请退出后重试')
        }
        return true
    } catch (e) {
        throw e
    }
}


async function check_app_key(app_key) {
    try {
        let sql = 'SELECT app_key FROM java_open_platform.customer_product WHERE goods_sn = "012008212235" and app_key = ? and state = 1'
        let ret = await sequelize.query(sql, {replacements: [app_key], type: sequelize.QueryTypes.SELECT})
        if (ret.length == 0) {
            throw new Error('无效的appKey')
        }
    } catch (e) {
        throw e
    }
}

//  该订单号最近一次计费的时间之后24小时不会计费
async function counted(order_id, app_key) {
    try {
        let sql = 'SELECT create_time FROM zmop_bill WHERE app_key = ? and order_id = ? and count = 1 order by create_time DESC LIMIT 1'
        let ret = await sequelize.query(sql, {replacements: [app_key, order_id], type: sequelize.QueryTypes.SELECT})
        if (ret.length > 0) {
            let delta = moment().diff(moment(ret[0].create_time), 'minutes')
            if (delta <= 60 * 24) {
                return ret[0].create_time
            }
        }
        return false
    } catch (e) {
        throw e
    }
}


async function create_task(row) {
    row.create_time = new Date().toLocaleString()
    let ret = await Task.create(row)
    return ret.toJSON()
}

async function update_task(row, order_id) {
    row.finish_time = new Date().toLocaleString()
    if (row.success == 'true') {
        row.success = 1
    } else {
        row.success = -1
    }
    let ret = await Task.update(row, {where: {order_id: order_id, success: 0}})
    if (ret[0] == 0) {
        console.warn('###### 更新任务状态失败 #####\n order_id: ', order_id)
    }
}

async function payload_app_id(platform = 'alipay') {
    try {
        let sql = 'SELECT `app_id`, `platform`, `weight` FROM zmop_alipay_payload WHERE `using`=1 and platform = ?'
        let ret = await sequelize.query(sql, {replacements: [platform], type: sequelize.QueryTypes.SELECT})
        if (ret.length == 0) {
            sql = 'SELECT `app_id`, `platform`, `weight` FROM zmop_alipay_payload WHERE `using`=1'
            return await sequelize.query(sql, {type: sequelize.QueryTypes.SELECT})
        }
        return ret
    } catch (e) {
        error(e)
        throw e
    }
}


//  选择有普惠版权限的app_id
async function payload_brief(method = 'score', admit_score) {
    try {
        let sql = 'SELECT `app_id`, `weight` FROM zmop_brief_payload WHERE `using`=1 and admit_score = ?'
        if (method != 'score') {
            sql = 'SELECT `app_id`, `weight` FROM zmop_brief_payload WHERE `using`=1'
        }
        let ret = await sequelize.query(sql, {replacements: [admit_score], type: sequelize.QueryTypes.SELECT})
        if (ret.length == 0) {
            throw new Error('请选择正确的准入分')
        }
        return ret
    } catch (e) {
        error(e)
        throw e
    }
}

async function update_payload(app_id) {
    try {
        let sql = 'UPDATE zmop_alipay_payload SET `count` = `count` + 1 WHERE `app_id`= ?'
        return await sequelize.query(sql, {
            replacements: [app_id],
            type: sequelize.QueryTypes.UPDATE
        })
    } catch (e) {
        error(e)
        throw e
    }
}

async function company_info(app_key) {
    try {
        let sql = 'SELECT `name`, `company`,`partya` FROM zmop_partner  WHERE `app_key`= ?'
        return await sequelize.query(sql, {
            replacements: [app_key],
            type: sequelize.QueryTypes.SELECT
        })
    } catch (e) {
        error(e)
        throw e
    }
}

//  是否已授权
async function authed(cert_no, platform) {
    try {
        let sql = 'select a.app_id, a.app_key, b.entity, b.platform from zmop_task a join ' +
            '(SELECT `app_id`, `entity`, `platform` FROM zmop_alipay_payload where `using` = 1 and platform = ?)' +
            ' b on a.app_id = b.app_id where a.cert_no = ? group by a.app_id order by create_time'
        return await sequelize.query(sql, {
            replacements: [platform, cert_no],
            type: sequelize.QueryTypes.SELECT
        })
    } catch (e) {
        error(e)
        throw e
    }
}


//  获取任务状态
async function task_state(app_key, order_id) {
    try {
        let sql = 'SELECT `order_id`, `app_key`, `success`, `error_msg` FROM zmop_task WHERE app_key=? and order_id = ?'
        let ret = await sequelize.query(sql, {replacements: [app_key, order_id], type: sequelize.QueryTypes.SELECT})
        if (ret.length == 0) {
            throw new Error('无此订单号')
        }
        return ret[0]
    } catch (e) {
        throw e
    }
}

//获取appkey
async function partner_appKey(order_id) {
    try{
        let sql = 'SELECT `app_key`,`cert_no` FROM zmop_task WHERE order_id=?'
        let ret = await sequelize.query(sql, {replacements:[order_id],type:sequelize.QueryTypes.SELECT})
        if (ret.length == 0){
            throw new Error('无此订单号')
        }
        return ret[0]
    } catch (e) {
        throw e
    }
}


//获取appkey用的通道
async function get_appkey_channel(app_key) {
    try {
        let sql = 'SELECT `channel` FROM zmop_partner  WHERE `app_key`= ?'
        return await sequelize.query(sql, {
            replacements: [app_key],
            type: sequelize.QueryTypes.SELECT
        })
    } catch (e) {
        error(e)
        return []
    }
}

//第三方接入数据
async function insert_task_channel( app_key, orderId, score, cert_no ) {
    try {
        let sql = 'INSERT INTO zmop_bill_score_otherchannel ( app_key, order_id, create_time, score, cert_no  ) VALUES (?,?,?,?,?)'
        await sequelize.query(sql, {
            replacements: [app_key, orderId, new Date().toLocaleString(), score, cert_no]
        })
    } catch (e) {
        error(e)
    }
}

//第三方接入数据
async function insert_other_channel( app_key, orderId, score, cert_no, type, channel, resp ) {
    try {
        let sql = 'INSERT INTO zmop_bill_otherchannel ( app_key, order_id, create_time, score, cert_no, type, channel, resp ) VALUES (?,?,?,?,?,?,?,?)'
        await sequelize.query(sql, {
            replacements: [app_key, orderId, new Date().toLocaleString(), score, cert_no, type, channel, resp]
        })
    } catch (e) {
        error(e)
    }
}


//获取第三方接入数据
async function get_task_channel(orderId) {
    try {
        let sql = 'SELECT `score`,`order_id`,`create_time` FROM zmop_bill_score_otherchannel WHERE order_id=?'
        let rows = await sequelize.query(sql, {
            replacements: [orderId]
        })
        return rows[0]
        // if (rows.length > 0 && utils.test_month(rows[0].create_time)) {
        //     //  直接通知任务成功
        //     return rows[0]
        // }
    } catch (e) {
        error(e)
        throw e
    }
}

//  获取三要素
async function get3ys(order_id) {
    try {
        let sql = 'SELECT open_id, platform, create_time, app_id, cert_no, cert_name, cert_phone FROM zmop_task  WHERE success = 1 and order_id = ?'
        let ret = await sequelize.query(sql, {
            replacements: [order_id,],
            type: sequelize.QueryTypes.SELECT
        })
        if (ret.length == 0) {
            log('API-[ last_task ]: 无此订单号', order_id)
            throw new Error('无此订单号')
        }
        return ret[0]
    } catch (e) {
        error(e)
        throw e
    }
}

// 判断orderid是否为公信宝服务
async function select_crawler_task(order_id) {
    try {
        let sql = 'SELECT orderSn FROM zmop_crawler_task  WHERE status = "success" and orderSn = ?'
        let ret = await sequelize.query(sql, {
            replacements: [order_id],
            type: sequelize.QueryTypes.SELECT
        })
        return ret
    } catch (e) {
        error(e)
        throw e
    }
}

//获取合作方信息
async function selectpartner() {
    try{
        let sql = 'SELECT app_key ,name,phone FROM zmop_partner WHERE env = "pro" '
        let ret = await sequelize.query(sql, {replacements:[],type:sequelize.QueryTypes.SELECT})
        if (ret.length == 0){
            throw new Error('未查询到')
        }
        return ret
    } catch (e) {
        throw e
    }
}

async function selectpartnerratio() {
    try{
        let sql = 'SELECT app_key,channelPC,ratio,ratio_crawler FROM zmop_partner'
        let ret = await sequelize.query(sql, {replacements:[],type:sequelize.QueryTypes.SELECT})
        if (ret.length == 0){
            throw new Error('未查询到')
        }
        return ret
    } catch (e) {
        throw e
    }
}


module.exports.create = create
module.exports.check_order_id = check_order_id
module.exports.check_app_key = check_app_key
module.exports.get_score = get_score
module.exports.cert_info = cert_info
module.exports.create_api_task = create_api_task
module.exports.task = task
module.exports.counted = counted
module.exports.bill_record = bill_record
module.exports.get_auth = get_auth
module.exports.update_task = update_task
module.exports.create_task = create_task
module.exports.task_state = task_state

module.exports.payload_app_id = payload_app_id
module.exports.update_payload = update_payload
module.exports.company_info = company_info
module.exports.authed = authed
module.exports.bill = bill
module.exports.create_watch_list = create_watch_list
module.exports.payload_brief = payload_brief
module.exports.brief_bill = brief_bill
module.exports.brief_bill_record = brief_bill_record
module.exports.partner_appKey = partner_appKey
module.exports.openId = openId
module.exports.selectpartner = selectpartner;


module.exports.get_appkey_channel = get_appkey_channel
module.exports.insert_task_channel = insert_task_channel
module.exports.get_task_channel = get_task_channel
module.exports.get3ys = get3ys
module.exports.select_crawler_task = select_crawler_task
module.exports.insert_other_channel = insert_other_channel
module.exports.selectpartnerratio = selectpartnerratio;