package fi.er.webService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import fi.cas.opplugin.TypeUtils;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.openapi.common.custom.annotation.ApiController;
import kd.bos.openapi.common.custom.annotation.ApiMapping;
import kd.bos.openapi.common.custom.annotation.ApiParam;
import kd.bos.openapi.common.custom.annotation.ApiPostMapping;
import kd.bos.openapi.common.result.CustomApiResult;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.util.StringUtils;
import nckd.jimin.jyyy.fi.common.NstcApiReturnModel;
import java.io.Serializable;
import java.util.Date;

/**
 * @author zf
 * 接收九恒星银行账户，并生成金融机构
 */
@ApiController(value = "account", desc = "自定义API 银行账户同步")
@ApiMapping(value = "SaveAccountApi")
public class SaveAccountApi implements Serializable {
    protected static final Long DEFAULT_ORG_ID = 100000L;

    private static final Log logger = LogFactory.getLog(SaveAccountApi.class);

    /**
     * @description 行名行号同步接口
     * @param data
     * @return CustomApiResult
     */
    @ApiPostMapping(value = "/save", desc = "同步银行账户")
    public CustomApiResult<JSONObject> saveAccount (@ApiParam(value = "九恒星银行账户") JSONArray data) {
        StringBuilder resultString = new StringBuilder();

        Boolean result = true;

        DynamicObject rmbinfo = BusinessDataServiceHelper.loadSingleFromCache(1L,"bd_currency");
        //默认的国家
        DynamicObject defaultgj = BusinessDataServiceHelper.loadSingleFromCache("1000001", "bd_country");

        RequestContext rc = RequestContext.get();
        DynamicObject user = BusinessDataServiceHelper.loadSingleFromCache(rc.getCurrUserId(), "bos_user");
        DynamicObject defaultOrg = BusinessDataServiceHelper.loadSingle(DEFAULT_ORG_ID, "bos_org");
        //默认金融机构类别
        DynamicObject defaultjrjgtypeinfo = BusinessDataServiceHelper.loadSingleFromCache(615763944224700416L,"bd_finorgtype");

        //默认银行类别
        QFilter typecodeFilter = new QFilter("type_code.number","=","BC-9999");
        DynamicObject defaulttypecodeinfo =BusinessDataServiceHelper.loadSingleFromCache("bd_bankcgsetting",new QFilter[]{typecodeFilter});


        JSONArray dataArray = new JSONArray();

        //循环传入的数据
        for (int i = 0; i < data.size(); i++) {
            JSONObject eobject = data.getJSONObject(i);
            try {
                NstcApiReturnModel contractSynReturnModel = syncAccount(eobject, rmbinfo, defaultjrjgtypeinfo, defaultgj, defaulttypecodeinfo, defaultOrg, user);
                if ("500".equals(contractSynReturnModel.getCode())) {
                    result = false;
                }
                dataArray.add(JSONObject.parseObject(JSON.toJSONString(contractSynReturnModel)));
            } catch (Exception e) {
                logger.error("保存银行账号失败：{}", e.getMessage());

                NstcApiReturnModel returnModel = new NstcApiReturnModel();

                returnModel.setNumber(eobject.get("bankAccountNumber")+"");
                returnModel.setName(eobject.get("acctName")+"");
                returnModel.setCode("500");
                returnModel.setMessage("保存银行账号失败: " + e.getMessage());

                dataArray.add(JSONObject.parseObject(JSON.toJSONString(returnModel)));
            }
        }

        return returnResult("200", "S", "接口调用成功，同步结果请查看responseData参数", dataArray);
    }


