package shkd.bamp.base.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.entity.DynamicObject;
import kd.bos.db.DB;
import kd.bos.db.DBRoute;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.org.model.OrgDutyView;
import kd.bos.org.model.OrgParam;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.org.OrgUnitServiceHelper;
import kd.bos.servicehelper.org.OrgViewType;
import kd.sdk.plugin.Plugin;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import shkd.utils.DobeDWUtils;

import java.io.IOException;
import java.util.*;

/**
 * 后台任务插件 yxl 20240830
 * 组织和人员的相关操作参考 https://dev.kingdee.com/open/detail/sdk/2077750769712378880
 */
public class DobeDWorgTask extends AbstractTask implements Plugin {

    private static final String entityName = "bos_org";//系统库 表名 t_org_org
    private static Log log = LogFactory.getLog(DobeDWorgTask.class);

    private static final String dw_menthod = "mdm_arog";

    @Override
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
        //定时任务具体执行逻辑 从数仓获取当天更新的行政组织数据,并与系统中的组织数据比较,是新增还是更新
        //组装请求数仓查询接口入参
        //调用数仓查询接口
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(DobeDWUtils.dwUrl+dw_menthod)
                .post(DobeDWUtils.createRequestBody("",1))
                .header("Content-Type", "application/json")
                .header("Authorization", DobeDWUtils.appCode)
                .build();

