package org.jeecg.modules.stm.risk.event.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.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.stm.act.main.entity.StCaMainLable;
import org.jeecg.modules.stm.act.main.service.IStCaMainLableService;
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.risk.event.entity.StRiskEvent;
import org.jeecg.modules.stm.risk.event.entity.StRiskEventLable;
import org.jeecg.modules.stm.risk.event.mapper.StRiskEventMapper;
import org.jeecg.modules.stm.risk.event.service.IStRiskEventService;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.stm.risk.event.service.IStRiskEventLableService;
import org.jeecg.modules.stm.risk.event.vo.StRiskEventVo;
import org.jeecg.modules.stm.risk.scenario.entity.StRiskScenario;
import org.jeecg.modules.stm.risk.scenario.service.IStRiskScenarioService;
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.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 风险事件
 * @Author: yzh
 * @Date:   2023-03-05
 * @Version: V1.0
 */
@Service
public class StRiskEventServiceImpl extends ServiceImpl<StRiskEventMapper, StRiskEvent> implements IStRiskEventService {

    private static final String NO_PRE = "SJ";
    private static final  int NO_SIZE = 5;

    @Autowired
    private IStRiskScenarioService iStRiskScenarioService;

    @Autowired
    private ISysDictService iSysDictService;

    @Autowired
    private IStCaMainLableService iStCaMainLableService;

    @Autowired
    private IStRiskEventLableService iStRiskEventLableService;

    @Autowired
    private IStLableService iStLableService;

    private String bizNo(){
        QueryWrapper<StRiskEvent> wapper = new QueryWrapper();
        wapper.orderByDesc("RISK_EVENT_NO");
        wapper.last("limit 1");
        StRiskEvent noUpper = super.baseMapper.selectOne(wapper);
        if(noUpper == null) {
            return NO_PRE+ StringUtils.leftPad("1",NO_SIZE,"0");
        }else{
            // 如果不为空+1
            int no  = Integer.valueOf(noUpper.getRiskEventNo().replace(NO_PRE,""))+1;
            String str = ""+no;
            return  NO_PRE+StringUtils.leftPad(str,NO_SIZE,"0");
        }
    }

    private void checkName(StRiskEvent entity, boolean isSave){
        if(entity==null){
            return;
        }
        QueryWrapper<StRiskEvent> wapper = new QueryWrapper<>();
        wapper.eq("RISK_EVENT_NAME",entity.getRiskEventName());
        if(!isSave){
            wapper.ne("ID",entity.getId());
        }
        long count = super.count(wapper);
        if(count>0){
            throw new JeecgBootException("风险事件名称已存在");
        }
    }

    @Override
    public boolean save(StRiskEvent entity) {
        checkName(entity,true);
        String no = bizNo();
        StRiskEventVo vo = (StRiskEventVo) entity;
        StRiskEvent stRiskEvent = new StRiskEvent();
        BeanUtils.copyProperties(entity,stRiskEvent);
        stRiskEvent.setRiskEventNo(no);
        stRiskEvent.setCreatedUser(UserUtil.getUserCode());
        stRiskEvent.setApproveFlag(StmConstans.DEFAULT_APPROVE_Flag);
        stRiskEvent.setValid(StmConstans.DEFAULT_VALID);
        saveLableCode(stRiskEvent,vo.getLableList());
        return super.save(stRiskEvent);
    }

    private void saveLableCode(StRiskEvent stRiskEvent, String lableList) {
        if(StringUtils.isNotEmpty(lableList)){
            String[] lableCodes = lableList.split(",");
            List<StRiskEventLable> list = new ArrayList<>();
            for(String  lableCode:lableCodes){
                StRiskEventLable stRiskEventLable = new StRiskEventLable();
                stRiskEventLable.setRiskEventNo(stRiskEvent.getRiskEventNo());
                stRiskEventLable.setLableCode(lableCode);
                stRiskEventLable.setValid(StmConstans.DEFAULT_VALID);
                stRiskEventLable.setCreatedUser(stRiskEvent.getCreatedUser());
                stRiskEventLable.setUpdatedUser(stRiskEvent.getUpdatedUser());
                list.add(stRiskEventLable);
            }
            iStRiskEventLableService.saveBatch(list);
        }
    }

    @Override
    public boolean updateById(StRiskEvent entity) {
        checkName(entity,false);
        StRiskEventVo vo = (StRiskEventVo) entity;
        StRiskEvent stRiskEvent = new StRiskEvent();
        BeanUtils.copyProperties(entity,stRiskEvent);
        stRiskEvent.setUpdatedUser(UserUtil.getUserCode());
        updateLableCodes(stRiskEvent,vo.getLableList());
        return super.updateById(entity);
    }
    private void deleteLableCodes(StRiskEvent stRiskEvent){
        QueryWrapper<StRiskEventLable> wrapper = new QueryWrapper<StRiskEventLable>();
        wrapper.eq("RISK_EVENT_NO",stRiskEvent.getRiskEventNo());
        iStRiskEventLableService.remove(wrapper);
    }
    private void updateLableCodes(StRiskEvent stRiskEvent, String lableList) {
        deleteLableCodes(stRiskEvent);
        this.saveLableCode(stRiskEvent,lableList);
    }

