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.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chinaweal.aiccs.aiccs.abnormal.entity.EBaseinfo;
import com.chinaweal.aiccs.aiccs.abnormal.service.EBaseinfoService;
import com.chinaweal.aiccs.aiccs.business.entity.TSTaskList;
import com.chinaweal.aiccs.aiccs.business.entity.dto.TaskListUnionDto;
import com.chinaweal.aiccs.aiccs.business.service.TSTaskListService;
import com.chinaweal.aiccs.aiccs.punishment.entity.EntLock;
import com.chinaweal.aiccs.aiccs.punishment.entity.Tolockentlist;
import com.chinaweal.aiccs.aiccs.punishment.entity.TsbizPunishLock;
import com.chinaweal.aiccs.aiccs.punishment.entity.excel.TolockentExcel;
import com.chinaweal.aiccs.aiccs.punishment.service.EntlockService;
import com.chinaweal.aiccs.aiccs.punishment.service.PersonlockService;
import com.chinaweal.aiccs.aiccs.punishment.service.TolockentlistService;
import com.chinaweal.aiccs.aiccs.punishment.service.TsbizPunishLockService;
import com.chinaweal.aiccs.aiccs.punishment.util.*;
import com.chinaweal.aiccs.aiccs.system.entity.TRBaseCode;
import com.chinaweal.aiccs.aiccs.system.service.TRBaseCodeService;
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.StringUtils;
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 io.swagger.annotations.ApiOperation;
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.LocalDate;
import java.util.*;


/**
 * <p>
 *  联合惩戒拟列入主体 前端控制器
 * </p>
 *
 * @author Lee
 * @since 2021-06-05
 */
@RestController
@RequestMapping("/tolockentlist")
public class TolockentlistController extends BaseController {

    @Autowired
    private TolockentlistService toLockEntListService;

    @Autowired
    private EntlockService entLockService;

    @Autowired
    private TSTaskListService taskListService;

    @Autowired
    private EBaseinfoService eBaseinfoService;

    @Autowired
    private BusTridMakeUtil busTridMakeUtil;

    @Autowired
    private TsbizPunishLockService tsbizPunishLockService;

    @Autowired
    private TolockentlistService tolockentlistService;

    @Autowired
    private TRBaseCodeService baseCodeService;

    @Autowired
    private TsbizPunishLockController tsbizPunishLockController;

    @Autowired
    private EntlockService entlockService;

    @Autowired
    private PersonlockService personlockService;

    @PostMapping("toLockEntListPage")
    public RestResult<?> toLockEntListPage(@RequestBody PageRequestDto pageRequestDto, HttpServletRequest request) {

        Map<String, Object> customParamMap = pageRequestDto.getCustomParamMap();

        AICUser curUser = getLoginUser(request);
        customParamMap = ParamUtils.getRegorg(customParamMap,curUser);

        String searchCode = "";
        String searchEntName = "";
        String searchPunishFrom = "";
        String unisicd = "";

        String regno = "";
        String punishDepartments = "";
        String regorg1 = "";
        String regorg2 = "";

        if(customParamMap != null){
            searchCode = StringUtils.tranObject(customParamMap.get("searchCode"));
            searchEntName = StringUtils.tranObject(customParamMap.get("searchEntName"));
            searchPunishFrom = StringUtils.tranObject(customParamMap.get("searchPunishFrom"));
            punishDepartments = StringUtils.tranObject(customParamMap.get("punishDepartments"));
            regorg1 = StringUtils.tranObject(customParamMap.get("regorg1"));
            regorg2 = StringUtils.tranObject(customParamMap.get("regorg2"));
        }


        if(StringUtils.isNotBlank(searchCode)){
            if(StringUtils.isUscc(searchCode)){
                unisicd = searchCode;
            }else {
                regno = searchCode;
            }
        }
/* 6月7日
        LambdaQueryWrapper<Tolockentlist> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(regno), Tolockentlist::getRegno,regno)
                .eq(StringUtils.isNotBlank(unisicd),Tolockentlist::getUniscid,unisicd)
                .like(StringUtils.isNotBlank(searchEntName),Tolockentlist::getEntName,searchEntName)
                .eq(StringUtils.isNotBlank(searchPunishFrom),Tolockentlist::getPunishFrom,searchPunishFrom)
                .eq(StringUtils.isNotBlank(punishDepartments),Tolockentlist::getDepartment,punishDepartments)
                .likeRight(StringUtils.isNotBlank(regorg1),Tolockentlist::getRegorg,regorg1)
                .eq(StringUtils.isNotBlank(regorg2),Tolockentlist::getRegorg,regorg2)
                .eq(Tolockentlist::getState,"0")
                .orderByDesc(Tolockentlist::getInsertTime).orderByDesc(Tolockentlist::getUniscid);

 */
        LambdaQueryWrapper<EBaseinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(regno), EBaseinfo::getRegno,regno)
                .eq(StringUtils.isNotBlank(unisicd),EBaseinfo::getUniscid,unisicd)
                .like(StringUtils.isNotBlank(searchEntName),EBaseinfo::getEntname,searchEntName);
        if(!"440101".equals(regorg1)){
            wrapper.eq(StringUtils.isNotBlank(regorg1),EBaseinfo::getRegorg,regorg1);
        }

