var express = require('express'),
    router = express.Router(),
    rsa = require('../lib/zmop_client/rsa'),
    extend = require('extend'),
    orm = require('../lib/orm'),
    flow = require('../lib/flow'),
    utils = require('../lib/utils'),
    oss = require('../lib/oss-node'),
    pubApi = require('../lib/publicApi'),
    ZmopClient = require('../lib/zmop_client/zmop_client'),
    Zmop = new ZmopClient(),
    moment = require('moment'),
    config = require('config'),
    log = console.log.bind(console),
    warn = console.warn.bind(console),
    error = console.error.bind(console),
    URL = require('url');

const entities = config.get('entities')

let partnerMap = new Map();

getpartner()

async function getpartner() {
    let row = await orm.selectpartnerratio();
    for (let item of row) {
        partnerMap.set(item.app_key, {
            ratio: item.ratio || 1,
            ratio_crawler: item.ratio_crawler || 0,
            channelPC: item.channelPC
        });
        console.log(item.app_key, partnerMap.get(item.app_key));
    }
}


router.use('*', function (req, res, next) {
    let keys = Object.keys(req.query)
    if (keys.length > 0) {
        log('####### REQUEST ######\n [', req.baseUrl, ' ] query: ', req.query)
    }
    keys = Object.keys(req.body)
    if (keys.length > 0) {
        log('####### REQUEST ######\n [', req.baseUrl, ' ] body: ', req.body)
    }
    next()
})

router.post('/refreshpartner', async (req, res) => {
    if (req.body.type == 'refresh' && req.body.keys == 'jd') {
        try {
            await getpartner();
            res.send('success');
        } catch (err) {
            console.error(err);
            res.send("error");
        }
    } else {
        res.statusCode = '404';
        res.send('');
    }
})

router.get('/index', async (req, res) => {
   // pubApi.analysisReq(req);
    try {
        let query = req.query
        if (!query.redirect) {
            throw new Error('参数错误')
        }
        await utils.test_order_id(query.order_id)
        await orm.check_app_key(query.appKey)
        if (query.channel && query.channel == 'partner') {
            return res.redirect(`https://t.51muge.com/zm_crawler/${req.originalUrl.substr(6)}`);
        }
        if (query.channel == 'H5' || query.appKey == 'CD3282798620404AB48EAA5F146E1F71' || query.appKey == '03B5615498F8432D8E9E8D2F1AA0D88B') {
                return res.redirect(`https://t.51muge.com/zm_crawler/${req.originalUrl.substr(6)}`);
        }
        if (query.appKey == '57DAAB1712D3495180D7DAC7D691E916'){
            return res.render('error.html', {error_message: '该产品已下线'})
        }
        let data = {
            cert_no: query.cert_no,
            cert_name: query.cert_name,
            cert_phone: query.cert_phone,
            readonly: query.readonly || 0,
            modify_no: query.modify_no || 0,
            modify_name: query.modify_name || 0,
            modify_phone: query.modify_phone || 0,
            app_key: query.appKey
        }
        //  51公积金管家的3个appKey需要验签
        if (['11E10EC946D8499486584F6E26E96D0F', '5429650395C74BFEA0B058275B1AE517', '2D0650A080644A59A4F56087E34A3983'].includes(query.appKey)) {
            let body = {
                sign: query.sign,
                type: 'zmop',
                params: {
                    appKey: query.appKey,
                    timestamp: query.timestamp,
                    cert_no: query.cert_no,
                    cert_phone: query.cert_phone,
                    token: query.token,
                }
            }
            let verifyRet = await pubApi.signValidityCheck(body)
            if (verifyRet.code != 0) {
                return res.render('error.html', {error_message: verifyRet.msg})
            }
        }
        //  是否脱敏
        if (query.desensitized == 1) {
            data.raw_no = query.cert_no
            data.raw_name = query.cert_name
            data.raw_phone = query.cert_phone
            try {
                data.cert_no = data.cert_no.slice(0, 6) + '**********' + data.cert_no.slice(data.cert_no.length - 2)
            } catch (e) {
                data.cert_no = ''
            }
            try {
                data.cert_name = '*' + data.cert_name.slice(1)
            } catch (e) {
                data.cert_name = ''
            }
            try {
                data.cert_phone = data.cert_phone.slice(0, 3) + '******' + data.cert_phone.slice(data.cert_phone.length - 2)
            } catch (e) {
                data.cert_phone = ''
            }

        }
        delete query.cert_name
        delete query.cert_no
        delete query.cert_phone
        delete query.modify_phone
        delete query.modify_no
        delete query.modify_name
        delete query.readonly
        delete query.desensitized
        data.query = JSON.stringify(query)
        res.render('index.html', data)
    } catch (e) {
        warn(`[${req.originalUrl}-warn]: `, e)
        if (/[a-zA-Z]+/.test(e.message)) {
            return res.render('error.html', {error_message: '系统错误, 请稍后再试'})
        }
        return res.render('error.html', {error_message: e.message})
    }
})

