package shkd.repc.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.sdk.plugin.Plugin;
import nccloud.open.api.auto.token.cur.utils.APICurUtils;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import shkd.utils.DobeDWUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 后台任务插件
 */
public class YongyouBIPTask extends AbstractTask implements Plugin {
    private static Log log = LogFactory.getLog(YongyouBIPTask.class);

    //合同付款申请单的实体名称
//    private static final String payrequestEntity = "recon_payreqbill";
    //费用登记的实体名称
//    private static final String notextEntity = "recon_connotextbill";
    private static final String payregisterEntity = "recon_payregister";//付款登记标识 供应链库 t_recon_payregister

    @Override
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
        //查找合同付款申请单已审核未付款的单子
//        DynamicObjectCollection docs = QueryServiceHelper.query(payrequestEntity,"id,number,name",new QFilter[]{new QFilter("billstatus","=","C")});
//        DynamicObject currentinfo = null;
//        for (int i = 0; i < docs.size(); i++) {
//            currentinfo = docs.get(i);
//        }

        //查找未审核的付款登记单,考虑费用登记和付款申请单如果是事后补单的话,此处是否需要过滤
        QFilter statusFilter = new QFilter("billstatus","=","A");
        QFilter statusB = new QFilter("billstatus","=","B");
//        String selectStr = "id,billno,bizdate,billstatus,connotextbill.id,connotextbill.billno,connotextbill.qeug_yynum,payreqbill.id,payreqbill.billno,payreqbill.qeug_yynum";
        DynamicObject[] prs = BusinessDataServiceHelper.load(payregisterEntity,"id",new QFilter[]{statusFilter.or(statusB)});
        if(prs.length == 0){
            return;
        }
        //将满足本次查询条件的单子存入map中
        DynamicObject prinfo = null;
        DynamicObject requestinfo = null;
        String yyid = null;
        JSONObject idjson = null;
        JSONArray idarray = new JSONArray();
        Map<String,DynamicObject> billMap = new HashMap();
        Map<String,String> billNumberMap = new HashMap();
        for (int i = 0; i < prs.length; i++) {
            prinfo = BusinessDataServiceHelper.loadSingle(prs[i].getPkValue(),payregisterEntity);
            //费用登记
            requestinfo = prinfo.getDynamicObject("connotextbill");
            if(requestinfo == null){
                //付款申请
                requestinfo = prinfo.getDynamicObject("payreqbill");
            }
            requestinfo = BusinessDataServiceHelper.loadSingle(requestinfo.getPkValue(),requestinfo.getDataEntityType().getName().replace("_f7",""));
            //看用友的实付款查询接口是一个个查询,还是集中查询;这个字段直接从F7实体对象中获取不到,需要扩展F7实体
            yyid = requestinfo.getString("qeug_yyid");
            //获取到的yyid为空,则不进行实付查询
            if(DobeDWUtils.isEmpty(yyid)){
                continue;
            }
            billMap.put(yyid,prinfo);
            billNumberMap.put(yyid,requestinfo.getString("qeug_yynum"));
            idjson = new JSONObject();
            idjson.put("id",yyid);
            idarray.add(idjson);
        }
        if(billMap.isEmpty()){
            return;
        }
        //bip接口认证
        String accesstoken = null;
        APICurUtils apiutil = new APICurUtils();//处理认证接口的工具类(用友提供的第三方工具),得到accesstoken
        apiutil.init(DobeDWUtils.yyip,DobeDWUtils.yyport,DobeDWUtils.bizcenter,DobeDWUtils.clientid,DobeDWUtils.clientsecret,DobeDWUtils.pubKey,DobeDWUtils.clientid,null);
        try {
            String tokenresult = apiutil.getTokenByClient();
            if(DobeDWUtils.isEmpty(tokenresult)){
                log.error("用友认证接口返回的accessToken为空");
                return;
            }
            JSONObject json_reuslt = JSON.parseObject(tokenresult);
            if(json_reuslt.getJSONObject("data") == null){
                log.error("用友认证接口返回的data为空");
                return;
            }
            accesstoken = json_reuslt.getJSONObject("data").getString("access_token");
        } catch (Exception e) {
            log.error(String.format("用友认证接口异常:%s", e.getMessage()));
            throw new RuntimeException(e);
        }
        if(DobeDWUtils.isEmpty(accesstoken)){
            log.error("用友认证接口返回的accessToken为空");
            return;
        }
        JSONObject queryParams = new JSONObject();
        queryParams.put("bipData",idarray);
        Request request = new Request.Builder().url(DobeDWUtils.payQueryUrl)
                .post(createFormRequestBody(queryParams))
                .header("Content-Type", "application/json;charset=utf-8")
                .header("access_token", accesstoken)
                .header("repeat_check", "Y")
                .header("ucg_flag", "Y")
                .header("client_id", DobeDWUtils.clientid)
                .build();
        try {
            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            JSONObject resultData = JSON.parseObject(response.body().string());
            if(!"200".equals(resultData.getString("code"))){
                //增加日志记录
                DobeDWUtils.saveLog("noQueryResult","用友实付查询",queryParams.toString(),resultData.toString(),false,"定时任务");
                return;
            }
            JSONArray dataArray = resultData.getJSONArray("data");
            for (int i = 0; i < dataArray.size(); i++) {
                idjson = dataArray.getJSONObject(i);
                yyid = idjson.getJSONObject("parentVO").getString("pk_busi");
                prinfo = billMap.get(yyid);
                if(prinfo != null){
                    prinfo.set("bizdate",idjson.getJSONObject("parentVO").getDate("settleDate"));
                    prinfo.set("billno",billNumberMap.get(yyid));
                    prinfo.set("billstatus","B"); //单据状态改为已提交
                    SaveServiceHelper.update(prinfo);//保存上述设置内容
                    //调用付款登记单的审核方法
                    OperationServiceHelper.executeOperate("audit",payregisterEntity,new DynamicObject[]{prinfo}, OperateOption.create());
                }
            }
            DobeDWUtils.saveLog("querySuccess","用友实付查询",queryParams.toString(),resultData.toString(),true,"定时任务");
        } catch (Exception e) {
            DobeDWUtils.saveLog("queryException","用友实付查询",queryParams.toString(),e.getMessage(),false,"定时任务");
        }

//        String[] companyDept = null;
//        for (int i = 0; i < prs.length; i++) {
//            //根据付款申请单的用款部门找到对应财务组织编号
//            companyDept = DobeDWUtils.getCompanyDeptNumber(requestinfo.getDynamicObject("usedepart").getString("number"));
//            if(companyDept[0] == null){
//                DobeDWUtils.saveLog(requestinfo.getString("number"),"用友实付查询",requestinfo.getDynamicObject("usedepart").getString("number"),"根据用款部门编号转换财务编号失败",false,"定时任务");
//                continue;
//            }
//            queryParams.put("pk_org",companyDept[0]);
//            //根据查询结果设置付款登记对象
//            prinfo.set("bizdate",resultData.getJSONObject("data").getDate("billdate"));
//            prinfo.set("billno",yynum);
//            prinfo.set("billstatus","B"); //单据状态改为已提交
//            SaveServiceHelper.update(prinfo);//保存上述设置内容
//            //调用提交方法
////            OperationServiceHelper.executeOperate("submit",payregisterEntity,new DynamicObject[]{prinfo}, OperateOption.create());
//            //调用付款登记单的审核方法
//            OperationServiceHelper.executeOperate("audit",payregisterEntity,new DynamicObject[]{prinfo}, OperateOption.create());
//            DobeDWUtils.saveLog(requestinfo.getString("number"),"用友实付查询",queryParams.toString(),resultData.toString(),true,"定时任务");
//        }
    }

    private RequestBody createFormRequestBody(JSONObject json_body) {
//        return RequestBody.create(ByteString.encodeUtf8(json_body.toJSONString()), DobeDWUtils.MTJSON);
        return RequestBody.create(json_body.toJSONString(), DobeDWUtils.MTJSON);
    }
}