        Page<EBaseinfo> page=eBaseinfoService.page(new Page<>(pageRequestDto.getCurPage(), pageRequestDto.getPageSize()), wrapper);
       //6月7日Page<Tolockentlist> page = toLockEntListService.page(new Page<>(pageRequestDto.getCurPage(), pageRequestDto.getPageSize()), wrapper);
        return RestResult.ok(page);

    }


    /**
     *  获取当前查询条件下的所有拟锁定主体
     * @param searchCode
     * @param searchEntName
     * @param searchPunishFrom
     * @return
     */
    @PostMapping("selectAllWithNopage")
    public RestResult<?> selectAllWithNopage(String searchCode, String searchEntName, String searchPunishFrom){
        String unisicd = "";
        String regno = "";
        ArrayList<String> pripids = new ArrayList<>();
        if(StringUtils.isNotBlank(searchCode)){
            if(StringUtils.isUscc(searchCode)){
                unisicd = searchCode;
            }else {
                regno = searchCode;
            }
        }
        LambdaQueryWrapper<Tolockentlist> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(regno), Tolockentlist::getRegno,regno)
                .eq(StringUtils.isNotBlank(unisicd),Tolockentlist::getUniscid,unisicd)
                .like(StringUtils.isNotBlank(searchEntName),Tolockentlist::getEntName,searchEntName)
                .eq(StringUtils.isNotBlank(searchPunishFrom),Tolockentlist::getPunishFrom,searchPunishFrom)
                .eq(Tolockentlist::getState,"0")
                .orderByDesc(Tolockentlist::getInsertTime);
        List<Tolockentlist> list = toLockEntListService.list(wrapper);
        return  RestResult.ok(list);
//        if(list.size() == 0){
//            return RestResult.ok(pripids);
//        }else {
//            for (Tolockentlist tolockentlist : list) {
//                pripids.add(tolockentlist.getPripid());
//            }
//            return RestResult.ok(pripids);
//        }
    }

    /**
     * 查询联合惩戒总数
     *
     * @author lwd
     * @since 2021年06月29日 17:23:56
     */
    @PostMapping("tolockentSize")
    @ApiOperation("联合惩戒总数")
    public RestResult<?> tolockentSize(String aicUserId) {


        Map<String,Object> resultMap = new HashMap<>();
        //企业异常名录列入
        String yclrStr = "61";
        List<TaskListUnionDto> yclr = taskListService.searchUnionTaskList(yclrStr,aicUserId);
        //企业异常名录异议
        String ycyyStr = "62";
        List<TaskListUnionDto> ycyy = taskListService.searchUnionTaskList(ycyyStr,aicUserId);

//        List<Tolockentlist> tolockentlistList = new ArrayList<>();
//        List<EntLock> entLockList = new ArrayList<>();
//        tolockentlistList = toLockEntListService.selectTolockentlistList();
//        entLockList = entLockService.selectEntLockList();
        resultMap.put("lhcjsd",yclr.size());
        resultMap.put("lhcjjs",ycyy.size());


        return RestResult.ok(resultMap);
    }

    @GetMapping("countNum")
    public RestResult<?> countNum() {
        Map resultMap = new HashMap();
        int tolockentlistNum = tolockentlistService.count(new LambdaQueryWrapper<Tolockentlist>()
                .eq(Tolockentlist::getState, "0"));   //未办
        int entlockNum = entLockService.count(new LambdaQueryWrapper<EntLock>()
                .eq(EntLock::getState, "1"));    //拟解锁
        resultMap.put("tolockentlistNum",tolockentlistNum);
        resultMap.put("entlockNum",entlockNum);
        return RestResult.ok(resultMap);
    }