//  channel = 'H5' 获取授权连接
router.post('/auth', async (req, res) => {
    try {
        let body = req.body
        let cert_no = body.cert_no
        let cert_name = body.cert_name
        let order_id = body.order_id
        let appKey = body.appKey
        if (!body.redirect) {
            throw new Error('参数错误')
        }
        if (!body.app_id) {
            return res.sendStatus(400).end()
        }
        await utils.test_order_id(order_id)
        await orm.check_app_key(appKey)
        //  根据身份证号确定是否有本月的
        let row = {
            order_id: order_id,
            app_key: appKey,
            platform: 'zhima',
            cert_no: cert_no,
            cert_name: cert_name,
            cert_phone: body.cert_phone,
            redirect: body.redirect,
            app_id: body.app_id
        }
        await orm.create_task(row)
        //  上传到oss
        let ret = await orm.company_info(appKey)
        let oss_data = protocol(body.app_id, ret[0].company, ret[0].name, ret[0].partya || '杭州惠风网络科技有限公司')
        let oss_key = `protocol/${moment().format('YYYY-MM-DD')}/${order_id}`
        await oss.upload(oss_key, oss_data)

        
        //新增根据appKey判断是否走第三方
        let appKeyInfo = await orm.get_appkey_channel(appKey);
        console.log('auth appKeyInfo', appKeyInfo[0])
        if (appKeyInfo[0] && appKeyInfo[0].channel == 'micai') {
            let returnUrl = `https://t.51gjj.com/zmop/phpcallback?channel=${appKeyInfo[0].channel}&customUrl=${body.customUrl}&redirect=${body.redirect}&orderId=${body.order_id}&extras=${body.extras}&appKey=${appKey}&`;
            let micaiRet = await pubApi.getMicaiUrl(cert_name, cert_no, body.cert_phone, returnUrl);
            if (0 == micaiRet.code) {
                return res.json({ code: 0, auth_url: micaiRet.data.url, channel: 'H5' });
            }
            return res.json({ code: -1, msg: '系统错误，请稍后重试' })
        }
        if (appKeyInfo[0] && appKeyInfo[0].channel == 'lingwa') {
            let returnUrl = `https://t.51gjj.com/zmop/phpcallback?channel=${appKeyInfo[0].channel}&customUrl=${body.customUrl}&redirect=${body.redirect}&orderId=${body.order_id}&extras=${body.extras}&appKey=${appKey}&`;
            let lingWaRet = await pubApi.getLingwaUrl(cert_name, cert_no, body.cert_phone, returnUrl);
            if ('200' == lingWaRet.code) {
                return res.json({ code: 0, auth_url: lingWaRet.body.url, channel: 'H5' });
            }
            return res.json({code: -1, msg: '系统错误，请稍后重试'})
        }

        delete body.cert_no
        delete body.cert_name
        delete body.cert_phone
        delete body.app_id
        //  生成授权连接
        let state = utils.to_base64(JSON.stringify(body))
        let url = Zmop.build_url(row.app_id, cert_no, cert_name, state)
        log(' url : ', url)
        res.json({code: 0, auth_url: url, channel: 'H5'})
        // }
    } catch (e) {
        warn(`[${req.originalUrl}-warn]: `, e)
        if (e.message == '无效的appKey') {
            return res.json({code: -1, msg: '无效的appKey'})
        }
        if (/[a-zA-Z]+/.test(e.message)) {
            return res.json({code: -1, msg: '系统错误, 请稍后再试'})
        }
        return res.json({code: -1, msg: e.message})
    }
})

