package org.jeecg.modules.stm.compliane.info.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.system.entity.SysDictItem;
import org.jeecg.modules.system.service.ISysDictItemService;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.jeecg.modules.stm.base.lable.entity.StLable;
import org.jeecg.modules.stm.base.lable.service.IStLableService;
import org.jeecg.modules.stm.compliane.info.constant.ComplianeClass;
import org.jeecg.modules.stm.compliane.info.entity.StComplianeInfo;
import org.jeecg.modules.stm.compliane.info.entity.StComplianeLable;
import org.jeecg.modules.stm.compliane.info.entity.StComplianeRangeCodes;
import org.jeecg.modules.stm.compliane.info.mapper.StComplianeInfoMapper;
import org.jeecg.modules.stm.compliane.info.service.IStComplianeInfoService;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.stm.compliane.info.service.IStComplianeLableService;
import org.jeecg.modules.stm.compliane.info.service.IStComplianeRangeCodesService;
import org.jeecg.modules.stm.compliane.info.vo.StComplianeInfoVo;
import org.jeecg.modules.stm.compliane.item.entity.StComplianeItem;
import org.jeecg.modules.stm.compliane.item.service.IStComplianeItemService;
import org.jeecg.modules.stm.utils.QueryLableParamsUtlis;
import org.jeecg.modules.stm.utils.StmConstans;
import org.jeecg.modules.stm.utils.UserUtil;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 合规库
 * @Author: yzh
 * @Date:   2023-03-05
 * @Version: V1.0
 */
@Service
public class StComplianeInfoServiceImpl extends ServiceImpl<StComplianeInfoMapper, StComplianeInfo> implements IStComplianeInfoService {
    @Autowired
    private ISysDictService iSysDictService;

    @Autowired
    private IStComplianeItemService stComplianeItemService;

    @Autowired
    private IStComplianeLableService stComplianeLableService;

    @Autowired
    private IStComplianeRangeCodesService stComplianeRangeCodesService;

    @Autowired
    private IStLableService iStLableService;

    private String complianeInfoNo(String classType){
        QueryWrapper<StComplianeInfo> wapper = new QueryWrapper();
        wapper.eq("compliane_class",classType);
        wapper.orderByDesc("compliane_no");
        wapper.last("limit 1");
        StComplianeInfo noUpper = super.baseMapper.selectOne(wapper);
        String pre = ComplianeClass.CLASS_NO_PREFIX.get(classType);
        if(noUpper == null) {
            return pre+ StringUtils.leftPad("1",ComplianeClass.NO_LENGTH,"0");
        }else{
            // 如果不为空+1
            int no  = Integer.valueOf(noUpper.getComplianeNo().replace(pre,""))+1;
            String str = ""+no;
            return  pre+StringUtils.leftPad(str,ComplianeClass.NO_LENGTH,"0");
        }
    }
    private void checkName(StComplianeInfo entity, boolean isSave){
        if(entity==null){
            return;
        }
        QueryWrapper<StComplianeInfo> wapper = new QueryWrapper<>();
        wapper.eq("FILE_NAME",entity.getFileName());
        if(!isSave){
            wapper.ne("ID",entity.getId());
        }
        long count = super.count(wapper);
        if(count>0){
            throw new JeecgBootException("文件名称已存在");
        }
    }

