package com.mortals.xhx.daemon.demo;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.util.DateUtils;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.common.model.RequestTaskReq;
import com.mortals.xhx.common.pdu.api.ApiReqPdu;
import com.mortals.xhx.common.pdu.api.ApiRespPdu;
import com.mortals.xhx.feign.flowable.IApiFlowDefinitionFeign;
import com.mortals.xhx.feign.flowable.IApiFlowFeign;
import com.mortals.xhx.module.matter.model.*;
import com.mortals.xhx.module.matter.service.*;
import com.mortals.xhx.module.matters.model.MattersDetailEntity;
import com.mortals.xhx.module.matters.model.MattersDetailQuery;
import com.mortals.xhx.module.matters.model.MattersQuery;
import com.mortals.xhx.module.matters.service.MattersDetailService;
import com.mortals.xhx.module.matters.service.MattersService;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.*;

/**
 * @author karlhoo
 */
@CommonsLog
@RestController
@RequestMapping("test")
public class RequestDispatchController {
    @Autowired
    private IApiFlowFeign apiFlowFeign;
    @Autowired
    private IApiFlowDefinitionFeign apiFlowDefinitionFeign;

    @Autowired
    private ICacheService cacheService;

    @Autowired
    private MatterService matterService;
    @Autowired
    private MatterDetailService matterDetailService;
    @Autowired
    private MattersService mattersService;
    @Autowired
    private MattersDetailService mattersDetailService;
    @Autowired
    private MatterFlowlimitService matterFlowlimitService;
    @Autowired
    private MatterAcceptService matterAcceptService;
    @Autowired
    private MatterSetbaseService matterSetbaseService;
    @Autowired
    private MatterQuestionService matterQuestionService;
    @Autowired
    private MatterIntermediaryService matterIntermediaryService;
    @Autowired
    private MatterDatumService matterDatumService;
    @Autowired
    private MatterChargesService matterChargesService;
    @Autowired
    private MatterBaseinfoService matterBaseinfoService;
    @Autowired
    private ParamService paramService;

    /**
     * eeeee
     *
     * @param multipartFile
     * @return
     */
    @RequestMapping(value = "/importXml", method = RequestMethod.POST)
    public ApiRespPdu importXml(@RequestParam("file") MultipartFile multipartFile) {

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        try {
            String xml = IoUtil.readUtf8(multipartFile.getInputStream());
            log.info(xml);

            respPdu.setData(xml);

            //respPdu = apiFlowDefinitionFeign.save("test", "请假", xml,"test");

        } catch (Exception e) {
            log.error("error", e);
        }
        return respPdu;
    }


    /**
     * adfafafd
     *
     * @param req
     * @return
     */
    @PostMapping("/readXml")
    public ApiRespPdu readXml(@RequestBody ApiReqPdu<RequestTaskReq> req) {

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        try {
            //respPdu = apiFlowDefinitionFeign.readXml(req.getTransmission().getDeployId());
        } catch (Exception e) {
            log.error("error", e);
        }
        return respPdu;
    }

    /**
     * adfasfd
     *
     * @param req
     * @return
     */
    @PostMapping("/readImage")
    public ApiRespPdu readImage(@RequestBody ApiReqPdu<RequestTaskReq> req) {

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        try {
            //respPdu = apiFlowDefinitionFeign.readImage(req.getTransmission().getDeployId());

            String data = respPdu.getData();
            byte[] decode = Base64.decode(data);

            FileUtil.writeBytes(decode, "E://pic//1.png");


        } catch (Exception e) {
            log.error("error", e);
        }
        return respPdu;
    }

    /**
     * fafda
     *
     * @param req
     * @return
     */
    @PostMapping("/delete")
    public ApiRespPdu delete(@RequestBody ApiReqPdu<RequestTaskReq> req) {

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        try {
            // respPdu = apiFlowDefinitionFeign.delete(req.getTransmission().getDeployId());
        } catch (Exception e) {
            log.error("error", e);
        }
        return respPdu;
    }