//  前端展示的协议
router.get('/protocol', async (req, res) => {
    try {
        let ret = await orm.company_info(req.query.app_key)
        let company = ret[0].company
        let name = ret[0].name
        let us = ret[0].partya || '杭州惠风网络科技有限公司'
        if (req.query.app_id == '2018051160085345' && us == '杭州惠风网络科技有限公司') {
            us = ''
        }
        log('company: ', ret)
        res.render('protocol.html', {
            entity: entities[req.query.app_id],
            company: company,
            name: name,
            us: us
        })
    } catch (e) {
        error('protocol: ', e)
        res.sendStatus(400)
    }
})

//  获取app_id
router.post('/app_id', async (req, res) => {
    try {
        let body = req.body
        let app_id = null
        let platform = ''
        if (body.channel == 'H5') {
            platform = 'zhima'
        } else {
            platform = 'alipay'
        }
        //  先判断之前是否有授权成功的app_id
        let rows = await orm.authed(body.cert_no, platform)
        log(rows)
        if (rows.length == 0) {
            //  根据权重选择app_id
            log('######## RANDOM APP_ID ########')
            let app_ids = await orm.payload_app_id(platform)
            app_id = utils.load_balance(app_ids)
        } else {
            app_id = rows[0].app_id
        }
        log('app_id: ', app_id)
        res.json({code: 0, data: app_id})
    } catch (e) {
        warn(`[${req.originalUrl}-warn]: `, e)
        if (e.message == '无效的appKey') {
            return res.json({code: -1, msg: '无效的appKey'})
        }
        if (/[a-zA-Z]+/.test(e.message)) {
            return res.json({code: -1, msg: '系统错误, 请稍后再试'})
        }
        return res.json({code: -1, msg: e.message})
    }
})

//  用户授权完成之后, 芝麻信用的跳转页面
router.get('/result', async (req, res) => {
    if (!req.query.params || !req.query.sign) {
        return res.render('error.html', {error_message: '参数错误'})
    }
    let custom_result = {}
    try {
        let decrypted = rsa.RSADecrypt(req.query.params)
        let params = rsa.str2params(decrypted)
        if (rsa.verify(req.query.sign, decrypted, params.app_id)) {
            let state = JSON.parse(utils.from_base64(params.state))
            log('state', state)
            log('params: ', params)
            let row = {
                success: params.success,
                error_msg: params.error_message,
                open_id: params.open_id
            }
            if (params.success == 'true'){
                let task = {open_id:params.open_id, platform:'zhima', app_id:params.app_id};
                let data = await flow.save_score(task)
                log('#####  最新的数据: #####', data)
            }
            //  通知合作方授权结果
            await flow.notify_result(state, params.success, params.error_message)
            await orm.update_task(row, state.order_id)
            //  有customUrl直接重定向到合作方页面
            if (state.customUrl) {
                try {
                    let _url = decodeURIComponent(state.customUrl).split('?')
                    let _p = {
                        order_id: state.order_id,
                        status: 'true' == params.success ? 'success' : 'fail',
                        msg: params.error_message,
                    }
                    if (state.extras) {
                        _p.extras = state.extras
                    }
                    let url = ''
                    if (_url.length == 2) {
                        url = `${_url[0]}?${rsa.params2str(_p)}&${_url[1]}`
                    } else {
                        url = `${_url[0]}?${rsa.params2str(_p)}`
                    }
                    console.log('customUrl: ', url)
                    return res.redirect(url)
                } catch (e) {
                }
            }
            console.log('params.app_id.length', params.app_id.length)
            res.render('result.html', {success: params.success, error_msg: params.error_message})
        } else {
            // 验签失败
            throw new Error('验签失败')
        }
    } catch (e) {
        error(`[/zmop/result-error]: `, e)
        return res.render('result.html', {error_msg: '系统错误, 请稍后再试'})
    }
})