        String resultData = null;
        Response response = null;
        try {
            response = client.newCall(request).execute();
            resultData = response.body().string();
            log.info("组织接口返回结果:\n{}", resultData);
        } catch (IOException e) {
            log.info(String.format("组织接口异常:%s", e.getMessage()));
            throw new RuntimeException(e);
        }
        JSONObject json_body = JSON.parseObject(resultData);
        //接口返回的数据进行了分页
        int totalNum = json_body.getIntValue("totalNum");//分页-SQL查询总数据量
        //解析接口返回值,与系统数据比较
        handleOrg(json_body);
        int queryCount = DobeDWUtils.getQueryCount(totalNum);
        if(queryCount > 1){
            //查询次数不止一次,需要分页查询
            for (int i = 2; i <= queryCount; i++) {
                request = new Request.Builder().url(DobeDWUtils.dwUrl+dw_menthod)
                        .post(DobeDWUtils.createRequestBody("",i))
                        .header("Content-Type", "application/json")
                        .header("Authorization", DobeDWUtils.appCode)
                        .build();
                try {
                    response = client.newCall(request).execute();
                    resultData = response.body().string();
//                    log.info("组织接口返回结果:\n{}", resultData);
                } catch (IOException e) {
                    log.info(String.format("组织接口异常:%s", e.getMessage()));
                    throw new RuntimeException(e);
                }
                json_body = JSON.parseObject(resultData);
                handleOrg(json_body);
            }
        }
    }

    private boolean isNeedUpdate(DynamicObject currentOrg,String orgNumber,String orgName,Long parentId){
        if(!orgNumber.equals(currentOrg.getString("number")) || !orgName.equals(currentOrg.getString("name"))){
            return true;
        }
        List<Long> idlist = new ArrayList<>();
        idlist.add(currentOrg.getLong("id"));
        //获取直接上级组织 返回值说明 <组织ID - 上级组织ID>
        Map<Long,Long> maprs = OrgUnitServiceHelper.getDirectSuperiorOrg(OrgViewType.Admin,idlist);
        if(maprs != null && !parentId.equals(maprs.get(idlist.get(0)))){
            return true;
        }
        return false;
    }

    private void handleOrg(JSONObject json_body) {
        JSONArray detailsJson = json_body.getJSONArray("data");
//        List<OrgParam> paramList = new ArrayList<>();
        OrgParam param = null;
        DynamicObject parentOrg = null;
        DynamicObject currentOrg = null;
        String orgNumber = null;
        String orgName = null;
        String orgID = null;
        String parentId = null;
        String person_charge = null;//部门下的负责人的工号
        String updateNocgeSql = "UPDATE t_SEC_UserPosition SET fisincharge=? WHERE fdptid in (select fid from t_org_org where fyzjorgid=?);";
        String updatecgeSql = "UPDATE t_SEC_UserPosition SET fisincharge=? WHERE fdptid in (select fid from t_org_org where fyzjorgid=?) and fid in (select fid from t_sec_user where fnumber=?);";
        TreeMap<String, OrgDutyView> multiViewMap = new TreeMap<>();
        OrgDutyView dutyView = null;
        for (int i = 0; i < detailsJson.size(); i++) {
            json_body = detailsJson.getJSONObject(i);
            orgNumber = json_body.getString("org_code");
            orgName = json_body.getString("org_name");
            orgID = json_body.getString("org_id");
//            String orgLevel = json_body.getString("org_level");//组织层级
            parentId = json_body.getString("org_parentid");
            person_charge = json_body.getString("person_chargecode");
            if(DobeDWUtils.isEmpty(orgID) || DobeDWUtils.isEmpty(orgNumber) || DobeDWUtils.isEmpty(orgName)
                    || DobeDWUtils.isEmpty(parentId)){
                //如果组织ID和组织编码 名称是空的,则跳过此记录
                log.info(String.format("组织入参为空异常:%s", json_body.toJSONString()));
                continue;
            }
            //根据父级ID获取父级组织对象,组织的主数据id存在于星瀚组织的fyzjorgid字段中
            parentOrg = QueryServiceHelper.queryOne(entityName,"id,number,name",new QFilter[]{new QFilter("fyzjorgid","=",parentId)});
            if(parentOrg == null){
                log.info(String.format("根据数仓组织父级ID未在金蝶中找到对应组织:%s", parentId));
                continue;
            }
            //根据组织ID查找系统现有数据是否存在,这种写法会抛异常,需要关注原因
            currentOrg = QueryServiceHelper.queryOne(entityName,"id,number,name",new QFilter[]{new QFilter("fyzjorgid","=",orgID)});
            if(currentOrg != null){
                //根据组织下的负责人id去人员分录表中更新负责人标记,先去除这个部门下人员的负责人标记,再更新
                if(!DobeDWUtils.isEmpty(person_charge)){
                    DB.update(DBRoute.of("sys"), updateNocgeSql, new Object[]{0,orgID});
                    DB.update(DBRoute.of("sys"), updatecgeSql, new Object[]{1,orgID,person_charge});
                }
                //已存在,做更新
                if(!isNeedUpdate(currentOrg,orgNumber,orgName,parentOrg.getLong("id"))){
                    //编号和名称、上级单位都没有变化,无需更新;现在判断不出来上级单位,直接更新
                    continue;
                }
                param = new OrgParam();
                param.setId(currentOrg.getLong("id"));
                param.setName(orgName);
                param.setNumber(orgNumber);
//                param.setParentId(parentOrg.getLong("id"));//上级组织的金蝶ID
                //设置多视图参数
                multiViewMap.clear();
                dutyView = new OrgDutyView();
                //组织移动时,设置新的上级ID
                dutyView.setParentId(parentOrg.getLong("id"));
                //行政组织
                multiViewMap.put(OrgViewType.Admin, dutyView);
                //每种视图方案的参数对象不能用同一个,需要单独实例化
                dutyView = new OrgDutyView();
                dutyView.setParentId(parentOrg.getLong("id"));
                //业务单元
                multiViewMap.put(OrgViewType.OrgUnit, dutyView);
                //采购组织
//                dutyView = new OrgDutyView();
//                dutyView.setParentId(parentOrg.getLong("id"));
//                multiViewMap.put(OrgViewType.Asset, dutyView);

                param.setMultiViewMap(multiViewMap);
                OrgUnitServiceHelper.update(param);
                if (!param.isSuccess()) {
                    log.info(String.format("组织修改异常:%s", param.getMsg()));
                }
            }else{

                /* 新增单个视图方案的组织 */
                param = new OrgParam();
//                param.setParentId(parentOrg.getLong("id"));//上级组织的金蝶ID
                param.setName(orgName);
                param.setYzjOrgId(orgID);//云之家组织内码字段,用于保存组织的外部ID
                param.setNumber(orgNumber);
                param.setOrgPatternId(4);//组织形态ID,默认ID为4L(部门)1为公司;当前组织是公司还是部门需要有字段可以体现
//                param.setCustomOrgId(Long.parseLong(orgID));//组织自定义ID,用于保存第三方系统的ID,并非额外字段保存,而是直接更新id字段
                param.setDuty(OrgViewType.Admin);//组织属性-行政组织
                //设置组织属性-单个视图
//                Map<String, Object> proMap = new HashMap<>();
//                proMap.put("uniformsocialcreditcode", "add0001");//统一社会信用代码
//                param.setPropertyMap(proMap);//组织关联属性map
//                paramList.add(param);

                // 设置多视图参数
//                TreeMap<String, OrgDutyView> multiViewMap = new TreeMap<>();
                multiViewMap.clear();
                dutyView = new OrgDutyView();
                dutyView.setParentId(parentOrg.getLong("id"));//上级组织的金蝶ID
                multiViewMap.put(OrgViewType.Admin, dutyView);//行政组织
                dutyView = new OrgDutyView();
                dutyView.setParentId(parentOrg.getLong("id"));//上级组织的金蝶ID
                multiViewMap.put(OrgViewType.OrgUnit, dutyView);//业务单元
                dutyView = new OrgDutyView();
                dutyView.setParentId(parentOrg.getLong("id"));//上级组织的金蝶ID
                multiViewMap.put(OrgViewType.Accounting, dutyView);//核算组织
                dutyView = new OrgDutyView();
                dutyView.setParentId(parentOrg.getLong("id"));//上级组织的金蝶ID
                multiViewMap.put(OrgViewType.Purchase, dutyView);//采购组织

                param.setMultiViewMap(multiViewMap);//多职能参数 支持一次更新多种业务视图方案;键为视图方案编码(参照本页参数说明的OrgViewType),值为OrgDutyView对象
//                paramList.add(param);
                // 执行并判断结果,如下是微服务模式调用,会提示服务找不到
//                IOrgService orgService = ServiceFactory.getService(OrgService.class);
//                orgService.add(paramList);
                OrgUnitServiceHelper.add(param);
                if (!param.isSuccess()) {
                    log.info(String.format("组织新增异常:%s", param.getMsg()));
                }
                //部门新增时,不用去更新部门下的负责人
            }
        }
    }
    //        for (OrgParam result : paramList) {
//            // 根据操作结果提示用户或执行其他处理
//            if (!result.isSuccess()) {
//                log.info(String.format("组织保存异常:%s", result.getMsg()));
//            }
//        }
}