    private void saveOrUpdateCodes(StComplianeInfoVo stComplianeInfoVo){
        String rangeCodestr = stComplianeInfoVo.getApplyRangeCodestr();
        if(StringUtils.isEmpty(rangeCodestr)){
            throw new JeecgBootException("适用范围未选择");
        }
        List<String> rangeCodes = Arrays.asList(rangeCodestr.split(","));
        stComplianeRangeCodesService.saveBatchCodes(rangeCodes,stComplianeInfoVo.getComplianeNo());
        // 如果是处罚库有标签信息
        if(ComplianeClass.CF.equals(stComplianeInfoVo.getComplianeClass())){
            String labelCodestr = stComplianeInfoVo.getLabelCodestr();
            if(StringUtils.isEmpty(labelCodestr)){
                throw new JeecgBootException("标签未选择");
            }
            List<String> lableCodes = Arrays.asList(labelCodestr.split(","));
            stComplianeLableService.saveBatchCodes(lableCodes,stComplianeInfoVo.getComplianeNo());
        }
    }
    @Override
    public boolean save(StComplianeInfo entity) {
        checkName(entity,true);
        String no = complianeInfoNo(entity.getComplianeClass());
        entity.setComplianeNo(no);
        entity.setCreatedUser(UserUtil.getUserCode());
        entity.setApproveFlag(StmConstans.DEFAULT_APPROVE_Flag);
        entity.setValid(StmConstans.DEFAULT_VALID);
        entity.setStatus(ComplianeClass.FILE_STATYS);
        if(entity instanceof StComplianeInfoVo){
            StComplianeInfoVo stComplianeInfoVo = (StComplianeInfoVo) entity;
            this.saveOrUpdateCodes(stComplianeInfoVo);
        }
        return super.save(entity);
    }

    @Override
    public boolean updateById(StComplianeInfo entity) {
        checkName(entity,false);
        entity.setUpdatedUser(UserUtil.getUserCode());
        if(entity instanceof StComplianeInfoVo){
            StComplianeInfoVo stComplianeInfoVo = (StComplianeInfoVo) entity;
            this.saveOrUpdateCodes(stComplianeInfoVo);
        }
        return super.updateById(entity);
    }
    public void assignComplianeInfoVo(StComplianeInfoVo stComplianeInfoVo){
       String complianeNo = stComplianeInfoVo.getComplianeNo();
       QueryWrapper<StComplianeRangeCodes> rangeCodesQueryWrapper = new QueryWrapper<>();
       rangeCodesQueryWrapper.eq("COMPLIANE_NO",complianeNo);
       List<StComplianeRangeCodes> rangeCodes = stComplianeRangeCodesService.list(rangeCodesQueryWrapper);
       if(!CollectionUtils.isEmpty(rangeCodes)){
           List<String> codes = new ArrayList<>();
           List<String> codeNames = new ArrayList<>();
           for(StComplianeRangeCodes item:rangeCodes){
               codes.add(item.getApplyRangeCode());
               String text = iSysDictService.queryDictTextByKey("applyrange",item.getApplyRangeCode());
                if(StringUtils.isNotEmpty(text)) {
                    codeNames.add(text);
                }
           }
           stComplianeInfoVo.setApplyRangeCodes(codes);
           stComplianeInfoVo.setApplyRangeCodestr(StringUtils.join(codes,","));
           stComplianeInfoVo.setApplyRangeNames(codeNames);
           stComplianeInfoVo.setApplyRangeNamestr(StringUtils.join(codeNames,"、"));
       }
        if(ComplianeClass.CF.equals(stComplianeInfoVo.getComplianeClass())){
            QueryWrapper<StComplianeLable> lableQueryWrapper = new QueryWrapper<>();
            lableQueryWrapper.eq("COMPLIANE_NO",complianeNo);
            List<StComplianeLable> lableList = stComplianeLableService.list(lableQueryWrapper);
            if(!CollectionUtils.isEmpty(lableList)){
                List<String> codes = new ArrayList<>();
                for(StComplianeLable item:lableList){
                    codes.add(item.getLableCode());
                }
                List<StLable> lables = iStLableService.listByCods(codes);
                List<String> lableNames = lables.stream().map(StLable::getLableName).collect(Collectors.toList());
                stComplianeInfoVo.setLabelCodes(codes);
                stComplianeInfoVo.setLabelCodestr(StringUtils.join(codes,","));
                stComplianeInfoVo.setLabelNames(lableNames);
            }
        }
    }
    @Override
    public <E extends IPage<StComplianeInfo>> E page(E page, Wrapper<StComplianeInfo> queryWrapper) {
        IPage<StComplianeInfo> stComplianeInfoIPage = super.page(page, queryWrapper);
        List<StComplianeInfo> data = stComplianeInfoIPage.getRecords();
        List<StComplianeInfo> records = new ArrayList<>();
        for(StComplianeInfo stComplianeInfo:data){
            StComplianeInfoVo stComplianeInfoVo = new StComplianeInfoVo();
            BeanUtils.copyProperties(stComplianeInfo,stComplianeInfoVo);
            assignComplianeInfoVo(stComplianeInfoVo);
            String stausName = iSysDictService.queryDictTextByKey("filestatus",stComplianeInfo.getStatus());
            if(StringUtils.isNotEmpty(stausName)) {
                stComplianeInfoVo.setStatusName(stausName);
            }else{
                stComplianeInfoVo.setStatusName("-");
            }
            records.add(stComplianeInfoVo);
        }
        stComplianeInfoIPage.setRecords(records);
        return (E) stComplianeInfoIPage;
    }