router.get('/phpcallback', async (req, res) => {

    try {

        //新增lingwa渠道回调
        if ('lingwa' == req.query.channel) {
            let params = req.query;
            let row = {
                success: 'fail',
                error_msg: '操作失败',
                open_id: 'lingwa'
            };
            if ('SUCCESS' == params.error_code) {
                row.success = 'true';
                row.error_msg = params.error_message;
            }

            console.log(params.orderId, row)
            let state = { order_id: params.orderId, redirect: params.redirect }
            if ('undefined' != params.extras) {
                state.extras = params.extras;
            }
            await flow.notify_result(state, row.success, row.error_msg)
            await orm.update_task(row, state.order_id)
            // await orm.insert_task_channel(params.appKey, state.order_id, scoreRet.data.zmf, scoreRet.data.card)
            let _url = decodeURIComponent(params.customUrl).split('?')

            if ('undefined' == params.customUrl) {
                return res.render('result.html', { success: row.success ? 'success' : 'fail', error_msg: row.error_msg })
            }
            let _p = {
                order_id: state.order_id,
                status: '1' == row.success ? 'success' : 'fail',
                msg: encodeURIComponent(row.error_msg),
            }
            if (state.extras) {
                _p.extras = state.extras
            }
            let url = ''
            if (_url.length == 2) {
                url = `${_url[0]}?${rsa.params2str(_p)}&${_url[1]}`
            } else {
                url = `${_url[0]}?${rsa.params2str(_p)}`
            }
            console.log('[/zmop/phpcallback]customUrl: ', url)
            return res.redirect(url)
        }

        let str = URL.parse(req.url).query.split('param=');
        let param = str[str.length - 1];
        console.log('[/zmop/phpcallback] param: ', param)
        let params = req.query;
        let scoreRet = await pubApi.rc4Deciper(param);
        let row = {
            success: 'fail',
            error_msg: '操作失败',
            open_id: 'micai'
        };
        if('0' == scoreRet.code) {
            row = {
                success: 'true',
                error_msg: '操作成功',
                open_id: 'micai'
            }
        }
        console.log(row)
        let state = {order_id: params.orderId, redirect: params.redirect}
        if('undefined' != params.extras) {
            state.extras = params.extras;
        }
        await flow.notify_result(state, row.success, row.error_msg)
        await orm.update_task(row, state.order_id)
        orm.insert_other_channel(params.appKey, state.order_id, '', '', 'score', req.query.channel, JSON.stringify(scoreRet));
        await orm.insert_task_channel(params.appKey, state.order_id, scoreRet.data.zmf, scoreRet.data.card)
        let _url = decodeURIComponent(params.customUrl).split('?')
        console.log('row success', row.success)
        console.log('row msg', row.error_msg)
        if ('undefined' == params.customUrl) {
            return res.render('result.html', {success: row.success ? 'success' : 'fail', error_msg: row.error_msg})
        }
        let _p = {
            order_id: state.order_id,
            status: '1' == row.success ? 'success' : 'fail',
            msg: encodeURIComponent(row.error_msg),
        }
        if (state.extras) {
            _p.extras = state.extras
        }
        let url = ''
        if (_url.length == 2) {
            url = `${_url[0]}?${rsa.params2str(_p)}&${_url[1]}`
        } else {
            url = `${_url[0]}?${rsa.params2str(_p)}`
        }
        console.log('[/zmop/phpcallback]customUrl: ', url)
        return res.redirect(url)
        // return res.render('result.html', {error_msg: '系统错误, 请稍后再试'})
    } catch (error) {
        console.error(`[/zmop/phpcallback-error]: `, error)
        return res.render('result.html', {error_msg: '系统错误, 请稍后再试'})
    }
    
})