//    @RequestMapping("downloadTemplate")
//    public RestResult<?> downloadTemplate(HttpServletRequest request, HttpServletResponse response){
//        try{
//            String host = request.getServerName();
//            int port = request.getServerPort();
//            String path = request.getContextPath() + "/template/Tolockent_list.xls";
//            URL url = new URL("http", host, port, path);
//            String result = new ExcelIePortUtils().download(url, "Tolockent_list.xls", response);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        return OK;
//    }

    /**
     * 联合惩戒excel导入校验
     * @param httpServletRequest
     * @param file
     * @return
     */
    @PostMapping("upload")
    public RestResult<?> upload(HttpServletRequest httpServletRequest, MultipartFile file){
        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 TolockentExcel(), 1, 1);
        Object objList = excelListener.getDatas();
        List<TolockentExcel> orderList = (List<TolockentExcel>) objList;
        //校验模板
        Map<Integer,String> headMap = excelListener.getMap();
        Map<String,String> checkMap = TolockentParamConstant.getMap("tolockent");
        if(checkMap.size() != headMap.size()){
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"上传模板错误!");
        }
        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,"上传模板错误!");
            }
        }
        String count = "";
        Map<String,Object> rs = new HashMap<>();
        List<TolockentExcel> failList = new ArrayList<>();
        List<String> successList = new ArrayList<>();
        Map<String, TRBaseCode> trBaseCodeMap = baseCodeService.getBaseCodeMapFormCache("CA19");
        //校验数据
        if(orderList.size()>0){
            count = String.valueOf(orderList.size());
            for(TolockentExcel tolockentExcel : orderList){
                if(StringUtils.isBlank(tolockentExcel.getUniscid())
                        && StringUtils.isBlank(tolockentExcel.getRegno())
                        && StringUtils.isBlank(tolockentExcel.getEntname())){
                    continue;
                }else{
                    LambdaQueryWrapper<EBaseinfo> wrapper = new LambdaQueryWrapper<>();
                    if(StringUtils.isNotBlank(tolockentExcel.getUniscid())){
                        wrapper.eq(EBaseinfo::getUniscid, tolockentExcel.getUniscid());
                    }
                    if(StringUtils.isNotBlank(tolockentExcel.getRegno())){
                        wrapper.eq(EBaseinfo::getRegno, tolockentExcel.getRegno());
                    }
                    if(StringUtils.isNotBlank(tolockentExcel.getEntname())){
                        wrapper.eq(EBaseinfo::getEntname, tolockentExcel.getEntname());
                    }
                    EBaseinfo eBaseinfos = eBaseinfoService.getOne(wrapper);
                    if(eBaseinfos!=null){
                        if(eBaseinfos.getRegstate().equals("1")) {
                            successList.add(eBaseinfos.getPripid());
                        }else {
                            tolockentExcel.setReason(trBaseCodeMap.get(eBaseinfos.getRegstate()) != null ?
                                    trBaseCodeMap.get(eBaseinfos.getRegstate()).getName() : "企业为非营业状态"); //存在004等数据
                            failList.add(tolockentExcel);
                        }
                    }else {
                        tolockentExcel.setReason("找不到对应主体");
                        failList.add(tolockentExcel);
                    }
                }
            }
        }else{
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"导入数据条数不能为0!");
        }
        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<TolockentExcel> 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(TolockentExcel.class).build();
            excelWriter.write(failList, writeSheet1);
            excelWriter.finish();
        } catch (IOException e) {
            outputStream.close();
            e.printStackTrace();
        } finally {
            outputStream.close();
        }
    }

    /**
     * 联合惩戒excel导入数据启动流程
     * @param uploadParam
     * @param request
     * @return
     */
    @Transactional
    @RequestMapping("saveAccept")
        public RestResult<?> saveAccept(@RequestBody String uploadParam, HttpServletRequest request) {
        JSONObject jsonObject = JSONObject.parseObject(uploadParam);
        String punishFrom = jsonObject.getString("uploadPublicFrom");
        String eBaseinfoListStr = jsonObject.getString("eBaseinfoList");
        List<String> eBaseinfoList = JSONObject.parseArray(eBaseinfoListStr,String.class);
        if(StringUtils.isBlank(punishFrom)){
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"惩戒来源不能为空!");
        }
        if(eBaseinfoList.size()==0){
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"没有符合导入条件的主体!");
        }
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i<eBaseinfoList.size(); i++) {
            if (i == eBaseinfoList.size()-1) {
                builder.append(eBaseinfoList.get(i));
            } else {
                builder.append(eBaseinfoList.get(i) + ";");
            }
        }
        return startAccept(builder.toString(), punishFrom, request);
    }

    /**
     * 单条新增
     * @param eBaseinfo
     * @param punishFrom
     * @param request
     * @return
     */
    @Transactional
    @RequestMapping("saveOneAndAccept")
    public RestResult<?> saveOneAndAccept(EBaseinfo eBaseinfo, String punishFrom, HttpServletRequest request) {
        LambdaQueryWrapper<EBaseinfo> wrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(eBaseinfo.getUniscid())){
            wrapper.eq(EBaseinfo::getUniscid, eBaseinfo.getUniscid());
        }
        EBaseinfo eachEBaseinfo = eBaseinfoService.getOne(wrapper);
        if(StringUtils.isBlank(punishFrom)){
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"惩戒来源不能为空!");
        }
        if(eachEBaseinfo == null){
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,"找不到对应主体!");
        }
        Map<String, TRBaseCode> trBaseCodeMap = baseCodeService.getBaseCodeMapFormCache("CA19");
        if(!eachEBaseinfo.getRegstate().equals("1")){
            String reason = trBaseCodeMap.get(eachEBaseinfo.getRegstate()) != null ?
                    "该企业为" + trBaseCodeMap.get(eachEBaseinfo.getRegstate()).getName() : "企业为非营业状态";
            return RestResult.error(ResultCode.BUSINESS_LOGIC_ERROR,reason);
        }
        return startAccept(eachEBaseinfo.getPripid(),punishFrom,request);
    }

    public RestResult<?> startAccept(String pripids, String punishFrom, HttpServletRequest request){
        String[] pripidArray = pripids.split(Constant.SEMICOLON);
        LambdaQueryWrapper<EBaseinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(EBaseinfo::getPripid, pripidArray);
        for (int i = 0; i < pripidArray.length; i++) {
            if(tsbizPunishLockService.checkpunishlock(pripidArray[i])){
                return RestResult.error(ResultCode.BUSINESS_ASSOCIATED,"该主体已存在锁定业务中");
            }
            LambdaQueryWrapper<EBaseinfo> eBaseinfoWrapper=new LambdaQueryWrapper<>();
            eBaseinfoWrapper.eq(EBaseinfo::getPripid, pripidArray[i]);
            EBaseinfo one = eBaseinfoService.getOne(eBaseinfoWrapper);
            if(entlockService.check(pripidArray[i])!=null&&!"3".equals(entlockService.check(pripidArray[i]).getState())){
                return RestResult.error(ResultCode.BUSINESS_ASSOCIATED,"该主体还在锁定中");
            }

            if(personlockService.check(one.getLerep())!=null&&"1".equals(personlockService.check(one.getLerep()).getLockstate())){
                return RestResult.error(ResultCode.BUSINESS_ASSOCIATED,"该法人还在锁定中");
            }
        }
        List<EBaseinfo> eBaseinfos = eBaseinfoService.list(wrapper);

        //办理联合惩戒流程逻辑
        AICUser aicUser = getLoginUser(request);
        //生成业务号
        String bizSeq = UUID.randomUUID().toString();

        ArrayList<TsbizPunishLock> tsbizPunishLocks = new ArrayList<>();

        for (int i = 0; i < eBaseinfos.size(); i++) {
            EBaseinfo eachEBaseinfo = eBaseinfos.get(i);
            TsbizPunishLock tsbizPunishLockModel = new TsbizPunishLock();
            tsbizPunishLockModel.setBizseq(bizSeq);
            tsbizPunishLockModel.setPripid(eachEBaseinfo.getPripid());
            tsbizPunishLockModel.setRegno(eachEBaseinfo.getRegno());
            tsbizPunishLockModel.setUniscid(eachEBaseinfo.getUniscid());
            tsbizPunishLockModel.setEntname(eachEBaseinfo.getEntname());
            tsbizPunishLockModel.setApprovaldate(LocalDate.now());
            tsbizPunishLockModel.setPunishFrom(punishFrom);
//            tsbizPunishLockModel.setPunishInfoId(tolockentlist.getPunishInfoId());  //punishInfoId 为空则为导入
            tsbizPunishLocks.add(tsbizPunishLockModel);
        }
        if (tsbizPunishLocks.size() == 0) throw new BusinessException("尚未查找到主体信息");
        //待办
        TSTaskList taskListModel = new TSTaskList();
        taskListModel.setBizseqid(bizSeq);
        taskListModel.setBustype(BaseDataConstant.PUNISH_TYPE_LOCK);
        //封装待办业务名称
        String entname = "联合惩戒锁定"+busTridMakeUtil.getLockCurAcceptNo();
        taskListModel.setBusname(entname);
        taskListModel = tsbizPunishLockService.savePunishLockAccept(aicUser, taskListModel, tsbizPunishLocks, null);
        //taskListModel = tsbizPunishLockService.savePunishLockAccept(aicUser, taskListModel, tsbizPunishLocks);

        if (StringUtils.isNotBlank(taskListModel.getTasklistid())) {
            Map<String, String> result = new HashMap<>();
            result.put("tasklistid", taskListModel.getTasklistid());
            result.put("bizseq", bizSeq);
            result.put("workflowId", taskListModel.getWorkflowid());
            return RestResult.ok(result);
        }
        return OK;
    }

    @RequestMapping("queryOne")
    public RestResult<?> queryOne(EBaseinfo eBaseinfo) {
        LambdaQueryWrapper<EBaseinfo> wrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(eBaseinfo.getUniscid())){
            wrapper.eq(EBaseinfo::getUniscid, eBaseinfo.getUniscid());
        }
        EBaseinfo eachEBaseinfo = eBaseinfoService.getOne(wrapper);
        return RestResult.ok(eachEBaseinfo);
    }

    @PostMapping("/groupDepart")
    public RestResult<?> groupDepart(@RequestBody PageRequestDto pageRequestDto) {

        Map<String, Object> customParamMap = pageRequestDto.getCustomParamMap();

        List<Map> maps = tolockentlistService.groupDepart(customParamMap);
        return RestResult.ok(maps);
    }


    @PostMapping("/list")
    public RestResult<?> list(@RequestBody Map<String, Object> data) {
        int size = (int) data.getOrDefault("size", 10);
        int current = (int) data.getOrDefault("current", 1);
        String department = (String) data.getOrDefault("department", null);
        List<String> states = (List) data.getOrDefault("states", null);
        LambdaQueryWrapper<Tolockentlist> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(department), Tolockentlist::getDepartment, department);
        lqw.in(states != null, Tolockentlist::getState, states);
        Page<Tolockentlist> page = tolockentlistService.page(new Page<>(current, size), lqw);
        return RestResult.ok(page);
    }
}

