const ServiceBase = require("../sve.base");
const system = require("../../system");

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");
    }

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

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

        if (!user) {
            user = await this.userDao.create({
                appkey: params.appId,
                unionId: unionId,
                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 econtract = await this.dao.findOne({
            eflowstatus: '2',
            usereaccount_id: eaccount.id,
            enttemplate_id: ecid,
        });

        if (econtract) {
            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");
            // {"code":-110,"message":"手机号格式错误","data":{}}
            //1成功,-110提示验证信息有误，-120亲，提供的信息不正确，请验证后再试！
            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 = etemplate.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 怎么赋值????????????
        econtract = {
            name: ecompany.name,
            eflowstatusname: "签约中",
            eflowstatus: "1",
            // begin_at: now,
            // completed_at: now,
            user_id: eaccount.user_id,
            usereaccount_id: eaccount.id,
            enttemplate_id: etemplate.id,
            entcompany_id: ecompany.id,
            // end_at: end,
        };
        econtract = await this.create(econtract);

        // 创建印章id
        var sealId = "";
        var eseal = await this.esealSve.findOne({
            nameA: ecompany.sealName
        });
        // 生产环境需要打开
        if (!eseal) {
            // var accountId = "";  // 测试

            var rs = await this.utilesignbaoSve.creatEntSignet(settings.apiconfig.companyAccountId(), etemplate.nameA + "alias", etemplate.nameA, "", "", "econtractSve");
            // var rs = await this.utilesignbaoSve.creatEntSignet("740b19e0799a4d7abacfa1a31fb72b1e", etemplate.nameA + "alias", etemplate.nameA, "", "", "econtractSve");
            if (rs && rs.code == 1) {
                sealId = rs.data.sealId;
                await this.esealSve.create({
                    nameA: etemplate.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: etemplate.templateid, //模板id，由创建模板接口调用返回的templateId 必填
            name: etemplate.name, //合同模板名称 必填
            simpleFormFields: {
                nameA: params.name, //甲方 必填
                addressA: params.addr, //甲方地址
                representA: params.legal,//甲方法定代表人
                agentA: params.contactName,//甲方联系人
                agentMobileA: params.contactMobile,//甲方 联系电话

                nameB: ecompany.name, //乙方 必填
                addressB: ecompany.addr, //乙方 地址
                representB: ecompany.legal,//乙方 法定代表人
                agentB: ecompany.contactName,//乙方 联系人
                agentMobileB: ecompany.contactMobile,//乙方 联系电话

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

                signDate: today,//签约时间
                signDateA: today, //甲方签约日期 必填
                signDateB: today //乙方签约日期 必填
            }
        };
        var ebaoAccountId = eaccount.eaccountid; //签署人账户id-- 必填
        var thirdOrderNo = econtract.id; //第三方流水号，通知回调使用---选填
        var eBaoRedirectBossUrl = "";

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

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

            await econtract.save();
            this.syncSign(econtract.id);
            return this.returnjson(0, "success", {
                contractId: econtract.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.ecompany_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.ecompany_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 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;