    /**
     * fafda
     *
     * @param req
     * @return
     */
    @PostMapping("/token")
    public ApiRespPdu token(@RequestBody ApiReqPdu<RequestTaskReq> req) {

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        try {

            mattersService.find(new MattersQuery()).stream().peek(item -> {

                MattersDetailEntity mattersDetailEntity = mattersDetailService.selectOne(new MattersDetailQuery().matterCode(item.getMatterCode()));

                MatterEntity matterEntity = new MatterEntity();
                matterEntity.setMatterNo(item.getMatterCode());
                matterEntity.setAreaCode(item.getAreaCode());
                matterEntity.setDeptCode(item.getDeptCode());

                matterEntity.setPowerCode(item.getPowerCode());
                matterEntity.setMatterName(item.getName());
                matterEntity.setGroupName(item.getGroupName());
                matterEntity.setThemeCode(item.getThemeCode());
                matterEntity.setUrl(item.getUrl());
                matterEntity.setUsertypeCode(item.getUsertypeCode());
                matterEntity.setSource(0);
                matterEntity.setCreateTime(new Date());
                matterEntity.setCreateUserName("system");

                //BeanUtils.copyProperties(item,matterEntity);


                matterService.save(matterEntity);

                if (!ObjectUtils.isEmpty(mattersDetailEntity)) {
                    MatterDetailEntity detailEntity = new MatterDetailEntity();
                    BeanUtils.copyProperties(mattersDetailEntity, detailEntity);
                    detailEntity.setBasicInfoJbxx(mattersDetailEntity.getBasicinfoJbxx());
                    detailEntity.setMatterId(matterEntity.getId());
                    matterDetailService.save(detailEntity);

                    MatterAcceptEntity acceptEntity = new MatterAcceptEntity();
                    acceptEntity.setMatterId(item.getId());
                    acceptEntity.setTitle(item.getName());
                    acceptEntity.setContent(mattersDetailEntity.getConditionsSltj());
                    acceptEntity.setSource(0);
                    acceptEntity.setCreateUser("system");
                    acceptEntity.setCreateTime(new Date());

                    matterAcceptService.save(acceptEntity);

                    MatterChargesEntity chargesEntity = new MatterChargesEntity();
                    chargesEntity.setMatterId(item.getId());
                    chargesEntity.setTitle(item.getName());
                    chargesEntity.setContent(mattersDetailEntity.getChargingSfbz());
                    chargesEntity.setSource(0);
                    chargesEntity.setCreateUser("system");
                    chargesEntity.setCreateTime(new Date());
                    matterChargesService.save(chargesEntity);

//                    MatterFlowlimitEntity flowlimitEntity = new MatterFlowlimitEntity();
//                    flowlimitEntity.setMatterId(item.getId());
//                    flowlimitEntity.setTitle(item.getName());
//                    flowlimitEntity.setContent(mattersDetailEntity.getProcessBllc());
//                    flowlimitEntity.setSource(0);
//                    flowlimitEntity.setCreateUser("system");
//                    flowlimitEntity.setCreateTime(new Date());
//                    matterFlowlimitService.save(flowlimitEntity);

                    MatterIntermediaryEntity intermediaryEntity = new MatterIntermediaryEntity();
                    intermediaryEntity.setMatterId(item.getId());
                    intermediaryEntity.setTitle(item.getName());
                    intermediaryEntity.setContent(mattersDetailEntity.getIntermediaryZjfw());
                    intermediaryEntity.setSource(0);
                    intermediaryEntity.setCreateUser("system");
                    intermediaryEntity.setCreateTime(new Date());
                    matterIntermediaryService.save(intermediaryEntity);


                    MatterQuestionEntity questionEntity = new MatterQuestionEntity();
                    questionEntity.setMatterId(item.getId());
                    questionEntity.setTitle(item.getName());
                    questionEntity.setContent(mattersDetailEntity.getQuestionCjwt());
                    questionEntity.setSource(0);
                    questionEntity.setCreateUser("system");
                    questionEntity.setCreateTime(new Date());
                    matterQuestionService.save(questionEntity);

                    MatterSetbaseEntity setbaseEntity = new MatterSetbaseEntity();
                    setbaseEntity.setMatterId(item.getId());
                    setbaseEntity.setTitle(item.getName());
                    setbaseEntity.setContent(mattersDetailEntity.getBasisSdyj());
                    setbaseEntity.setSource(0);
                    setbaseEntity.setCreateUser("system");
                    setbaseEntity.setCreateTime(new Date());
                    matterSetbaseService.save(setbaseEntity);

//
//                    MatterDatumEntity datumEntity = new MatterDatumEntity();
//                    datumEntity.initAttrValue();
//                    datumEntity.setMatterId(item.getId());
//                    datumEntity.setMaterialName(item.getName());
//                    //datumEntity.setContent(mattersDetailEntity.getMaterialsSqcl());
//                    datumEntity.setSource(0);
//                    datumEntity.setCreateUser("system");
//                    datumEntity.setCreateTime(new Date());
//                    matterDatumService.save(datumEntity);


                    MatterBaseinfoEntity baseinfoEntity = new MatterBaseinfoEntity();
                    baseinfoEntity.setMatterId(item.getId());
                    baseinfoEntity.setTitle(item.getName());
                    baseinfoEntity.setContent(mattersDetailEntity.getBasicinfoJbxx());
                    baseinfoEntity.setSource(0);
                    baseinfoEntity.setCreateUser("system");
                    baseinfoEntity.setCreateTime(new Date());
                    matterBaseinfoService.save(baseinfoEntity);


                }

            }).count();

        } catch (Exception e) {
            log.error("error", e);
        }
        return respPdu;
    }