    @Override
    public boolean removeById(Serializable id) {
        StComplianeInfo stComplianeInfo = super.getById(id);
        if(stComplianeInfo!=null) {
            QueryWrapper<StComplianeItem> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("COMPLIANE_NO",stComplianeInfo.getComplianeNo());
            stComplianeItemService.remove(queryWrapper);
        }
        return super.removeById(id);
    }

    @Override
    public IPage<StComplianeInfo> defPageListAll(StComplianeInfo stComplianeInfo, Integer pageNo, Integer pageSize, Map<String, String[]> parameterMap) {
        String [] checkStatus = parameterMap.get("checkStatus[]");
        String [] checkDates = parameterMap.get("checkDates[]");
        String [] checkClassifys = parameterMap.get("checkClassifys[]");
        QueryWrapper<StComplianeInfo> queryWrapper = QueryGenerator.initQueryWrapper(stComplianeInfo, parameterMap);
        if(checkStatus!=null && checkStatus.length>0 && !"all".equals(checkStatus[0])){
            queryWrapper.in("STATUS",checkStatus);
        }
        if(checkDates!=null && checkDates.length>0 && !"all".equals(checkDates[0])){
            int check = 0;
            int threeYearbef = 0;
            for(String item : checkDates){
                if("4".equals(item)){
                    threeYearbef = Integer.valueOf(item);
                    continue;
                }
                // 近一年 近两年 近三年 取最大的关系
                if(check < Integer.valueOf(item)){
                    check = Integer.valueOf(item);
                }
            }
            // 三年以上和近三年就是全部的时间
            if(threeYearbef ==4 && check == 3){
            }else{
                if(check>0 && threeYearbef==0) {
                    queryWrapper.ge("ISSUED_TIME",DateUtils.addYears(new Date(), 0-check));
                }else if(check ==0 && threeYearbef>0){
                    queryWrapper.le("ISSUED_TIME",DateUtils.addYears(new Date(), 1-threeYearbef));
                }else{
                    final Date jDate = DateUtils.addYears(new Date(), 0-check);
                    final Date afDate = DateUtils.addYears(new Date(), 1-threeYearbef);
                    queryWrapper.and(wq->{
                        wq.ge("ISSUED_TIME",jDate)
                                .or()
                                .le("ISSUED_TIME",afDate);
                    });
                }
            }
        }
        if(checkClassifys!=null && checkClassifys.length>0 && !"all".equals(checkClassifys[0])){
           // List<String> classifysList = Arrays.stream(checkClassifys).collect(Collectors.toList());
            queryWrapper.in("COMPLIANE_CLASS",checkClassifys);
        }
        Page<StComplianeInfo> page = new Page<StComplianeInfo>(pageNo, pageSize);
        return this.page(page,queryWrapper);
    }

