const ServiceBase = require("../sve.base");
var settings = require("../../../config/settings");
const moment = require('moment');
const system = require("../../system");
const md5 = require("MD5");

class EntcontractService extends ServiceBase {
    constructor() {
        super(ServiceBase.getDaoName(EntcontractService));
        this.enttemplateSve = system.getObject("service.enttemplateSve");
        this.entcompanyDao = system.getObject("db.entcompanyDao");
        this.usereaccountDao = system.getObject("db.usereaccountDao");
        this.ecompanybusiDao = system.getObject("db.ecompanybusiDao");
        this.utilesignbaoSve = system.getObject("service.utilesignbaoSve");
        this.userDao = system.getObject("db.userDao");
        this.esealSve = system.getObject("service.esealSve");
        this.ejobapplySve = system.getObject("service.ejobapplySve");
        this.restClient = system.getObject("util.restClient");
        this.yzmerchantsignedDao = system.getObject("db.yzmerchantsignedDao");
        this.URL = "http://39.106.185.66:8000/merchant/busi/reg";
        this.YZKEY = "4a112ce87c38464d8d454caf23b7b31f"
    }

    async autoSign(params) {
        var ecid = params.ecid;
        var unionId = params.appId + "_" + params.userId;
        // enttemplate 模板查询
        var enttemplate = await this.enttemplateSve.findById(ecid);
        // entcompany
        var entcompany = await this.entcompanyDao.findById(enttemplate.entcompany_id);
        // p_user
        var user = await this.userDao.findOne({
            unionId: unionId,
        });

        if (!user) {
            user = await this.userDao.create({
                appkey: params.appId,
                unionId: unionId,
                userId3rd: params.userId,
                userName: params.idName,
                mobile: params.mobile,
                utype: 0,
            });
        }

        // p_user_eaccount
        var eaccount = await this.usereaccountDao.findOne({
            user_id: user.id,
            personsSign: params.idNo,
        }) || {};

        var isNeedCreate = !eaccount.eaccountid || eaccount.userName != params.idName || eaccount.mobile != params.mobile || eaccount.bankno != params.bankno;

        eaccount.user_id = user.id;
        eaccount.userName = params.idName;
        eaccount.mobile = params.mobile;
        eaccount.bankno = params.bankno;
        eaccount.personsSign = params.idNo;
        if (eaccount.id) {
            await eaccount.save();
        } else {
            eaccount = await this.usereaccountDao.create(eaccount);
        }

        // c_entcontract
        var entcontract = await this.dao.findOne({
            eflowstatus: '2',
            usereaccount_id: eaccount.id,
            enttemplate_id: ecid,
        });

        if (entcontract) {
            return this.returnjson(0, "用户已经签约，请不要重复签约");
        }

        // e签宝流程
        if (isNeedCreate) {
            var bankthreeParams = {
                name: eaccount.userName,
                idno: eaccount.personsSign,
                cardno: eaccount.bankno
            };
            var threeResult = await this.utilesignbaoSve.bankthree(bankthreeParams, "bankinfoAuth");
            console.log("threeResult-----------------------------", threeResult);
            if (!threeResult || threeResult.code == -120) {
                return this.returnjson(-1, "银行三要素（姓名、身份证、银行卡号）验证失败");
            }
            if (threeResult.code == -110) {
                return this.returnjson(-1, "银行三要素验证失败");
            }

            var uidStr = await this.getUidStr(8, 36);
            var thirdId = enttemplate.id + "_" + eaccount.id + uidStr;

            //2.创建e签宝account 5.2.1 , 创建后save()
            var params = {
                thirdId: thirdId,
                name: eaccount.userName,
                idNo: eaccount.personsSign,
                idType: 19,
                mobile: eaccount.mobile
            };
            var getAccount = await this.utilesignbaoSve.createAccountId(params, "econtractSve");
            if (getAccount && getAccount.code == 1 && getAccount.data) {
                eaccount.eaccountid = getAccount.data.accountId;
                await eaccount.save();
            } else {
                return this.returnjson(-1, "账户创建失败");
            }
        }

        // 3.设置静默签署授权 5.2.5
        if (!eaccount.isGrantAuto) {
            var paramsGrant = {
                grantAccountId: eaccount.eaccountid
            };
            var grantAuto = await this.utilesignbaoSve.grantAuthorization(paramsGrant, "econtractSve");
            if (grantAuto.code != 1) {
                return this.returnjson(-1, "静默签署设置失败");
            }
            eaccount.isGrantAuto = true;
            await eaccount.save();
        }

        // 创建合同
        entcontract = {
            name: entcompany.name,
            eflowstatusname: "签约中",
            eflowstatus: "1",
            user_id: eaccount.user_id,
            usereaccount_id: eaccount.id,
            enttemplate_id: enttemplate.id,
            entcompany_id: entcompany.id,
        };
        entcontract = await this.create(entcontract);
        var sealId = entcompany.sealId;
        let today = new Date().Format("yyyy") + "年" + new Date().Format("MM") + "月" + new Date().Format("dd") + "日";
        var signParams = {
            templateId: enttemplate.templateid, //模板id，由创建模板接口调用返回的templateId 必填
            name: enttemplate.name, //合同模板名称 必填
            simpleFormFields: {
                nameA: params.name, //甲方 必填
                addressA: params.addr, //甲方地址
                representA: params.legal,//甲方法定代表人
                agentA: params.contactName,//甲方联系人
                agentMobileA: params.contactMobile,//甲方 联系电话

                nameB: eaccount.userName, //乙方 必填
                addressB: entcompany.addr, //乙方 地址
                representB: entcompany.legal,//乙方 法定代表人
                agentB: entcompany.contactName,//乙方 联系人
                agentMobileB: eaccount.mobile,//乙方 联系电话

                bankNameB: entcompany.bankAccount,//账户名称
                bank: entcompany.bankName,//开户行
                bankNumB: entcompany.bankNo,//账号

                signDate: today,//签约时间
                signDateA: today, //甲方签约日期 必填
                signDateB: today //乙方签约日期 必填
            }
        };
        var ebaoAccountId = eaccount.eaccountid; //签署人账户id-- 必填
        var thirdOrderNo = entcontract.id; //第三方流水号，通知回调使用---选填
        var eBaoRedirectBossUrl = "";
        var tt = await this.utilesignbaoSve.userAutoSignContractNoTemplate(signParams, ebaoAccountId, thirdOrderNo, eBaoRedirectBossUrl, "econtractSve", sealId);
        if (tt && tt.data && tt.code == 1) {
            entcontract.eflowid = tt.data.flowId;
            entcontract.edocid = tt.data.docId;
            entcontract.eflowstatus = '2';
            entcontract.eflowstatusname = "已完成";

            var signTime = new Date();
            entcontract.completed_at = signTime;
            entcontract.begin_at = signTime;
            var end_at = new Date();
            end_at.setFullYear(end_at.getFullYear() + 1);
            entcontract.end_at = end_at;

            await entcontract.save();
            // this.syncSign(entcontract.id);
            return await this.createMerchant(params);
            // return this.returnjson(0, "success", {
            //     contractId: entcontract.id
            // });
        }
        return this.returnjson(-1, tt.message || "签约失败", tt.code);
    }