    /**
     * afdasfdasfd
     *
     * @param req
     * @return
     */
    // @PostMapping("/datumn")
    public ApiRespPdu list(@RequestBody ApiReqPdu<RequestTaskReq> req) {

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        Map<String, Object> model = new HashMap<String, Object>();


        Map<String, String> materialPropertyMap = paramService.getParamByFirstOrganize(Constant.Param_materialProperty);

        model.put("isMust", YesNoEnum.getEnumMap());
        model.put("iszzsb", YesNoEnum.getEnumMap());
        model.put("materialProperty", paramService.getParamByFirstOrganize(Constant.Param_materialProperty));
        model.put("materialType", paramService.getParamByFirstOrganize(Constant.Param_materialType));
        model.put("electronicgs", paramService.getParamByFirstOrganize(Constant.Param_electronicgs));
        model.put("materialSource", paramService.getParamByFirstOrganize(Constant.Param_materialSource));
        model.put("paperGg", paramService.getParamByFirstOrganize(Constant.Param_paperGg));
        model.put("jianmMs", paramService.getParamByFirstOrganize(Constant.Param_jianmMs));
        model.put("sealWay", paramService.getParamByFirstOrganize(Constant.Param_sealWay));


        try {
            //拆分材料库数据
            matterDetailService.find(new MatterDetailQuery()).stream().peek(item -> {
                String json = item.getMaterialsSqcl();

                buildJson(json, model);

            }).count();


        } catch (Exception e) {
            log.error("error", e);
        }
        return respPdu;
    }

