package com.chinaweal.aiccs.aiccs.punishment.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chinaweal.aiccs.aiccs.abnormal.entity.EBaseinfo;
import com.chinaweal.aiccs.aiccs.abnormal.mapper.EBaseinfoMapper;
import com.chinaweal.aiccs.aiccs.abnormal.service.EBaseinfoService;
import com.chinaweal.aiccs.aiccs.auditing.entity.TSOpinion;
import com.chinaweal.aiccs.aiccs.auditing.service.TSOpinionService;
import com.chinaweal.aiccs.aiccs.business.entity.TSTaskList;
import com.chinaweal.aiccs.aiccs.business.entity.TSTwfProcessNode;
import com.chinaweal.aiccs.aiccs.business.service.TSTaskListService;
import com.chinaweal.aiccs.aiccs.business.service.TSTwfProcessNodeService;
import com.chinaweal.aiccs.aiccs.business.service.WorkFlowService;
import com.chinaweal.aiccs.aiccs.punishment.entity.EntLock;
import com.chinaweal.aiccs.aiccs.punishment.entity.Personlock;
import com.chinaweal.aiccs.aiccs.punishment.entity.TsbizPunishUnlock;
import com.chinaweal.aiccs.aiccs.punishment.entity.dto.PersonEntDto;
import com.chinaweal.aiccs.aiccs.punishment.entity.excel.UnlockExcel;
import com.chinaweal.aiccs.aiccs.punishment.service.EntlockService;
import com.chinaweal.aiccs.aiccs.punishment.service.PersonEntService;
import com.chinaweal.aiccs.aiccs.punishment.service.PersonlockService;
import com.chinaweal.aiccs.aiccs.punishment.service.TsbizPunishUnlockService;
import com.chinaweal.aiccs.aiccs.punishment.service.impl.TsbizPunishUnlockServiceImpl;
import com.chinaweal.aiccs.aiccs.punishment.util.BusTridMakeUtil;
import com.chinaweal.aiccs.aiccs.punishment.util.ExcelIePortUtils;
import com.chinaweal.aiccs.aiccs.punishment.util.ExcelListener;
import com.chinaweal.aiccs.aiccs.punishment.util.TolockentParamConstant;
import com.chinaweal.aiccs.common.base.controller.BaseController;
import com.chinaweal.aiccs.common.constant.BaseDataConstant;
import com.chinaweal.aiccs.common.constant.Constant;
import com.chinaweal.aiccs.common.util.FlowUtil;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aiccs.common.util.WorkFlowUtil;
import com.chinaweal.aicorg.model.AICUser;
import com.chinaweal.youfool.framework.springboot.exception.custom.BusinessException;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.page.PageRequestDto;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.chinaweal.youfool.framework.springboot.rest.ResultCode;
import com.chinaweal.youfool.framework.springboot.util.AssertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;


/**
 * <p>
 * 解锁业务表 前端控制器
 * </p>
 *
 * @author Lee
 * @since 2021-06-07
 */
@RestController
@RequestMapping("/tsbizpunishunlock")
public class TsbizPunishUnlockController extends BaseController {


    @Autowired
    private EntlockService entlockService;
    @Autowired
    private TsbizPunishUnlockService tsbizPunishUnlockService;
    @Autowired
    private TsbizPunishUnlockServiceImpl tsbizPunishUnlockServiceImpl;
    @Autowired
    private TSTaskListService taskListService;
    @Autowired
    private WorkFlowService workFlowService;
    @Autowired
    private BusTridMakeUtil busTridMakeUtil;
    @Autowired
    private TSOpinionService opinionService;

    @Autowired
    private TSTwfProcessNodeService tsTwfProcessNodeService;

    @Autowired
    private PersonEntService personEntService;

    @Autowired
    private PersonlockService personlockService;

    @Autowired
    private EBaseinfoMapper eBaseinfoMapper;