    async createMerchant(params) {
        var data = {
            appId: "1202849621743763458",
            mchtId: "1202848945651318786",
            type: "0",// 类型 0 一般纳税人 1 小规模纳税人
            companyName: params.name,//商户名称
            mobile: params.contactMobile,//手机号
            mainId: "67731504",//代征主体 67731101
            signedName: params.name, //合同名称 使用商户名称
            beginTime: moment().format("YYYY-MM-DD"), //当前时间, //  签约开始时间
            invalidTime: moment().add(2, 'y').format("YYYY-MM-DD"), // 签约失效时间
            completeTime: moment().format("YYYY-MM-DD"), //  签约完成时间 取当前时间
            incomeCompany: "0", // 个税来源 0 个税向个人收 1 个税向企业收
            addedCollectType: "0", //  服务费PLUS收取类型, 0 个人收 1 企业收
            addedValueRate: 6.5, //    服务费PLUS费率(%)
            serviceCollectType: "0", //  服务费收取类型, 0 个人收 1 企业收
            serviceRate: '0.0',    //服务费率(%)
            operatingCost: '0.0', //  核定成本费用率(%)
            taxChargeMode: "0", //  个税计费模式 0 按月，1 按年
            signType: 'MD5',
            nonceStr: "1398243242129742"
        };
        var signArr = [];
        var keys = Object.keys(data).sort();
        for (var i = 0; i < keys.length; i++) {
            var k = keys[i];
            var v = data[k];
            signArr.push(k + "=" + v);
        }
        var signStr = signArr.join("&") + "&key=" + this.YZKEY;
        data.sign = md5(signStr).toUpperCase();
        data.bizContent = [
            {
                "quickDeductionFactor": 0,
                "minValue": 0,
                "rate": 0,
                "maxValue": 3000000
            },
            {
                "quickDeductionFactor": 0,
                "minValue": 3000001,
                "rate": 1.5,
                "maxValue": 10000000
            },
            {
                "quickDeductionFactor": 0,
                "minValue": 10000001,
                "rate": 4.86,
                "maxValue": 214748364700
            }
        ];
        var rtn = null;
        try {
            rtn = await this.restClient.execPost(data, this.URL);
            if (rtn.stdout == null || rtn.stdout == "" || rtn.stdout == "undefined") {
                result.errCode = -100;
                result.code = -100;
                result.message = "请求结果返回为空";
                return result;
            }

            var erchants = await this.yzmerchantsignedDao.findOne({
                companyName: params.name,
            });
            var reso = JSON.parse(rtn.stdout);
            if (!erchants) {
                this.yzmerchantsignedDao.create({
                    companyName: params.name,
                    appId: reso.data.appId,
                    mchtId: reso.data.mchtId,
                    mainId: reso.data.mainId,
                    secret: reso.data.secret,
                });
            }

            return reso;
        } catch (e) {
            console.log(e.stack);
            result.errCode = -200;
            result.code = -200;
            result.message = "操作异常";
            return result;
        }
    }