    @Override
    public IPage<StComplianeInfo> defPage(StComplianeInfo stComplianeInfo, Integer pageNo, Integer pageSize, Map<String, String[]> parameterMap) {
        QueryWrapper<StComplianeInfo> queryWrapper = QueryGenerator.initQueryWrapper(stComplianeInfo, parameterMap);
        String [] applyRangeCodes = parameterMap.get("applyRangeCode");
        String [] rangeIssuedTimes = parameterMap.get("rangeIssuedTime");
        List<String> complianeNos = null;
        boolean applyFlag = false;
        if(applyRangeCodes!=null){
            String applyRangeCode = applyRangeCodes[0];
            if(StringUtils.isNotEmpty(applyRangeCode)) {
                QueryWrapper<StComplianeRangeCodes> codesQueryWrapper = new QueryWrapper<>();
                codesQueryWrapper.eq("apply_range_code", applyRangeCode);
                List<StComplianeRangeCodes> rangeCodes = stComplianeRangeCodesService.list(codesQueryWrapper);
                if (!CollectionUtils.isEmpty(rangeCodes)) {
                    complianeNos = rangeCodes.stream().map(StComplianeRangeCodes::getComplianeNo).collect(Collectors.toList());
                    applyFlag = true;
                } else {
                    return null;
                }
            }
        }

        if(ComplianeClass.CF.equals(stComplianeInfo.getComplianeClass())){
            List<String> labelCodes = QueryLableParamsUtlis.getLableCodes(parameterMap);
            Collection<String> queryComplianeNos;
            boolean labelFlag =false;
            if(!CollectionUtils.isEmpty(labelCodes)){
                if(labelCodes.size()==1 && "notExist".equals(labelCodes.get(0))){
                    return null;
                }else {
                    QueryWrapper<StComplianeLable> stComplianeLableQueryWrapper = new QueryWrapper<>();
                    stComplianeLableQueryWrapper.in("LABLE_CODE",labelCodes);
                    List<StComplianeLable> stComplianeLableList = stComplianeLableService.list(stComplianeLableQueryWrapper);
                    if(CollectionUtils.isEmpty(stComplianeLableList)){
                        return null;
                    }else{
                        List<String> complianeNos2 = stComplianeLableList.stream().map(StComplianeLable::getComplianeNo).collect(Collectors.toList());
                        if(CollectionUtils.isEmpty(complianeNos2)){
                            return null;
                        }else {
                            if (applyFlag) {
                                queryComplianeNos = org.apache.commons.collections.CollectionUtils.retainAll(complianeNos, complianeNos2);
                            }else{
                                queryComplianeNos = complianeNos2;
                            }
                        }
                    }
                    if(CollectionUtils.isEmpty(queryComplianeNos)){
                        return null;
                    }
                    queryWrapper.in("COMPLIANE_NO",queryComplianeNos);
                    labelFlag = true;
                }
            }
            if(!labelFlag && applyFlag){
                queryWrapper.in("COMPLIANE_NO",complianeNos);
            }



        }else{
            if(applyFlag && !CollectionUtils.isEmpty(complianeNos)) {
                queryWrapper.in("COMPLIANE_NO", complianeNos);
            }
        }


        if(rangeIssuedTimes!=null) {
            String rangeIssuedTime = rangeIssuedTimes[0];
            if(!rangeIssuedTime.equals("")) {
                String[] tmpAry = rangeIssuedTime.split(",");
                if(tmpAry.length==2) {
                    queryWrapper.between("issued_time", tmpAry[0], tmpAry[1]);
                }
            }

        }

        Page<StComplianeInfo> page = new Page<StComplianeInfo>(pageNo, pageSize);
        return this.page(page,queryWrapper);
    }

    @Override
    public List<StComplianeInfo> findStComplianInfoWithFile() {
        QueryWrapper<StComplianeInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNotNull("file_upload_path");
        List<StComplianeInfo> list = this.list(queryWrapper);
        return list;
    }

    @Override
    public List<Map<String,Object>> queryAllStComplianeItems(){

        return this.baseMapper.queryAllStComplianeItems();
    }
}