    @PostMapping(value = "/saveAccept")
    public RestResult<?> saveAccept(String elIds, HttpServletRequest request) {
        AssertUtils.isNotBlank(elIds);
        //生成业务号
        String bizSeq = UUID.randomUUID().toString();
        String[] elIdArray = elIds.split(Constant.SEMICOLON);
        for (int i = 0; i < elIdArray.length; i++) {
            if(tsbizPunishUnlockService.checkpunishlock(elIdArray[i])){
                return RestResult.error(ResultCode.BUSINESS_ASSOCIATED,"该主体已存在解锁业务中");
            }
        }

        Map<String, String> map = tsbizPunishUnlockServiceImpl.addtounlock(elIdArray, bizSeq,request);

//        if(entLocks!=null&&entLocks.size()!=0){
//            for (EntLock entLock : entLocks) {
//                TsbizPunishUnlock tsbizpunishunlockmodel = new TsbizPunishUnlock();
//                tsbizpunishunlockmodel.setBizseq(bizSeq);
//                tsbizpunishunlockmodel.setElid(entLock.getElid());
//                tsbizpunishunlockmodel.setEntname(entLock.getEntname());
//                tsbizpunishunlockmodel.setPripid(entLock.getPripid());
//                tsbizpunishunlockmodel.setRegno(entLock.getRegno());
//                tsbizpunishunlockmodel.setUniscid(entLock.getUniscid());
//                tsbizPunishUnlocks.add(tsbizpunishunlockmodel);
//            }
//        }
        if (StringUtils.isNotBlank(map.get("tasklistid"))) {
            return RestResult.ok(map);
        }
        //待办
        return OK;
    }

    @PostMapping(value = "/next")
    public RestResult<?> next(HttpServletRequest request, TsbizPunishUnlock tsbizPunishUnlockModel, TSOpinion opinionModel,
                              String tasklistid, String nextPerformerids, String nextPerformerNames, String nextNodeID) {
        AICUser user = getLoginUser(request);
        Map<String, Object> resultMap = new HashMap<>();

        //更新业务表
        if (tsbizPunishUnlockModel != null && StringUtils.isNotBlank(tsbizPunishUnlockModel.getBizseq())) {
            TSTaskList taskListModel = taskListService.selectByTasklistID(tasklistid);
            TsbizPunishUnlock paramModel = new TsbizPunishUnlock();
            LambdaQueryWrapper<TsbizPunishUnlock> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(TsbizPunishUnlock::getBizseq,tsbizPunishUnlockModel.getBizseq());
            //批量，业务主体有多个
            List<TsbizPunishUnlock> tsbizPunishUnlocks = tsbizPunishUnlockService.list(wrapper);
            LocalDateTime nowDateTime = LocalDateTime.now();
            for (TsbizPunishUnlock bizPunishUnlockModel : tsbizPunishUnlocks) {
                //下一步为审核
                if (FlowUtil.PUNISHWORKFLOWE_HANDLEPUNISH.equals(nextNodeID)) {
                    TSTwfProcessNode processNode = workFlowService.findCurrentNode(taskListModel.getWorkflowid());
                    int order = WorkFlowUtil.checkNextOrder(processNode.getCurrentnode(), nextNodeID);
                    if (order > 0) {
//                        bizPunishUnlockModel.setUnluserid();
                        bizPunishUnlockModel.setUnlockreason(tsbizPunishUnlockModel.getUnlockreason());
                        bizPunishUnlockModel.setUnlusername(user.getName());
                        bizPunishUnlockModel.setUnlockTime(nowDateTime);
                    }

                }
            }
            if(StringUtils.isBlank(nextPerformerids)) {
                TSTwfProcessNode processNode = workFlowService.findCurrentNode(taskListModel.getWorkflowid());
                int order = WorkFlowUtil.checkNextOrder(processNode.getCurrentnode(), nextNodeID);
                // 通过order判断为回退还是前进 >0前进
                if(order >0){
                    LambdaQueryWrapper<TSOpinion> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(TSOpinion::getWorkflowid, taskListModel.getWorkflowid())
                            .eq(TSOpinion::getOpiniontype, "0")// 经办为0
                            .orderByDesc(TSOpinion::getLauptime);
                    List<TSOpinion> list = opinionService.list(queryWrapper);
                    if (org.apache.commons.collections4.CollectionUtils.isEmpty(list)) {
                        return RestResult.error(ResultCode.DATA_NONE);
                    }
                    nextPerformerids = list.get(0).getHandlerid();
                    nextPerformerNames = list.get(0).getHandler();
                }
                // 回退时 获取上一个处理人
                if (order < 0){
                    List<TSTwfProcessNode> tsTwfProcessNodes = tsTwfProcessNodeService.queryByPROCESSIDAndCURRENTNODE(taskListModel.getWorkflowid(),nextNodeID);
                    nextPerformerids = tsTwfProcessNodes.get(0).getCurruserid();
                    nextPerformerNames = tsTwfProcessNodeService.queryRealName(tsTwfProcessNodes.get(0).getCurruserid());
//                    nextPerformerids = taskListModel.getSenderuserid();
//                    nextPerformerNames = taskListModel.getSendername();
                }
            }
            //发送
            String[] ids = StringUtils.split(nextPerformerids, Constant.COMMA);
            String[] names = StringUtils.split(nextPerformerNames, Constant.COMMA);
            tsbizPunishUnlockService.savePunishUnlockProcess(user, taskListModel, tsbizPunishUnlocks, opinionModel, nextNodeID, ids, names);
            if (ids.length == 1 && StringUtils.equals(user.getPrimaryKey(), ids[0])) {
                resultMap.put("bizseq", tsbizPunishUnlockModel.getBizseq());
                resultMap.put("nextNodeId", nextNodeID);
                resultMap.put("taskListId", tasklistid);
                resultMap.put("workFlowId", taskListModel.getWorkflowid());
            }
        } else {
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR);
        }
        return RestResult.ok(resultMap);
    }

    @PostMapping("getEntLockPageandPunishFrom")
    public RestResult<?> getEntLockPageandPunishFrom(@RequestBody PageRequestDto pageRequestDto){
        List list=new ArrayList();
        List<EntLock> ents = null;
        List<Personlock> persons = null;
        String punishFrom = null;
        AssertUtils.isNotNull(pageRequestDto,pageRequestDto.getCustomParamMap());
        Map<String, Object> customParamMap = pageRequestDto.getCustomParamMap();
        String bizseq = StringUtils.tranObject(customParamMap.get("bizseq"));
        String searchName = StringUtils.tranObject(customParamMap.get("searchName"));
        AssertUtils.isNotBlank(bizseq);
        LambdaQueryWrapper<TsbizPunishUnlock> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TsbizPunishUnlock::getBizseq,bizseq);
        wrapper.like(StringUtils.isNotBlank(searchName),TsbizPunishUnlock::getEntname,searchName);
        List<TsbizPunishUnlock> tsbizPunishUnlocks = tsbizPunishUnlockService.list(wrapper);
        if(tsbizPunishUnlocks.size() ==0){
            return RestResult.error(ResultCode.DATA_NONE);
        }
        ArrayList<String> elIds = new ArrayList<>();
        for (TsbizPunishUnlock tsbizPunishUnlock : tsbizPunishUnlocks) {
            elIds.add(tsbizPunishUnlock.getElid());
        }
        //LambdaQueryWrapper<EntLock> queryWrapper = new LambdaQueryWrapper<>();
        //queryWrapper.in(EntLock::getElid,elIds);
        //List<EntLock> page = entlockService.list(queryWrapper);
        LambdaQueryWrapper<EntLock> EntWrapper = new LambdaQueryWrapper<>();
        EntWrapper.in(EntLock::getElid,elIds);
        LambdaQueryWrapper<Personlock> PersonWrapper = new LambdaQueryWrapper<>();
        PersonWrapper.in(Personlock::getPlid,elIds);
        if(entlockService.list(EntWrapper)!=null&entlockService.list(EntWrapper).size()>0){
            ents = entlockService.list(EntWrapper);
        }
        if(personlockService.list(PersonWrapper)!=null&personlockService.list(PersonWrapper).size()>0){
            persons = personlockService.list(PersonWrapper);
        }