    async autoSignToPer(params) {
        var ecid = params.ecid;

        var unionId = params.appId + "_" + params.userId;
        // ecid enttemplate
        var enttemplate = await this.enttemplateSve.findById(ecid);

        // entcompany
        var entcompany = await this.entcompanyDao.findById(enttemplate.entcompany_id);

        // p_user
        var user = await this.userDao.findOne({
            unionId: unionId,
        });
        if (!user) {
            user = await this.userDao.create({
                appkey: params.appId,
                unionId: unionId,
                userId3rd: params.userId,
                userName: params.idName,
                mobile: params.mobile,
                utype: 0,
            });
        }

        // p_user_eaccount
        var eaccount = await this.usereaccountDao.findOne({
            user_id: user.id,
            personsSign: params.idNo,
        }) || {};

        var isNeedCreate = !eaccount.eaccountid || eaccount.userName != params.idName || eaccount.mobile != params.mobile;

        eaccount.user_id = user.id;
        eaccount.userName = params.idName;
        eaccount.mobile = params.mobile;
        eaccount.personsSign = params.idNo;
        if (eaccount.id) {
            await eaccount.save();
        } else {
            eaccount = await this.usereaccountDao.create(eaccount);
        }

        // c_entcontract
        var entcontract = await this.dao.findOne({
            eflowstatus: '2',
            usereaccount_id: eaccount.id,
            enttemplate_id: ecid,
        });

        if (entcontract) {
            return this.returnjson(0, "用户已经签约", {
                contractId: entcontract.id
            });
        }

        // e签宝流程
        if (isNeedCreate) {
            var uidStr = await this.getUidStr(8, 36);
            var thirdId = enttemplate.id + "_" + eaccount.id + uidStr;

            //2.创建e签宝account 5.2.1 , 创建后save()
            var params = {
                thirdId: thirdId,
                name: eaccount.userName,
                idNo: eaccount.personsSign,
                idType: 19,
                mobile: eaccount.mobile
            };
            var getAccount = await this.utilesignbaoSve.createAccountId(params, "econtractSve");
            if (getAccount && getAccount.code == 1 && getAccount.data) {
                eaccount.eaccountid = getAccount.data.accountId;
                await eaccount.save();
            } else {
                return this.returnjson(-1, "账户创建失败");
            }
        }

        // 3.设置静默签署授权 5.2.5
        if (!eaccount.isGrantAuto) {
            var paramsGrant = {
                grantAccountId: eaccount.eaccountid
            };
            var grantAuto = await this.utilesignbaoSve.grantAuthorization(paramsGrant, "econtractSve");
            if (grantAuto.code != 1) {
                return this.returnjson(-1, "静默签署设置失败");
            }
            eaccount.isGrantAuto = true;
            await eaccount.save();
        }

        // 创建合同   fileurl、esignUrl 怎么赋值????????????
        entcontract = {
            name: enttemplate.name,
            eflowstatusname: "签约中",
            eflowstatus: "1",
            user_id: eaccount.user_id,
            usereaccount_id: eaccount.id,
            enttemplate_id: enttemplate.id,
            entcompany_id: enttemplate.id,
        };
        entcontract = await this.create(entcontract);

        var sealId = entcompany.sealId;
        // var eseal = await this.esealSve.findOne({
        //     nameA: enttemplate.nameA
        // });
        // // 生产环境需要打开
        // if (!eseal) {
        //     // var accountId = "";  // 测试
        //
        //     var rs = await this.utilesignbaoSve.creatEntSignet(settings.apiconfig.companyAccountId(), enttemplate.nameA + "alias", enttemplate.nameA, "", "", "econtractSve");
        //     // var rs = await this.utilesignbaoSve.creatEntSignet("740b19e0799a4d7abacfa1a31fb72b1e", enttemplate.nameA + "alias", enttemplate.nameA, "", "", "econtractSve");
        //     if (rs && rs.code == 1) {
        //         sealId = rs.data.sealId;
        //         await this.esealSve.create({
        //             nameA: enttemplate.nameA,
        //             sealId: sealId,
        //         });
        //     } else {
        //         return this.returnjson(-1, "生成印章错误");
        //     }
        // } else {
        //     sealId = eseal.sealId;
        // }
        let today = new Date().Format("yyyy") + "年" + new Date().Format("MM") + "月" + new Date().Format("dd") + "日";
        var signParams = {
            templateId: enttemplate.templateid, //模板id，由创建模板接口调用返回的templateId 必填
            name: entcompany.name, //合同模板名称 必填
            simpleFormFields: {
                nameA: entcompany.legal, //甲方 必填
                nameB: eaccount.userName, //乙方 必填
                unit: entcompany.name, //合作单位（国美） 必填---------------------------超出长度风险---目前不知多少长度
                signDateA: today, //甲方签约日期 必填
                signDateB: today //乙方签约日期 必填
            }
        };
        var ebaoAccountId = eaccount.eaccountid; //签署人账户id-- 必填
        var thirdOrderNo = entcontract.id; //第三方流水号，通知回调使用---选填
        var eBaoRedirectBossUrl = "";

        var tt = await this.utilesignbaoSve.userAutoSignContractNoTemplate(signParams, ebaoAccountId, thirdOrderNo, eBaoRedirectBossUrl, "econtractSve", sealId);
        if (tt && tt.data && tt.code == 1) {
            entcontract.eflowid = tt.data.flowId;
            entcontract.edocid = tt.data.docId;
            entcontract.eflowstatus = '2';
            entcontract.eflowstatusname = "已完成";

            var signTime = new Date();
            entcontract.completed_at = signTime;
            entcontract.begin_at = signTime;
            var end_at = new Date();
            end_at.setFullYear(end_at.getFullYear() + 1);
            entcontract.end_at = end_at;

            await entcontract.save();
            //this.syncSign(entcontract.id);
            return this.returnjson(0, "success", {
                contractId: entcontract.id
            });
        }
        return this.returnjson(-1, tt.message || "签约失败", tt.code);
    }