router.post('/getToken', async (req, res) => {
    try {
        let ret = await pubApi.getToken(req.body)
        res.send(ret)
    } catch (e) {
        res.send({code: -1, msg: '系统错误, 请稍后再试'})
    }
})

//  查询任务状态, 优化app授权的用户体验
router.post('/task', async (req, res) => {
    try {
        let ret = await orm.task_state(req.body.appKey, req.body.order_id)
        log('#####  TASK  #####: ', JSON.stringify(ret))
        res.send({code: 0, data: ret})
    } catch (e) {
        res.send({code: -1, msg: e.message || '系统错误, 请稍后再试'})
    }
})

// //  build entry url
// //  http://ti.51gjj.com:10030/zmop/result?params=LDoyXM2%2BsqVI5kGiCtBykYDOcau7UGpjCQxr96mTqkzDzQXgHGf0GQEzFV1rzPBnGEa%2FR0vyBdHq9eSoKfyqPLL1AEkDIIuEwmre7H8%2BMBmIb9Wy8Ghh50qBRz%2FM8%2Bw2r%2B5NkIEyBzYxW9mIefjniDShDcZnjy%2BWdu6fkqy%2FjbsJ%2BVMqDtKksLV%2BlBOU9l6F1LXGfqRWs6IXLqeVI5ubCtzYyttLYkiiD4uyZs1p23aa%2B8G1oDeRTkEtWvVCUrkbvLv4gpzeXyQKUrX4Fwi4a3uAexDE2b9W2oKoiRUu%2BqsAfBvzh9BGpGqljZiCxm9Q%2FanI8P%2FFDzx86%2BqDW1ThWw%3D%3D&sign=HWw8Djzt0%2BOgS3N4WSWOwOgMlB55Gk7z5EFA0QESqnZEOkrTG6ictgOwCoLfEo8QtIKhvQMEN1EGSDQHsg%2F01lEekJuWrKrJgIOa4XzFL66%2BM7F89K1E7yUShcYJldfkL7Gnwzw8%2FRLJibVXmLfQ8s9q7l10rxravf%2BWmECAmRE%3D
let app_id = config.get('zmop_app_id')
log('app_id: ', app_id, entities[app_id])
// let order_id = ZmopClient.build_transaction_id()
// let appKey = '39DB28E81AFC4B99B2E9A9E6AF074FB6'
// let redirect = encodeURIComponent('https://www.baidu.com')
// let extras = encodeURIComponent(JSON.stringify({user_id: 3214565}))
// log(`${config.host}:10030/zmop/index/?appKey=${appKey}&order_id=${order_id}&redirect=${redirect}&extras=${extras}`)
//  https://ti.51gjj.com/zmop/index/?appKey=421ADA909326905ECD114935F1CFB83C&order_id=201805230851240149trGspFQ2dOO0Qk&redirect=https%3A%2F%2Fwww.baidu.com&extras=%7B%22user_id%22%3A3214565%7D&cert_no=330182199401213216&cert_name=%E9%BB%84%E7%82%9C&cert_phone=13107706693
//  https://t.51gjj.com/zmop/index/?appKey=421ADA909326905ECD114935F1CFB83C&order_id=201805230851240149vrGspFQ2dOO0Qk&redirect=https%3A%2F%2Fwww.baidu.com&extras=%7B%22user_id%22%3A3214565%7D&channel=H5&cert_no=330182199401213216&cert_name=%E9%BB%84%E7%82%9C&cert_phone=13107706693&customUrl=http%3A%2F%2Fzrb-t211.zhenrongbao.com%2Fi_pdl%2Ftjy%2FgetZmScore