//        for (int i = 0; i < page.size(); i++) {
//            EntLock entLock = page.get(i);
//             String address=eBaseinfoMapper.selectAddress(entLock.getEntname());
//            entLock.setAddress(address);
//        }
//        EntLock entLock = page.get(0);
        if(ents!=null&&ents.size()>0){
            for (int i = 0; i < ents.size(); i++) {
                EntLock entLock = ents.get(i);
                EBaseinfo eBaseinfo=eBaseinfoMapper.selectAddress(entLock.getEntname());
                entLock.setAddress(eBaseinfo.getAddress());
            }
        }
        if(persons!=null&&persons.size()>0) {
            for (int i = 0; i < persons.size(); i++) {
                Personlock personlock = persons.get(i);
                EBaseinfo eBaseinfo = eBaseinfoMapper.selectAddress(personlock.getEntname());
                personlock.setAddress(eBaseinfo.getAddress());
                personlock.setRegorg(eBaseinfo.getRegorg());
                personlock.setRegstate(eBaseinfo.getRegstate());
            }
        }
        if(ents!=null){
            EntLock entLock = ents.get(0);
            punishFrom = entLock.getPunishFrom();
        }
        String unlockReason = tsbizPunishUnlocks.get(0).getUnlockreason();
        HashMap<String, Object> map = new HashMap<>();
        map.put("punishFrom",punishFrom);
        map.put("unlockReason",unlockReason);
        if(ents!=null){
            list.addAll(ents);
        }
        if(null==ents&&persons!=null){
            list.addAll(persons);
        }
        map.put("page",list);
        //map.put("page",page);
        return RestResult.ok(map);
    }

    /**
     * 联合惩戒解锁导入
     * @param httpServletRequest
     * @param file
     * @return
     */
    @PostMapping("upload")
    public RestResult<?> upload(HttpServletRequest httpServletRequest, MultipartFile file, String measure){

        if(StringUtils.isBlank(measure)){
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"请选择惩戒措施!");
        }

        AssertUtils.isNotNull(file);
        String filename = file.getOriginalFilename();
        if (filename == null || (!filename.toLowerCase().endsWith(".xls") && !filename.toLowerCase().endsWith(".xlsx"))) {
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"文件类型错误");
        }
        ExcelListener excelListener = ExcelIePortUtils.getExcelListener(file, new UnlockExcel(), 1, 1);
        Object objList = excelListener.getDatas();
        List<UnlockExcel> orderList = (List<UnlockExcel>) objList;
        //校验模板
        Map<Integer,String> headMap = excelListener.getMap();
        Map<String,String> checkMap = TolockentParamConstant.getMap("unlock");
        for (Map.Entry<Integer,String> entry : headMap.entrySet()) {
            String value = checkMap.get(entry.getKey().toString());
            if (StringUtils.isNotBlank(value) && !value.equals(entry.getValue())){
                return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"上传模板错误!");
            }
        }
        List<String> successList = new ArrayList<>();
        List<UnlockExcel> failList = new ArrayList<>();
        Map<String,Object> rs = new HashMap<>();
        String count = "";
        if(orderList.size()==0){
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"导入数据条数不能为0!");
        }
        count = String.valueOf(orderList.size());
        for(UnlockExcel unlockExcel : orderList){
            LambdaQueryWrapper<EntLock> wrapper = new LambdaQueryWrapper<>();
            if(StringUtils.isNotBlank(unlockExcel.getUniscid())){
                wrapper.eq(EntLock::getUniscid, unlockExcel.getUniscid());
            }
            if(StringUtils.isNotBlank(unlockExcel.getRegno())){
                wrapper.eq(EntLock::getRegno, unlockExcel.getRegno());
            }
            if(StringUtils.isNotBlank(unlockExcel.getEntname())){
                wrapper.eq(EntLock::getEntname, unlockExcel.getEntname());
            }
            wrapper.eq(EntLock::getMeasure,measure);
            EntLock entLock = entlockService.getOne(wrapper);
            if(entLock != null){
                if(entLock.getState().equals("0")) { //锁定状态
                    successList.add(entLock.getElid());
                }else { //解锁中，以解锁
                    unlockExcel.setReason("该企业处于解锁中或以解锁状态");
                    failList.add(unlockExcel);
                }
            }else {
                unlockExcel.setReason("该主体不存在锁定表中");
                failList.add(unlockExcel);
            }
        }
        rs.put("successList",successList);
        rs.put("failList",failList);
        rs.put("count",count);
        //导入数据
        return RestResult.ok(rs);
    }

    @RequestMapping(value = "exportExcel", method = {RequestMethod.POST}, produces = {"application/vnd.ms-excel;" +
            "charset=UTF-8"})
    public void exportExcel(@RequestBody List<UnlockExcel> failList, HttpServletResponse response) throws IOException {
        ServletOutputStream outputStream=null;
        try {
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + new String("导入失败数据.xls".getBytes(), "UTF-8"));
            response.setContentType("application/msexcel;charset=UTF-8");
            outputStream = response.getOutputStream();
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "sheet1").head(UnlockExcel.class).build();
            excelWriter.write(failList, writeSheet1);
            excelWriter.finish();
        } catch (IOException e) {
            outputStream.close();
            e.printStackTrace();
        } finally {
            outputStream.close();
        }
    }


    @Transactional
    @RequestMapping("saveAcceptByUpload")
    public RestResult<?> saveAcceptByUpload(@RequestBody String entLockStr, HttpServletRequest request) {

        AssertUtils.isNotBlank(entLockStr);
        List<String> entLocks = JSONObject.parseArray(entLockStr,String.class);
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i<entLocks.size(); i++) {
            if (i == entLocks.size()-1) {
                builder.append(entLocks.get(i));
            } else {
                builder.append(entLocks.get(i) + ";");
            }
        }
        String param = builder.toString();
        // 发起流程
        RestResult<?> rs = this.saveAccept(param,request);
        return rs;
    }
}