    async syncSign(contractId) {
        var contract = await this.dao.findById(contractId);
        if (!contract) {
            return null;
        }
        var account = await this.usereaccountDao.findById(contract.usereaccount_id);
        if (!account) {
            return null;
        }
        var user = await this.userDao.findById(account.user_id);

        var busi = await this.ecompanybusiDao.findOne({
            etemplate_id: contract.enttemplate_id
        });
        if (!account.isPush && busi && busi.postsignurl) {
            var param = {
                "appId": busi.appId,
                "idNo": account.personsSign,
                "idName": account.userName,
                "bankNo": account.bankno,
                "mobile": account.mobile,
                "appId3rd": user.appId3rd || "",
                "userCode3rd": user.userCode3rd || "",
                "userId3rd": user.userId3rd || "",
                "branchCode3rd": user.branchCode3rd || "",
                "nonceStr": await this.getUidStr(16),
                "beginDate": await this.formateTime(contract.begin_at),
                "endDate": await this.formateTime(contract.end_at),
            };
            if (!user.userCode3rd && !user.userId3rd) {
                param.openId = user.openId;
            }
            if (this.ydCompanyIds.indexOf(contract.entcompany_id) > -1) {
                param.pbType = "eSign";
            }

            var signArr = [];
            signArr.push("appId=" + param.appId);
            signArr.push("appId3rd=" + param.appId3rd);
            signArr.push("bankNo=" + param.bankNo);
            signArr.push("beginDate=" + param.beginDate);
            signArr.push("branchCode3rd=" + param.branchCode3rd);
            signArr.push("endDate=" + param.endDate);
            signArr.push("idName=" + param.idName);
            signArr.push("idNo=" + param.idNo);
            signArr.push("mobile=" + param.mobile);
            signArr.push("nonceStr=" + param.nonceStr);
            if (!user.userCode3rd && !user.userId3rd) {
                signArr.push("openId=" + param.openId);
            }
            // if (contract.ecompany_id == 10173 || contract.ecompany_id == 10174 || contract.ecompany_id == 10175 || contract.ecompany_id == 10207) {
            if (this.ydCompanyIds.indexOf(contract.entcompany_id) > -1) {
                signArr.push("pbType=eSign");
            }
            signArr.push("userCode3rd=" + param.userCode3rd);
            signArr.push("userId3rd=" + param.userId3rd);
            signArr.push("key=" + busi.key);

            param.sign = md5(signArr.join("&")).toUpperCase();
            console.log(JSON.stringify(param));
            var rs = "";
            try {
                var rs = await this.restClient.execPost(param, busi.postsignurl);
                if (rs.stdout) {
                    let rsData = JSON.parse(rs.stdout);
                    if (rsData.code == "0" || rsData.code == "0000") {
                        account.isPush = true;
                        account.save();
                    }
                }
                return rs.stdout;
            } catch (error) {
                console.log(rs, "push sign url " + busi.postsignurl, "rs = " + rs);
                console.log(error);
                return "error";
            }
        }
    }

