const rp = require('request-promise'),
    moment = require('moment'),
    fs = require('fs'),
    rsa = require('./rsa'),
    orm = require('./orm'),
    extend = require('extend'),
    config = require('config'),
    log = console.log.bind(console),
    error = console.error.bind(console)


// const api_host = "https://zmopenapi.zmxy.com.cn/openapi.do"  // 芝麻信用网关地址
// const private_key_file = "d:\\keys\\private_key.pem"  // 商户私钥文件路径
// const zmPublic_key_file = "d:\\keys\\public_key.pem"  // 芝麻公钥文件路径
// const app_id = "1000***"  // 芝麻分配给商户的 appId

//  params= URLEncode(Base64(RSAEncrypt(param1=URLEncode(param1value)&param2=URLEncode(param2value))))

class ZmopClient {
    constructor() {
        this.zmop_host = 'https://zmopenapi.zmxy.com.cn/openapi.do'
        this.data = {
            app_id: config.get("zmop_app_id"),
            charset: 'UTF-8',
            version: '1.0',
            platform: 'zmop',
        }
    }

    prepare(method, params) {
        this.data.method = method
        let extended = {
            method: method,
            params: rsa.RSAEncrypt(params),
            sign: rsa.sign(params)
        }

        return extend(extended, this.data)
    }

    build_url(certNo, name, extras) {
        try {
            log(certNo)
            log(extras)

            let params = {
                identity_type: 2,
                identity_param: {"certNo": certNo.toString().toUpperCase(), "name": name, "certType": "IDENTITY_CARD"},
                biz_params: {"auth_code": "M_H5", "channelType": "app", "state": extras}
            }
            let method = 'zhima.auth.info.authorize'
            return this.zmop_host + '?' + rsa.params2str(this.prepare(method, params))
        } catch (e) {
            error(e)
            throw e
        }
    }

    //  查看是否授权
    async authed(certNo, name) {
        try {
            let method = 'zhima.auth.info.authquery'
            // let params = {
            //     auth_category: 'C2B',
            //     identity_type: '0',
            //     identity_param: {"openId": "268801234567890123456"}
            // }
            //使用身份证和姓名
            let params = {
                auth_category: 'C2B',
                identity_type: '2',
                identity_param: {"certNo": certNo.toString().toUpperCase(), "name": name, "certType": "IDENTITY_CARD"}
            }
            let resp = await rp.post({
                url: this.zmop_host,
                json: true,
                form: this.prepare(method, params)
            })
            if (resp.encrypted) {
                let decrypted_res = rsa.RSADecrypt(resp.biz_response)
                if (rsa.verify(resp.biz_response_sign, decrypted_res)) {
                    return decrypted_res
                } else {
                    throw new Error('api-authed 验签失败 resp')
                }
            } else {
                return resp
            }
        } catch (e) {
            throw e
        }

    }

    async watch_list(open_id) {
        let retry = 0
        let self = this

        async function get(transaction_id) {
            try {
                let method = 'zhima.credit.watchlistii.get'
                let params = {
                    transaction_id: transaction_id,
                    product_code: 'w1010100100000000022',
                    open_id: open_id
                }
                let resp = await rp.post({
                    url: self.zmop_host,
                    json: true,
                    form: self.prepare(method, params)
                })
                let row = {
                    transaction_id: transaction_id,
                    form_data: JSON.stringify(resp),
                    open_id: open_id,
                    method: 'watch_list'
                }
                log('zmop_score resp: ', resp)
                await orm.create_api_task(row)
                if (resp.encrypted) {
                    let decrypted_res = rsa.RSADecrypt(resp.biz_response)
                    if (rsa.verify(resp.biz_response_sign, decrypted_res)) {
                        return JSON.parse(decrypted_res)
                    } else {
                        error('api-score 验签失败: ', decrypted_res)
                        throw new Error('api-score 验签失败')
                    }
                } else {
                    let biz_response = JSON.parse(resp.biz_response)
                    //{ encrypted: false, biz_response: '{"success":false,"error_code":"ZMCSP.zm_account_not_existed","error_message":"芝麻账户不存在"}' }
                    if (biz_response.error_code == 'ZMCREDIT.transaction_id_repeat' && retry < 3) {
                        retry++
                        let transaction_id = ZmopClient.build_transaction_id()
                        return await get(open_id, transaction_id)
                    } else {
                        return biz_response
                    }
                }
            } catch (e) {
                throw e
            }
        }

        let transaction_id = ZmopClient.build_transaction_id()
        return await get(transaction_id)
    }

    //  查询芝麻分接口
    async score(open_id) {
        let retry = 0
        let self = this
        async function get(transaction_id) {
            try {
                let method = 'zhima.credit.score.get'
                let params = {
                    transaction_id: transaction_id,
                    product_code: 'w1010100100000000001',
                    open_id: open_id
                }
                let resp = await rp.post({
                    url: self.zmop_host,
                    json: true,
                    form: self.prepare(method, params)
                })
                let row = {
                    transaction_id: transaction_id,
                    form_data: JSON.stringify(resp),
                    open_id: open_id,
                    method: 'score'
                }
                log('zmop_score resp: ', resp)
                await orm.create_api_task(row)
                if (resp.encrypted) {
                    let decrypted_res = rsa.RSADecrypt(resp.biz_response)
                    if (rsa.verify(resp.biz_response_sign, decrypted_res)) {
                        return JSON.parse(decrypted_res)
                    } else {
                        error('api-score 验签失败: ', decrypted_res)
                        throw new Error('api-score 验签失败')
                    }
                } else {
                    let biz_response = JSON.parse(resp.biz_response)
                    //{ encrypted: false, biz_response: '{"success":false,"error_code":"ZMCSP.zm_account_not_existed","error_message":"芝麻账户不存在"}' }
                    if (biz_response.error_code == 'ZMCREDIT.transaction_id_repeat' && retry < 3) {
                        retry++
                        let transaction_id = ZmopClient.build_transaction_id()
                        return await get(open_id, transaction_id)
                    } else {
                        return biz_response
                    }
                }
            } catch (e) {
                throw e
            }
        }

        let transaction_id = ZmopClient.build_transaction_id()
        return await get(transaction_id)
    }

    static
    build_transaction_id() {
        let t = moment().format('YYYYMMDDHHmmssSSS')
        let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
        while (t.length < 32) {
            t += str[Math.round(Math.random() * (str.length - 1))]
        }
        return t
    }
}

// let t = ZmopClient.build_transaction_id()
// let open_id = '268806822853700342467205358'
// let zmop = new ZmopClient()
// console.log(zmop.build_url('330182199401213216', '黄炜'))

module.exports = ZmopClient