    public void buildJson(String json, Map<String, Object> model) {
        JSONObject root = JSON.parseObject(json);
        JSONArray jsonArray = root.getJSONArray("申请材料");


        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject secondJsonObject = jsonArray.getJSONObject(i);

            MatterDatumEntity datumEntity = new MatterDatumEntity();


            //示例样表
            JSONArray jsonArrayone = secondJsonObject.getJSONArray("示例样表");
            if (!ObjectUtils.isEmpty(jsonArray)) {
                System.out.println("示例样表");

                for (int j = 0; j < jsonArrayone.size(); j++) {
                    jsonArrayone.getJSONObject(j).entrySet().stream().peek(m -> {


                        System.out.println("name:" + m.getKey());
                        System.out.println("value:" + m.getValue());
                    }).count();
                }
            }

            //空白表格
            JSONArray jsonArraytwo = secondJsonObject.getJSONArray("空白表格");

            if (!ObjectUtils.isEmpty(jsonArraytwo)) {

                System.out.println("空白表格");
                for (int j = 0; j < jsonArraytwo.size(); j++) {
                    jsonArraytwo.getJSONObject(j).entrySet().stream().peek(m -> {
                        System.out.println("name:" + m.getKey());
                        System.out.print(" value:" + m.getValue());
                    }).count();
                }
            }
            //材料详情
            System.out.println("材料详情");
            JSONArray jsonArrayThree = secondJsonObject.getJSONArray("材料详情");
            if (!ObjectUtils.isEmpty(jsonArrayThree)) {

                for (int j = 0; j < jsonArrayThree.size(); j++) {
                    jsonArrayThree.getJSONObject(j).entrySet().stream().peek(m -> {

                        if ("材料名称".equals(m.getKey().trim())) {
                            datumEntity.setMaterialName(m.getValue().toString());
                        }

                        if ("材料形式".equals(m.getKey().trim())) {
                            //查找
                            //materialPropertyMap
                            Map<String, String> map = (Map<String, String>) model.get("materialProperty");
                            BiMap<String, String> inverse = HashBiMap.create(map).inverse();
                            String value = inverse.getOrDefault(m.getValue().toString(), "0");
                            datumEntity.setMaterialProperty(Integer.parseInt(value));

                            //datumEntity.setMaterialName(m.getValue().toString());
                        }


                        System.out.println("name:" + m.getKey());
                        System.out.print(" value:" + m.getValue());
                    }).count();
                }
            }


        }
    }

    /**
     * dfasfdaf
     *
     * @param req
     * @return
     */
    @PostMapping("task/acceptor")
    public ApiRespPdu taskAcceptor(@RequestBody ApiReqPdu<RequestTaskReq> req) {

        log.info("receive api  request:" + JSON.toJSONString(req));
        String processDiagram = apiFlowFeign.getProcessDiagram(req.getTransmission().getProcessInstanceId());
        log.info("receive api base64  receive:" + processDiagram);

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();

        respPdu.setData(processDiagram);
        return respPdu;
    }

    /**
     * fasfdasfd
     *
     * @param req
     * @return
     */
    @PostMapping("task/deploy")
    public ApiRespPdu deploy(@RequestBody ApiReqPdu<RequestTaskReq> req) {

        log.info("receive api  request:" + JSON.toJSONString(req));
        ApiRespPdu<String> deploy = apiFlowFeign.deploy(req.getTransmission().getModelId());
        log.info("receive api base64  receive:" + JSON.toJSONString(deploy));

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        respPdu.setData(JSON.toJSONString(deploy));
        return respPdu;
    }

    /**
     * dfafdasfda
     *
     * @param req
     * @return
     */
    @PostMapping("task/start")
    public ApiRespPdu start(@RequestBody ApiReqPdu<RequestTaskReq> req) {
        log.info("receive api  request:" + JSON.toJSONString(req));

        ApiRespPdu<String> start = apiFlowFeign.start(req.getTransmission().getDeployId(), req.getTransmission().getUserId(), req.getTransmission().getDataKey());
        log.info("receive api start  receive:" + JSON.toJSONString(start));

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        respPdu.setData(JSON.toJSONString(start));
        return respPdu;
    }

    /**
     * afasdfasf
     *
     * @param req
     * @return
     */
    @PostMapping("task/complete")
    public ApiRespPdu taskComplete(@RequestBody ApiReqPdu<RequestTaskReq> req) {
        log.info("receive api  request:" + JSON.toJSONString(req));

        //任务完成，设置审核人，完成当前任务

        HashMap<String, Object> map = new HashMap<>();
        map.put("test", "1111");

        apiFlowFeign.taskByAssignee(req.getTransmission().getTaskId(), req.getTransmission().getAssignee(), map);

        ApiRespPdu<String> start = apiFlowFeign.start(req.getTransmission().getDeployId(), req.getTransmission().getUserId(), req.getTransmission().getDataKey());
        log.info("receive api complete  receive:" + JSON.toJSONString(start));

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        respPdu.setData(JSON.toJSONString(start));
        return respPdu;
    }


    /**
     * 测试 发起审核流程
     *
     * @param req
     * @return
     */
    @PostMapping("process/start")
    public ApiRespPdu processStart(@RequestBody ApiReqPdu<RequestTaskReq> req) {
        log.info("receive processStart  request:" + JSON.toJSONString(req));

        ApiRespPdu<String> start = apiFlowFeign.start(req.getTransmission().getDeployId(), req.getTransmission().getUserId(), req.getTransmission().getDataKey());

        log.info("receive api complete  receive:" + JSON.toJSONString(start));


        //流程发起成功后 数据与流程进行绑定 并更新当前业务数据审核状态

//        ApiRespPdu<List<Map<String, Object>>> maps = apiFlowFeign.getRuntimeBusinessKeyByUser("admin");
//        Map<String, Object> taskMap = maps.getData().stream().findAny().orElseGet(() -> null);
//        String taskId = (String) taskMap.get("taskId");

        String taskId = getTaskId("admin");
        log.info("taskId:" + taskId);

        ApiRespPdu<String> resp = apiFlowFeign.getTaskInfo(taskId);
        String processId = resp.getData();

        //下个流程有分配人为变量，所以要提前设置变量值
        apiFlowFeign.setVariable(taskId, "reviewer", "bbb");

        // 设置 assigneeList 参数
        //这个参数是在进入会签节点之前就设置了
        List<String> assigneeList = new ArrayList<>();
        assigneeList.add("a1");
        assigneeList.add("a2");
        assigneeList.add("a3");
        assigneeList.add("a4");
        assigneeList.add("a5");
        assigneeList.add("a6");
        apiFlowFeign.setListVariable(taskId, "assigneeList", assigneeList);

        Map<String, Object> map = new HashMap<>();

        //由第一个审核人进行审核  由用户获取自己的当前任务列表
        log.info("first assign admin 进行审核");
        ApiRespPdu<String> respPdu = apiFlowFeign.taskByAssignee(taskId, "admin", map);
        log.info("assign first flow:" + JSON.toJSONString(respPdu));

        //由第二个人进行审核 从新获取审核人的任务实例

        log.info("second assign b1 进行审核");
        respPdu = apiFlowFeign.taskByAssignee(getTaskId("bbb"), "bbb", map);
        log.info("assign second flow:" + JSON.toJSONString(respPdu));

        log.info("third assign  分支进行审核");
        ApiRespPdu<List<Map<String, Object>>> runtimeBusinessKeyByGroup = apiFlowFeign.getRuntimeBusinessKeyByGroup(new ArrayList<>(Arrays.asList("test-1")));

        Map<String, Object> thirdTaskMap = runtimeBusinessKeyByGroup.getData().stream().findAny().orElseGet(() -> null);
        taskId = (String) thirdTaskMap.get("taskId");
        log.info("sep_2 taskId:" + taskId);

        // 流程完成所需的条件参数
        map = new HashMap<>();
        map.put("assignee", "a2");
        // 完成任务，taskId 任务节点 ID
        respPdu = apiFlowFeign.taskByAssignee(taskId, "admin", map);
        log.info("assign four flow:" + JSON.toJSONString(respPdu));


        log.info("four assign  审核");
        apiFlowFeign.taskByAssignee(getTaskId("a2"), "a2", new HashMap<>());


        log.info("a1 assign  会签审核");
        apiFlowFeign.taskByAssignee(getTaskId("a1"), "a1", new HashMap<>());

        log.info("a2 assign  会签审核");
        apiFlowFeign.taskByAssignee(getTaskId("a2"), "a2", new HashMap<>());

        log.info("a3 assign  会签审核");
        apiFlowFeign.taskByAssignee(getTaskId("a3"), "a3", new HashMap<>());

        log.info("a4 assign  会签审核");
        apiFlowFeign.taskByAssignee(getTaskId("a4"), "a4", new HashMap<>());

        //终止流程

        log.info("processId:" + processId);
        if (!ObjectUtils.isEmpty(processId)) {
            ApiRespPdu<Boolean> booleanApiRespPdu = apiFlowFeign.checkProcessInstanceFinish(processId);
            if (booleanApiRespPdu.getData()) {
                log.info("process finish ！");
            } else {
                log.info("process unfinish ！");
            }

        }
        // apiFlowFeign.deleteProcess(resp.getData());


        return respPdu;
    }

    public String getTaskId(String userId) {

        ApiRespPdu<List<Map<String, Object>>> map = apiFlowFeign.getRuntimeBusinessKeyByUser(userId);


        if (map.getData().size() > 0) {
            Map<String, Object> taskMap = map.getData().get(map.getData().size() - 1);

            // Map<String, Object> taskMap = map.getData().stream().fin().orElseGet(() -> null);
            String taskId = (String) taskMap.get("taskId");
            log.info(" map:" + JSON.toJSONString(taskMap));
            return taskId;
        }

        return null;

    }

    void findToken() {

        String key = "Contants:" + DateUtils.getCurrDateTime(DateUtils.P_yyyy_MM_dd_HH_mm_ss);

        cacheService.setnx(key, 0);

        cacheService.incr(key);

    }


    /**
     * json提交
     *
     * @param info
     * @return
     */
    @PostMapping("/getHcpSin")
    public ApiRespPdu getHcpSin(@RequestBody TestInfo info) {

        ApiRespPdu<String> respPdu = new ApiRespPdu<>();
        respPdu.setCode(200);

        return respPdu;
    }

    /**
     * json提交
     *
     * @param
     * @return
     */
    @PostMapping("/other")
    public String other() {

        return "200";
    }


    public static void main(String[] args) {


        File file = new File("E:\\test.txt");

        String json = FileUtil.readString(file, "utf-8");

        System.out.println(json);

        json = json.replaceAll("\\\\", "\\\\\\\\");

        JSONObject jsonObject = JSONObject.parseObject(json);

        //RequestDispatchController.buildJson(json);

//        Map<String, String> map = new HashMap<>();
//
//        map.put("1","纸质");
//        map.put("2","纸质");
//
//        BiMap<String, String> inverse = HashBiMap.create(map).inverse();
//        String value = inverse.getOrDefault("纸质", "0");
//
//
//        System.out.println(value);


    }

}