    /**
     * @description 保存行名行号
     * @param jsonObject
     */
    private NstcApiReturnModel syncAccount(JSONObject jsonObject,DynamicObject rmbinfo, DynamicObject defaultjrjgtypeinfo,DynamicObject defaultgj,DynamicObject defaulttypecodeinfo, DynamicObject defaultOrg,DynamicObject user) {
        NstcApiReturnModel contractSynReturnModel = new NstcApiReturnModel();
        Date curDate = new Date();
        String number = jsonObject.get("bankAccountNumber")+"";
        String name = jsonObject.get("acctName")+"";
        if ("".equals(number)||"".equals(name)) {
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("账户名和银行账号不能为空");
            return contractSynReturnModel;
        }

        contractSynReturnModel.setNumber(number);
        contractSynReturnModel.setName(name);

        //查询是否存在，存在则返回。不存在更新
        QFilter qFilter = new QFilter("number","=",number);
        DynamicObject accountinfo =  BusinessDataServiceHelper.loadSingle("bd_accountbanks",new QFilter[]{qFilter});
        if(accountinfo!=null){
            //已存在
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("该银行账号已存在");
            return contractSynReturnModel;
        }

        //法人主体，改成用company接口，取消使用name参数接收
//        String orgname = jsonObject.get("name")+"";
//        if ("".equals(orgname)) {
//            contractSynReturnModel.setCode("500");
//            contractSynReturnModel.setMessage("法人主体不能为空");
//            return contractSynReturnModel;
//        }

        if(jsonObject.get("company") == null || jsonObject.getJSONObject("company").get("id") == null){
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("法人主体(company)为空");
            return contractSynReturnModel;
        }

        //账户类型
        String companyNo = jsonObject.getJSONObject("company").getString("id");

        //查询组织是否存在
        QFilter orgqFilter = new QFilter("number","=", companyNo);
        DynamicObject orginfo =BusinessDataServiceHelper.loadSingleFromCache("bos_org",new QFilter[]{orgqFilter});
        if(orginfo == null){
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("没有找到编码为："+ companyNo +"的组织");
            return contractSynReturnModel;
        }

        if(jsonObject.get("accountBankType") == null || jsonObject.getJSONObject("accountBankType").get("alias") == null){
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("账户类型参数(accountBankType)为空");
            return contractSynReturnModel;
        }

        //账户类型
        String acctstyle = jsonObject.getJSONObject("accountBankType").getString("alias");
        if ("".equals(acctstyle)) {
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("账户类型不能为空");
            return contractSynReturnModel;
        }
        //opendate开户日期
        String opendate = jsonObject.get("openDate")+"";
        if ("".equals(opendate)) {
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("开户日期不能为空");
            return contractSynReturnModel;
        }

        //会计科目
        if(jsonObject.get("account") == null || jsonObject.getJSONObject("account").get("id") == null){
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("会计科目参数(account)为空");
            return contractSynReturnModel;
        }

        //账户类型
        String account = jsonObject.getJSONObject("account").getString("id");
        if ("".equals(account)) {
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("账户类型不能为空");
            return contractSynReturnModel;
        }

        //查询会计科目
        QFilter accountFilter = new QFilter("number","=",account);
        DynamicObject accountViewInfo = BusinessDataServiceHelper.loadSingleFromCache("bd_accountview",new QFilter[]{accountFilter});
        if (accountViewInfo == null) {
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("会计科目"+ account +"不存在");
            return contractSynReturnModel;
        }

        //账户用途
        if(jsonObject.get("accountPrupose") == null || jsonObject.getJSONObject("accountPrupose").get("alias") == null){
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("账户用途不能为空");
            return contractSynReturnModel;
        }

        String accountPrupose = jsonObject.getJSONObject("accountPrupose").getString("alias");
        if ("".equals(acctstyle)) {
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("账户用途不能为空");
            return contractSynReturnModel;
        }

        QFilter prupose = new QFilter("name","=", accountPrupose);
        DynamicObject pruposeInfo =BusinessDataServiceHelper.loadSingleFromCache("bd_acctpurpose",new QFilter[]{prupose});
        if(pruposeInfo == null){
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("账户用途不存在：" + accountPrupose);
            return contractSynReturnModel;
        }

        if(jsonObject.get("bank") == null || jsonObject.getJSONObject("bank").get("id") == null){
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("开户行参数(bank)为空");
            return contractSynReturnModel;
        }
        //开户行行号
        String banknumber = jsonObject.getJSONObject("bank").getString("id");
        if ("".equals(banknumber)) {
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("开户行行号不能为空");
            return contractSynReturnModel;
        }
        //查询行名行号
        QFilter bankqFilter = new QFilter("number","=",banknumber);
        DynamicObject bankinfo =BusinessDataServiceHelper.loadSingleFromCache("bd_bebank",new QFilter[]{bankqFilter});
        if (bankinfo==null) {
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("开户行行号"+banknumber+"不存在");
            return contractSynReturnModel;
        }

        //通过开户行行号找到金融机构，没有就新增一个
        QFilter jrjgqFilter = new QFilter("bebank.number","=",banknumber);
        DynamicObject jrjginfo =BusinessDataServiceHelper.loadSingleFromCache("bd_finorginfo",new QFilter[]{jrjgqFilter});
        if (jrjginfo==null) {
            jrjginfo = BusinessDataServiceHelper.newDynamicObject("bd_finorginfo");
            jrjginfo.set("finorgtype",defaultjrjgtypeinfo);
            jrjginfo.set("number",banknumber);
            jrjginfo.set("bebank",bankinfo);
            jrjginfo.set("name",bankinfo.get("name")+"");
            //根据行号前3位找到银行类别，找不到就其他
            String typecode = banknumber.substring(0,3);
            QFilter typecodeFilter = new QFilter("type_code.number","=",typecode);
            DynamicObject typecodeinfo =BusinessDataServiceHelper.loadSingleFromCache("bd_bankcgsetting",new QFilter[]{typecodeFilter});
            if(typecodeinfo==null){
                jrjginfo.set("bank_cate",defaulttypecodeinfo);
            }else{
                jrjginfo.set("bank_cate",typecodeinfo);
            }
            //国家
            jrjginfo.set("country",defaultgj);
            //联行号
            jrjginfo.set("union_number",banknumber);


            jrjginfo.set("creator", user);
            jrjginfo.set("createtime", curDate);
            jrjginfo.set("enable",1);
            jrjginfo.set("status","C");
            //执行保存
            StringBuilder err = new StringBuilder();
            OperationResult result = SaveServiceHelper.saveOperate("bd_finorginfo", new DynamicObject[]{jrjginfo}, OperateOption.create());
            if (result.getSuccessPkIds().size() > 0) {
                jrjginfo.set("id",result.getSuccessPkIds().get(0));
            }else{
                for (int k = 0; k < result.getAllErrorOrValidateInfo().size(); k++) {
                    String message = result.getAllErrorOrValidateInfo().get(k).getMessage();
                    err.append("/").append(message);
                }
                contractSynReturnModel.setCode("500");
                contractSynReturnModel.setMessage("金融机构保存失败："+err.toString());
                return contractSynReturnModel;
            }
        }




        accountinfo =BusinessDataServiceHelper.newDynamicObject("bd_accountbanks");
        accountinfo.set("company",orginfo);
        accountinfo.set("openorg",orginfo);
        accountinfo.set("finorgtype","0");
        //开户行,即金融机构
        accountinfo.set("bank",jrjginfo);
        accountinfo.set("bankaccountnumber",number);
        accountinfo.set("name",name);//账户简称
        accountinfo.set("acctname", name);//账户名称

        //币别，多选基础资料
        DynamicObjectCollection currencyinfos = accountinfo.getDynamicObjectCollection("currency");
        DynamicObject bibiecollinfo = currencyinfos.addNew();
        bibiecollinfo.set("fbasedataid",rmbinfo);
        //默认币种
        accountinfo.set("defaultcurrency",rmbinfo);

        //acctstyle 账户类型
        String acctstylestr = "normal";
        if("基本存款账户".equals(acctstyle)){
            acctstylestr = "basic";
        }else if("临时存款账户".equals(acctstyle)){
            acctstylestr = "temp";
        }else if("专用存款账户".equals(acctstyle)){
            acctstylestr = "spcl";
        }else if("经常项目外汇账户".equals(acctstyle)){
            acctstylestr = "fgn_curr";
        }else if("资本项目外汇账户".equals(acctstyle)){
            acctstylestr = "fng_fin";
        }
        accountinfo.set("acctstyle",acctstylestr);

        accountinfo.set("accttype","in_out");


        accountinfo.set("acctproperty", pruposeInfo);

        try {
            accountinfo.set("opendate", TypeUtils.string2Date(opendate,TypeUtils.DEFAULT_DATE_FORMAT));
        }catch (Exception e){
            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("开户日期"+opendate+"格式不对：应为yyyy-MM-dd");
            return contractSynReturnModel;
        }
        accountinfo.set("nckd_bd_acctview", accountViewInfo);//会计科目
        accountinfo.set("acctstatus","normal");
        accountinfo.set("elecpaymentlevel","WL01");
        accountinfo.set("manager",user);


        accountinfo.set("enable",1);
        accountinfo.set("status","C");



        accountinfo.set("creator", user);
        accountinfo.set("createorg", defaultOrg);
        accountinfo.set("org", defaultOrg);
        accountinfo.set("createtime", curDate);

        //执行保存
        OperationResult result = SaveServiceHelper.saveOperate("bd_accountbanks", new DynamicObject[]{accountinfo}, OperateOption.create());

        StringBuilder err = new StringBuilder();
        if (result.getSuccessPkIds().size() > 0) {
            if (result.isSuccess()) {
                contractSynReturnModel.setCode("200");
                contractSynReturnModel.setMessage("保存成功");
                return contractSynReturnModel;
            } else {
                for (int k = 0; k < result.getAllErrorOrValidateInfo().size(); k++) {
                    String message = result.getAllErrorOrValidateInfo().get(k).getMessage();
                    err.append("/").append(message);
                }
                contractSynReturnModel.setCode("500");
                contractSynReturnModel.setMessage(err.toString());
                return contractSynReturnModel;
            }
        } else{
            StringBuilder errMsg = new StringBuilder();

            if(StringUtils.isNotEmpty(result.getMessage())){
                errMsg.append(result.getMessage() + ";");
            }

            if (result.getSuccessPkIds().size() <= 0) {
                for (int i = 0; i < result.getAllErrorOrValidateInfo().size(); i++) {
                    String message = result.getAllErrorOrValidateInfo().get(i).getMessage();
                    errMsg.append("/").append(message);
                }
            }

            contractSynReturnModel.setCode("500");
            contractSynReturnModel.setMessage("保存失败" + errMsg.toString());
            return contractSynReturnModel;
        }
    }


    /**
     * 自定义返回data对象
     * @param code  编码
     * @param message  错误信息
     * @return   CustomApiResult  返回
     */
    public CustomApiResult<JSONObject> returnResult(String code, String status, String message, JSONArray dataArrary){
        JSONObject reslutData = new JSONObject();

        JSONArray responseData = new JSONArray();
        JSONObject dataJSON = new JSONObject();
        dataJSON.put("data", dataArrary);

        responseData.add(dataJSON);

        reslutData.put("code", code);
        reslutData.put("status", status);
        reslutData.put("message", message);
        reslutData.put("responseData", responseData);

        return CustomApiResult.success(reslutData);
    }
}
