package com.mortals.xhx.busiz;

import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.OrderCol;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.framework.util.FileUtil;
import com.mortals.xhx.base.framework.config.InterceptorConfig;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.base.system.upload.service.UploadService;
import com.mortals.xhx.busiz.audit.AuditInfo;
import com.mortals.xhx.busiz.audit.AuditReq;
import com.mortals.xhx.busiz.login.DatumDataReq;
import com.mortals.xhx.busiz.matters.MyMattersReq;
import com.mortals.xhx.busiz.oneProblemlist.OneProblemInfo;
import com.mortals.xhx.busiz.oneProblemlist.OneProblemReq;
import com.mortals.xhx.busiz.onethinglist.OneThineInfo;
import com.mortals.xhx.busiz.onethinglist.OneThingReq;
import com.mortals.xhx.busiz.onethinglist.OneThingRsp;
import com.mortals.xhx.busiz.question.QuestionInfo;
import com.mortals.xhx.busiz.question.AnswerReq;
import com.mortals.xhx.busiz.topic.TopicInfo;
import com.mortals.xhx.busiz.topic.TopicReq;
import com.mortals.xhx.busiz.topic.TopicRsp;
import com.mortals.xhx.busiz.uploadfile.DeleteFileReq;
import com.mortals.xhx.busiz.uploadfile.SubmitDatumReq;
import com.mortals.xhx.common.code.ApiRespCodeEnum;
import com.mortals.xhx.common.code.OneThingRespCodeEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.pdu.api.Page;
import com.mortals.xhx.feign.flowable.IApiFlowInstanceFeign;
import com.mortals.xhx.feign.rsp.ApiResp;
import com.mortals.xhx.module.member.model.MemberEntity;
import com.mortals.xhx.module.member.model.MemberQuery;
import com.mortals.xhx.module.member.service.MemberService;
import com.mortals.xhx.module.one.model.*;
import com.mortals.xhx.module.one.service.OneClassifyService;
import com.mortals.xhx.module.one.service.OneClassifyTopicalService;
import com.mortals.xhx.module.one.service.OneTopicalService;
import com.mortals.xhx.module.yth.model.YthOnethingEntity;
import com.mortals.xhx.module.yth.model.YthOnethingQuery;
import com.mortals.xhx.module.yth.service.YthOnethingService;
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.util.*;
import java.util.stream.Collectors;

/**
 * 一件事微信对外服务接口
 *
 * @author: zxfei
 * @date: 2021/8/24 20:28
 */
@CrossOrigin(origins = "*")
@RestController
@CommonsLog
@RequestMapping("/zwfw/proced/")
public class WxOneThingApiController {

    @Autowired
    private YthOnethingService onethingService;

    @Autowired
    private MemberService memberService;
    @Autowired
    private InterceptorConfig config;
    @Autowired
    private UploadService uploadService;
    @Autowired
    private OneTopicalService oneTopicalService;
    @Autowired
    private OneClassifyService oneClassifyService;
    @Autowired
    private OneClassifyTopicalService oneClassifyTopicalService;