    @Override
    public <E extends IPage<StRiskEvent>> E page(E page, Wrapper<StRiskEvent> queryWrapper) {
        IPage<StRiskEvent> iPage = super.page(page, queryWrapper);
        List<StRiskEvent> data = iPage.getRecords();
        List<StRiskEvent> records = new ArrayList<>();
        for(StRiskEvent stRiskEvent:data){
            StRiskEventVo stRiskEventVo = new StRiskEventVo();
            BeanUtils.copyProperties(stRiskEvent,stRiskEventVo);
            StRiskScenario stRiskScenario = iStRiskScenarioService.queryByScenarioNo(stRiskEvent.getScenarioNo());
            if(stRiskScenario!=null) {
                stRiskEventVo.setScenarioName(stRiskScenario.getScenarioName());
                String name = iSysDictService.queryDictTextByKey("applyobj",stRiskScenario.getApplicableCode());
                if(StringUtils.isNotEmpty(name)) {
                    stRiskEventVo.setApplicableName(name);
                }else{
                    stRiskEventVo.setApplicableName("-");
                }
            }else{
                stRiskEventVo.setScenarioName("-");
            }
            String name = iSysDictService.queryDictTextByKey("eventclassify",stRiskEvent.getEventClassify());
            if(StringUtils.isNotEmpty(name)) {
                stRiskEventVo.setEventClassifyName(name);
            }else{
                stRiskEventVo.setEventClassifyName("-");
            }
            QueryWrapper<StRiskEventLable> stRiskEventLableQueryWrapper = new QueryWrapper<>();
            stRiskEventLableQueryWrapper.eq("RISK_EVENT_NO",stRiskEvent.getRiskEventNo());
            List<StRiskEventLable> stRiskEventLables = iStRiskEventLableService.list(stRiskEventLableQueryWrapper);
            if(CollectionUtils.isEmpty(stRiskEventLables)){
               stRiskEventVo.setLableList("");
            }else{
                List<String> lableCodes = stRiskEventLables.stream().map(StRiskEventLable::getLableCode).collect(Collectors.toList());
                stRiskEventVo.setLableList(StringUtils.join(lableCodes,","));
                List<StLable> stLableList = iStLableService.listByCods(lableCodes);
                if(!CollectionUtils.isEmpty(stLableList)){
                    List<String> lableNames = stLableList.stream().map(StLable::getLableName).collect(Collectors.toList());
                    stRiskEventVo.setLableNameList(lableNames);
                }
            }
            records.add(stRiskEventVo);
        }
        iPage.setRecords(records);
        return (E) iPage;
    }

    @Override
    public IPage<StRiskEvent> defPage(StRiskEvent stRiskEvent, Integer pageNo, Integer pageSize, Map<String, String[]> parameterMap) {
        QueryWrapper<StRiskEvent> queryWrapper = QueryGenerator.initQueryWrapper(stRiskEvent, parameterMap);
        String [] scenarioName = parameterMap.get("scenarioName");
        String [] applicableCode = parameterMap.get("applicableCode");
        String [] caNos = parameterMap.get("caNo");
        QueryWrapper<StRiskScenario> stRiskScenarioQueryWrapper = new QueryWrapper<>();
        boolean queryFlag = false;
        if(scenarioName!=null && scenarioName.length ==1 &&StringUtils.isNotEmpty(scenarioName[0])){
            stRiskScenarioQueryWrapper.like("SCENARIO_NAME",scenarioName[0]);
            queryFlag = true;
        }
        if(applicableCode!=null && applicableCode.length ==1 &&StringUtils.isNotEmpty(applicableCode[0])){
            stRiskScenarioQueryWrapper.eq("APPLICABLE_CODE",applicableCode[0]);
            queryFlag = true;
        }
        if(queryFlag){
           List<StRiskScenario>  stRiskScenarioList = iStRiskScenarioService.list(stRiskScenarioQueryWrapper);
           if(CollectionUtils.isEmpty(stRiskScenarioList)){
               queryWrapper.eq("SCENARIO_NO","notexist");
           }else{
               List<String> scenarioNos = stRiskScenarioList.stream().map(StRiskScenario::getScenarioNo).collect(Collectors.toList());
               queryWrapper.in("SCENARIO_NO",scenarioNos);
           }
        }
        List<String> lableCodesList = QueryLableParamsUtlis.getLableCodes(parameterMap);
        lableCodes(lableCodesList,queryWrapper);
        // 控制活动关联的查询
        if(caNos!=null && caNos.length == 1 && StringUtils.isNotEmpty(caNos[0])){
            QueryWrapper<StCaMainLable> stCaMainLableQueryWrapper = new QueryWrapper<>();
            stCaMainLableQueryWrapper.eq("CA_NO",caNos[0]);
            List<StCaMainLable> lables =  iStCaMainLableService.list(stCaMainLableQueryWrapper);
            if(!CollectionUtils.isEmpty(lables)){
              List<String> lableCodes = lables.stream().map(StCaMainLable::getLableCode).collect(Collectors.toList());
              lableCodes(lableCodes,queryWrapper);
            }else{
                queryWrapper.in("RISK_EVENT_NO","notexist");
            }
        }
        Page<StRiskEvent> page = new Page<StRiskEvent>(pageNo, pageSize);
        return this.page(page,queryWrapper);
    }