//  动态生成协议内容
function protocol(app_id, company, name, us) {
    log('######## PROTOCOL ########: ', app_id, company, name, us)
    if (!us) {
        us = '杭州惠风网络科技有限公司'
    }
    if (app_id == '2018051160085345' && us == '杭州惠风网络科技有限公司') {
        us = ''
    }
    return `用户授权服务协议
  【重要提示】：
   为了保障您的合法权益，请您务必审慎阅读、充分理解本授权书之条款、承诺，特别是涉及被授权方（包括但不限于${us}、 ${entities[app_id]}及相关合作方、关联方等，下同）责任的条款，或限制您权利的条款，或加粗条款
        除非您已阅读、接受并自愿遵守本授权书所有的条款，否则您无权使用被授权方提供的查询服务。您的申请、使用或登录等行为，亦或点击、勾选“确认”、“同意”、“申请”或“查询”按钮，亦或填写资料申请服务等，即表明您对本授权书含义及法律后果的知悉和全面理解，并自愿签署并遵照执行。
   【致被授权方】：
        （本人拟向__${company}___（下简称“${name}”）申请其提供的服务（包括但不限于融资服务、借贷咨询、借贷方案推荐、助贷服务、分期服务、委托服务、代办服务等，下同），需查询本人的芝麻信用数据。现本人不可撤销的授权：1）授权被授权方收集、存储、使用本人提交或本人授权${name}提交的姓名、身份证号码、手机号码等个人资料；2）授权被授权方根据芝麻信用管理有限公司（下简称“芝麻信用公司”）的规则向芝麻信用公司发起登录、收集、查询等服务请求，代为查询、收集、存储芝麻信用公司反馈的本人芝麻信用数据，并授权被授权方传输给${name}用于存储、分析使用、评估本人情况；必要时授权${name}可同时向本人所申请服务之实际提供方反馈本人之个人信息及评估结果。本人知悉，本授权书包含了被授权方收集、使用、查询、存储和传输本人芝麻信用数据的条款，并接受被授权方及${name}的规则/评估体系/评估方法。
        就上述授权，本人同时确认并承诺如下：
        1. 本人知悉，向被授权方/${name}提供的本人之个人信息（包括但不限于姓名、手机号码、身份证号码、芝麻信用数据等，下同）属于本人重要的个人信息，本人同意并不可撤销地授权被授权方在保证本人信息安全的前提下，存储、使用本人之个人信息，并仅向本人授权的相关方提供，因被授权方提供该等服务所得收益归被授权方所有。除前述情况及因国家机关、生效判决等强制性要求而必须提供外，被授权方不应将本人之个人信息提供给任何未经本人授权的其他机构或平台。
        2. 本人知悉，被授权方会采用行业通行安全技术标准保护本人之个人信息，以防止个人信息及数据丢失、被盗用或遭窜改，除非遇到不可抗力（包括但不限于黑客攻击、系统故障、软硬件故障、自然灾害、政策变动等）的影响。
        3. 本授权委托书系本人做出的单方承诺，效力具有独立性，不因其他合同的任何条款无效而失效。
        4. 以上授权期限为本人作出本授权承诺之日起至本授权委托书约定事项完成之日止。
        5. 若本人与被授权方发生任何纠纷或争议，首先应友好协商解决；协商不成的，本人同意将纠纷或争议提交杭州仲裁委员会仲裁解决。本授权书的成立、生效、履行、解释及纠纷解决，适用中华人民共和国大陆地区法律（不包括冲突法）。
        6. 本人已知悉本授权书所有内容（特别是加粗字体内容）的意义以及由此产生的法律后果，自愿作出上述授权，本授权书是本人真实的意思表示，本人同意承担由此带来的一切法律后果。
        7. 本授权书自填写个人资料，或点击、勾选“确认”、“同意”、“申请”或“查询”等按钮之日起生效。
        特此授权。
`
}

module.exports = router;