    /**
     * 一件事主题包列表
     *
     * @param req
     * @return
     */
    @PostMapping("thing/getTopicList")
    public ApiResp<TopicRsp> getTopicList(TopicReq req) {
        ApiResp<TopicRsp> rsp = new ApiResp<>();
        TopicRsp topicRsp = new TopicRsp();
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        try {
            //分页查询
            PageInfo pageInfo = new PageInfo();
            pageInfo.setPrePageResult(req.getLimit());
            pageInfo.setCurrPage(req.getPage());
            OneTopicalQuery query = new OneTopicalQuery();
            if (!ObjectUtils.isEmpty(req.getName())) {
                query.setTopicalName("%" + req.getName() + "%");
            }
            Result<OneTopicalEntity> result = oneTopicalService.find(query.topicalType(req.getType()).deleted(YesNoEnum.NO.getValue()), pageInfo, null);

            List<TopicInfo> collect = result.getList().stream().map(item -> {
                TopicInfo info = new TopicInfo();
                info.setId(item.getId());
                info.setTopicalType(item.getTopicalType());
                info.setTopicalName(item.getTopicalName());
                info.setDescription(item.getRemark());
                //info.setDescription(item.get);

                OneClassifyTopicalEntity oneClassifyTopicalEntity = oneClassifyTopicalService.selectOne(new OneClassifyTopicalQuery().topicalId(item.getId()));
                if (!ObjectUtils.isEmpty(oneClassifyTopicalEntity)) {
                    info.setMoveIcon(oneClassifyTopicalEntity.getMoveIcon());
                }
                info.setCreateTime(item.getCreateTime());
                return info;
            }).collect(Collectors.toList());
            Page page = new Page();
            page.setSize(result.getPageInfo().getCurrPage());
            page.setPer(result.getPageInfo().getPrePageResult());
            page.setTotal(result.getPageInfo().getTotalResult());
            topicRsp.setPage(page);
            topicRsp.setList(collect);
            rsp.setData(topicRsp);
        } catch (Exception e) {
            log.error("一件事主题列表失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【一件事主题包列表】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 一件事主题列表(包含主题包)
     *
     * @param req
     * @return
     */
    @PostMapping("thing/oneTopiclist")
    public ApiResp<List<Map<String, Object>>> oneThingList(OneThingReq req) {
        ApiResp<List<Map<String, Object>>> rsp = new ApiResp<>();
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        try {
            List<Map<String, Object>> treeList = oneTopicalService.getTreeList(req.getType());
            rsp.setData(treeList);
        } catch (Exception e) {
            log.error("一件事列表失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【一件事列表】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 一件事列表
     *
     * @param req
     * @return
     */
    @PostMapping("thing/getList")
    public ApiResp<OneThingRsp> getList(OneThingReq req) {
        ApiResp<OneThingRsp> rsp = new ApiResp<>();
        OneThingRsp oneThingRsp = new OneThingRsp();
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        try {
            Map<Long, OneTopicalEntity> topicMap = oneTopicalService.find(new OneTopicalQuery().deleted(YesNoEnum.NO.getValue())).stream().collect(Collectors.toMap(x -> x.getId(), y -> y));
            Map<Long, String> classifyMap = oneClassifyService.find(new OneClassifyQuery().deleted(YesNoEnum.NO.getValue()).classifyLevel(1L)).stream().collect(Collectors.toMap(x -> x.getId(), y -> y.getClassifyName()));
            //如果有分类查询，则需要关联查询
            PageInfo pageInfo = new PageInfo();
            pageInfo.setPrePageResult(req.getLimit());
            pageInfo.setCurrPage(req.getPage());
            List<OneThineInfo> collect = new ArrayList<>();
            Page page = new Page();
            //判断是否有分类查询
            if (!ObjectUtils.isEmpty(req.getTopicId())) {
                Result<OneClassifyTopicalEntity> result = oneClassifyTopicalService.find(new OneClassifyTopicalQuery().topicalId(req.getTopicId()).deleted(YesNoEnum.NO.getValue()), pageInfo, null);
                collect = result.getList().stream().map(item -> {
                    OneThineInfo info = new OneThineInfo();
                    info.setId(item.getClassifyId());
                    info.setTopicalName(topicMap.get(item.getTopicalId()) == null ? "" : topicMap.get(item.getTopicalId()).getTopicalName());
                    info.setTopicalType(topicMap.get(item.getTopicalId()) == null ? 1 : topicMap.get(item.getTopicalId()).getTopicalType());
                    info.setName(classifyMap.get(item.getClassifyId()) == null ? "" : classifyMap.get(item.getClassifyId()));
                    info.setCreateTime(item.getCreateTime());
                    return info;
                }).collect(Collectors.toList());

                page.setSize(result.getPageInfo().getCurrPage());
                page.setPer(result.getPageInfo().getPrePageResult());
                page.setTotal(result.getPageInfo().getTotalResult());

            } else {
                Result<OneClassifyEntity> result = oneClassifyService.find(new OneClassifyQuery().classifyLevel(1L).classifyName("%" + req.getName() + "%").deleted(YesNoEnum.NO.getValue()), pageInfo, null);
                collect =result.getList().stream().map(item -> {
                    OneThineInfo info = new OneThineInfo();
                    info.setId(item.getId());
                    info.setName(item.getClassifyName());
                    info.setCreateTime(item.getCreateTime());
                    return info;
                }).collect(Collectors.toList());

                page.setSize(result.getPageInfo().getCurrPage());
                page.setPer(result.getPageInfo().getPrePageResult());
                page.setTotal(result.getPageInfo().getTotalResult());

            }
            oneThingRsp.setPage(page);
            oneThingRsp.setList(collect);
            rsp.setData(oneThingRsp);
        } catch (Exception e) {
            log.error("一件事列表失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【一件事列表】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 问题详细
     *
     * @param req
     * @return
     */
    @PostMapping("thing/oneProblem")
    public ApiResp<OneProblemInfo> oneProblem(OneProblemReq req) {
        ApiResp<OneProblemInfo> rsp = new ApiResp<>();
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        try {
            OneProblemInfo allQuestion = oneClassifyTopicalService.findAllQuestion(req.getId());
            rsp.setData(allQuestion);
        } catch (Exception e) {
            log.error("一件事问答失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【一件事详细】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 问答答案提交后返回的详细结果
     *
     * @param req
     * @return
     */
    @PostMapping("thing/ansResults")
    public ApiResp<QuestionInfo> ansResults(AnswerReq req) {
        ApiResp<QuestionInfo> rsp = new ApiResp<>();
        rsp.setMsg(OneThingRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(OneThingRespCodeEnum.SUCCESS.getValue());
        try {

            QuestionInfo mattersByAnswers = oneClassifyTopicalService.getMattersByAnswers(req);
            rsp.setData(mattersByAnswers);
        } catch (Exception e) {
            log.error("问答基础信息失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【问答基础信息】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 上传附件
     *
     * @param file
     * @return
     */
    @PostMapping("thing/uploadFile")
    public ApiResp<Map<String, String>> uploadFile(@RequestParam("file") MultipartFile file) {
        ApiResp<Map<String, String>> rsp = new ApiResp<>();
        rsp.setMsg(OneThingRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(OneThingRespCodeEnum.SUCCESS.getValue());
        try {
            String path = uploadService.saveFileUpload(file, config.getPrepath(), null);
            Map<String, String> map = new HashMap<>();
            map.put("path", path);
            rsp.setData(map);
        } catch (Exception e) {
            log.error("上传文件", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【上传文件】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 删除附件
     *
     * @param req
     * @return
     */
    @PostMapping("thing/delFile")
    public ApiResp<String> deleteFile(DeleteFileReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(OneThingRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(OneThingRespCodeEnum.SUCCESS.getValue());
        try {

            String filePath = uploadService.getFilePath(req.getFilePath());
            boolean delete = FileUtil.delete(filePath);
            if (!delete) {
                rsp.setMsg("未找到文件");
                rsp.setCode(OneThingRespCodeEnum.FAILED.getValue());
            }
        } catch (Exception e) {
            log.error("删除文件", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【删除文件】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 查询用户信息
     *
     * @param req
     * @return
     */
    @PostMapping("thing/searchMember")
    public ApiResp<MemberEntity> searchMember(BaseReq req) {
        ApiResp<MemberEntity> rsp = new ApiResp<>();
        rsp.setMsg(OneThingRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(OneThingRespCodeEnum.SUCCESS.getValue());
        try {

            MemberEntity memberEntity = memberService.selectOne(new MemberQuery().openId(req.getOpenId()), null);
            if (ObjectUtils.isEmpty(memberEntity)) {
                throw new AppException("查询用户不存在");
            }
            rsp.setData(memberEntity);
        } catch (Exception e) {
            log.error("查询用户信息失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【查询用户信息】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 一件事办理资料提交
     *
     * @param req
     * @return
     */
    @PostMapping("thing/submitDatum")
    public ApiResp<String> submitDatum(SubmitDatumReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(OneThingRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(OneThingRespCodeEnum.SUCCESS.getValue());
        try {
            onethingService.datumUploadAndStartFlow(req);
        } catch (Exception e) {
            log.error("一件事办理资料提交失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【一件事办理资料提交】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 我的办理
     *
     * @param req
     * @return
     */
    @PostMapping("thing/myHandle")
    public ApiResp<List<AuditInfo>> myHandle(AuditReq req) {
        ApiResp<List<AuditInfo>> rsp = new ApiResp<>();
        rsp.setMsg(OneThingRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(OneThingRespCodeEnum.SUCCESS.getValue());
        try {
            //todo 我的办理信息
            List<YthOnethingEntity> list = onethingService.find(new YthOnethingQuery().openId(req.getOpenId()));
            List<AuditInfo> collect = list.stream().map(item -> {
                AuditInfo auditInfo = new AuditInfo();
                BeanUtils.copyProperties(item, auditInfo);
                OneClassifyEntity oneClassifyEntity = oneClassifyService.get(item.getClassifyTopicId());
                if(!ObjectUtils.isEmpty(oneClassifyEntity)){
                    auditInfo.setClassifyName(oneClassifyEntity.getClassifyName());
                }
                return auditInfo;
            }).collect(Collectors.toList());

            rsp.setData(collect);
        } catch (Exception e) {
            log.error("我的办理失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【我的办理】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 微信用户提交材料
     *
     * @param entity
     * @return
     */
//    @PostMapping("thing/create")
//    public ApiResp<String> createThing(OnethingEntity entity) {
//        ApiResp rsp = new ApiResp<>();
//        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
//        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
//        try {
//            entity.setType(OneThingTypeEnum.UNSUBMIT.getValue());
//            entity.setStatus(ApproveStateEnum.UN_AUDIT.getValue());
//            entity.setCreateUser("admin");
//            entity.setCreateTime(new Date());
//            OnethingEntity save = onethingService.save(entity);
//            rsp.setData(save.getId());
//        } catch (Exception e) {
//            log.error("流程实例化终止失败", e);
//            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
//            rsp.setMsg(e.getMessage());
//            return rsp;
//        }
//
//        log.info("响应【材料创建】【响应体】-->  " + JSONObject.toJSONString(rsp));
//        return rsp;
//    }


    /**
     * 发起流程
     *
     * @param req
     * @return
     */
   /* @PostMapping("thing/start")
    public ApiResp<String> startProcess(StartOneThingReq req) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            OnethingEntity onethingEntity = onethingService.get(req.getOneThingId());
            MemberEntity memberEntity = memberService.get(onethingEntity.getMemberId());

            //获取流程定义key 发起流程 当前通过param参数固定获取
            String oneThingKey = paramService.getValueByKey(BusizParams.SYS_PARAM_FLOW_KEY);
            //通过流程key获取基础提交参数
            String vars = paramService.getValueByKey(oneThingKey);

            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> variables = mapper.readValue(vars, Map.class);

            StartProcessInstanceReq startProcessInstanceReq = new StartProcessInstanceReq();
            startProcessInstanceReq.setProcessDefinitionKey(oneThingKey);
            startProcessInstanceReq.setBusinessKey(onethingEntity.getId().toString());
            startProcessInstanceReq.setFormName("一件事一次办");
            startProcessInstanceReq.setUserCode(memberEntity.getOpenId());
            startProcessInstanceReq.setPlatformSn(config.getTenantId());
            startProcessInstanceReq.setVariables(variables);

            ApiResp<String> resp = apiFlowInstanceFeign.processStart(startProcessInstanceReq);
            onethingEntity.setProcessInstanceId(resp.getData());
            onethingEntity.setType(OneThingTypeEnum.SUBMIT.getValue());
            onethingEntity.setStatus(ApproveStateEnum.AUDITING.getValue());

            onethingService.update(onethingEntity);

            rsp.setData(resp.getData());

        } catch (Exception e) {
            log.error("发起审批流程", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }
        log.info("响应【材料创建】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }*/


}