    private void lableCodes( List<String> lableCodesList,QueryWrapper<StRiskEvent> queryWrapper){
        if(lableCodesList!=null && lableCodesList.size() == 0){
            queryWrapper.eq("RISK_EVENT_NO","notExist");
        }else if(!CollectionUtils.isEmpty(lableCodesList)){
            if(lableCodesList.size()==1 && "notExist".equals(lableCodesList.get(0))){
                queryWrapper.eq("RISK_EVENT_NO","notExist");
            }else {
                QueryWrapper<StRiskEventLable> stRiskEventWrapper = new QueryWrapper<>();
                stRiskEventWrapper.in("LABLE_CODE",lableCodesList);
                List<StRiskEventLable> stRiskEventLables  = iStRiskEventLableService.list(stRiskEventWrapper);
                if(CollectionUtils.isEmpty(stRiskEventLables)){
                    queryWrapper.eq("RISK_EVENT_NO","notExist");
                }else{
                    List<String> eventNos = stRiskEventLables.stream().map(StRiskEventLable::getRiskEventNo).collect(Collectors.toList());
                    queryWrapper.in("RISK_EVENT_NO",eventNos);
                }
            }
        }
    }
    @Override
    public StRiskEventVo queryVoByRiskNo(String riskNo) {
        QueryWrapper<StRiskEvent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("RISK_EVENT_NO",riskNo);
        StRiskEvent stRiskEvent = this.baseMapper.selectOne(queryWrapper);
        if(stRiskEvent!=null) {
            StRiskEventVo stRiskEventVo = new StRiskEventVo();
            BeanUtils.copyProperties(stRiskEvent, stRiskEventVo);
            StRiskScenario stRiskScenario = iStRiskScenarioService.queryByScenarioNo(stRiskEvent.getScenarioNo());
            if (stRiskScenario != null) {
                stRiskEventVo.setScenarioName(stRiskScenario.getScenarioName());
            }
            String name = iSysDictService.queryDictTextByKey("eventclassify",stRiskEvent.getEventClassify());
            if(StringUtils.isNotEmpty(name)) {
                stRiskEventVo.setEventClassifyName(name);
            }else{
                stRiskEventVo.setEventClassifyName("-");
            }
            QueryWrapper<StRiskEventLable> stRiskEventLableQueryWrapper = new QueryWrapper<>();
            stRiskEventLableQueryWrapper.eq("RISK_EVENT_NO",stRiskEvent.getRiskEventNo());
            List<StRiskEventLable> stRiskEventLables = iStRiskEventLableService.list(stRiskEventLableQueryWrapper);
            if(CollectionUtils.isEmpty(stRiskEventLables)){
                stRiskEventVo.setLableList("");
            }else{
                List<String> lableCodes = stRiskEventLables.stream().map(StRiskEventLable::getLableCode).collect(Collectors.toList());
                stRiskEventVo.setLableList(StringUtils.join(lableCodes,","));
                List<StLable> stLableList = iStLableService.listByCods(lableCodes);
                if(!CollectionUtils.isEmpty(stLableList)){
                    List<String> lableNames = stLableList.stream().map(StLable::getLableName).collect(Collectors.toList());
                    stRiskEventVo.setLableNameList(lableNames);
                }
            }
            return stRiskEventVo;
        }
        return null;
    }

    @Override
    public long countBylables(List<StCaMainLable> lables) {
        QueryWrapper queryWrapper = new QueryWrapper<StRiskEvent>();
        if(CollectionUtils.isEmpty(lables)){
            return 0;
        }
        List<String> lableCodes = lables.stream().
                map(StCaMainLable::getLableCode).collect(Collectors.toList());
        this.lableCodes(lableCodes,queryWrapper);
        return this.count(queryWrapper);
    }

    @Override
    public boolean removeById(Serializable id) {
        StRiskEvent stRiskEvent = super.getById(id);
        deleteLableCodes(stRiskEvent);
        return super.removeById(id);
    }
}