    async findSignedUses4Push(params) {
        var sql = [];
        sql.push("SELECT t1.id,t1.begin_at as beginDate,t1.end_at as endDate,");
        sql.push("t2.userName AS idName, t2.mobile ,t2.`personsSign` AS idNo, t1.completed_at AS signTime, t2.bankno AS bankNo,");
        sql.push("t3.userId3rd, t3.userCode3rd, t3.branchCode3rd, t1.fileurl AS fileUrl");
        sql.push("FROM c_entcontract t1");
        sql.push("INNER JOIN p_user_eaccount t2 ON t1.`usereaccount_id` = t2.`id`");
        sql.push("INNER JOIN p_user t3 ON t2.`user_id` = t3.`id`");
        sql.push("WHERE t1.id > :startId AND t1.`entcompany_id` = :entcompanyId AND t1.`eflowstatus` = '2' AND t1.`end_at`>= NOW()");
        if (params.idNo) {
            sql.push("AND t2.`personsSign` = :idNo");
        }
        if (params.userId3rd) {
            sql.push("AND t3.`userId3rd` = :userId3rd");
        }
        if (params.userCode3rd) {
            sql.push("AND t3.`userCode3rd` = :userCode3rd");
        }
        if (params.branchCode3rd) {
            sql.push("AND t3.`branchCode3rd` = :branchCode3rd");
        }

        sql.push("ORDER BY t1.id ASC LIMIT :pageSize ");
        var list = await this.dao.customQuery(sql.join(" "), params);
        for (var item of list) {
            item.signTime = await this.formateTime(item.signTime);
            item.beginDate = await this.formateTime(item.beginDate);
            item.endDate = await this.formateTime(item.endDate);
        }
        return list;
    }


    async getUidStr(len, radix) {
        var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
        var uuid = [],
            i;
        radix = radix || chars.length;
        if (len) {
            for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
        } else {
            var r;
            uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
            uuid[14] = '4';
            for (i = 0; i < 36; i++) {
                if (!uuid[i]) {
                    r = 0 | Math.random() * 16;
                    uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
                }
            }
        }
        return uuid.join('');
    }

    returnjson(code, msg, data) {
        return {
            code: code,
            msg: msg,
            data: data || null
        }
    }
}

module.exports = EntcontractService;