package com.prolog.rdc.tms.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.common.util.DateUtils;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.SeriaNnumberConstant;
import com.prolog.rdc.tms.dao.mapper.SysGroupCfgDtlMapper;
import com.prolog.rdc.tms.dao.mapper.SysGroupCfgHdrMapper;
import com.prolog.rdc.tms.model.dto.SysGroupCfgDtlDTO;
import com.prolog.rdc.tms.model.dto.SysGroupCfgHdrDTO;
import com.prolog.rdc.tms.model.entity.SysGroupCfgDtlModel;
import com.prolog.rdc.tms.model.entity.SysGroupCfgHdrModel;
import com.prolog.rdc.tms.model.entity.SysRefdatadModel;
import com.prolog.rdc.tms.model.vo.SysGroupCfgDtlSaveVO;
import com.prolog.rdc.tms.model.vo.SysGroupCfgSaveVO;
import com.prolog.rdc.tms.model.vo.SysGroupCfgVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import com.prolog.rdc.tms.service.SysGroupCfgService;
import com.prolog.rdc.tms.util.ConvertorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统调度分组配置实现层
 *
 * @author lhb
 * @since 2022-04-13 14:45:00
 */
@Service
@Slf4j
public class SysGroupCfgServiceImpl implements SysGroupCfgService {

    @Autowired
    private SysGroupCfgHdrMapper sysGroupCfgHdrMapper;

    @Autowired
    private SysGroupCfgDtlMapper sysGroupCfgDtlMapper;

    @Autowired
    private MaindataFeign maindataTmsResource;

    @Autowired
    private ConvertorUtil convertorUtil;

    /**
     * 分组配置查询
     *
     * @param vo
     * @return
     */
    public List<SysGroupCfgHdrDTO> queryGroupCfg(@RequestBody SysGroupCfgVO vo) {
        ToolKits.isParamNull(vo, "查询请求不为空");
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        List<SysGroupCfgHdrDTO> sysGroupCfgHdrDTOList = Lists.newArrayList();

        Criteria criteriaCfgHdr = Criteria.forClass(SysGroupCfgHdrModel.class);
        Restriction r1 = Restrictions.eq(SysGroupCfgHdrModel::getCreateperson, user.getNickname());
        Restriction r2 = Restrictions.eq(SysGroupCfgHdrModel::getEnterpriseId, user.getEnterpriseId());
        Restriction r3 = ToolKits.isEmpty(vo.getGroupName()) ? null:Restrictions.eq(SysGroupCfgHdrModel::getGroupName, vo.getGroupName());
        Restriction r4 = ToolKits.isEmpty(vo.getDefaultFlag()) ? null:Restrictions.eq(SysGroupCfgHdrModel::getDefaultFlag, vo.getDefaultFlag());
        criteriaCfgHdr.setRestriction(Restrictions.and(r1, r2,r3,r4));
        List<SysGroupCfgHdrModel> cfgHdrModels = sysGroupCfgHdrMapper.findByCriteria(criteriaCfgHdr);

        if (ToolKits.isNotEmpty(cfgHdrModels)) {
            for (SysGroupCfgHdrModel hdrModel:cfgHdrModels) {
                SysGroupCfgHdrDTO cfgHdrDTO = new SysGroupCfgHdrDTO();
                cfgHdrDTO.setGroupName(hdrModel.getGroupName());
                cfgHdrDTO.setDefaultFlag(hdrModel.getDefaultFlag());
                cfgHdrDTO.setId(hdrModel.getId());
                cfgHdrDTO.setCreateperson(hdrModel.getCreateperson());
                cfgHdrDTO.setEnterpriseId(hdrModel.getEnterpriseId());
                cfgHdrDTO.setEnterpriseName(hdrModel.getEnterpriseName());
                cfgHdrDTO.setTotalLevel(hdrModel.getTotalLevel());

                // 明细查询
                Criteria criteriaCfgDtl = Criteria.forClass(SysGroupCfgDtlModel.class);
                r1 = Restrictions.eq(SysGroupCfgDtlModel::getHdrId, hdrModel.getId());
                r2 = Restrictions.eq(SysGroupCfgDtlModel::getGroupNumber, vo.getGroupNumber());
                criteriaCfgDtl.setRestriction(Restrictions.and(r1,r2));
                criteriaCfgDtl.orderAscBy(SysGroupCfgDtlModel::getGroupNumber);
                List<SysGroupCfgDtlModel> cfgDtlModels = sysGroupCfgDtlMapper.findByCriteria(criteriaCfgDtl);

                // 数据字典翻译数据集合
                List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] {
                        DataDictionaryConstant.GROUP_DISPATCH_NEW
                });
                List<SysGroupCfgDtlDTO> groupCfgDtlDTOList = Lists.newArrayList();
                for (SysGroupCfgDtlModel dtlModel:cfgDtlModels) {
                    SysGroupCfgDtlDTO cfgDtlDTO = new SysGroupCfgDtlDTO();
                    cfgDtlDTO.setId(dtlModel.getId());
                    cfgDtlDTO.setHdrId(dtlModel.getHdrId());
                    cfgDtlDTO.setGroupItem(dtlModel.getGroupItem());
                    cfgDtlDTO.setGroupNumber(dtlModel.getGroupNumber());
                    if (ToolKits.isNotEmpty(dtlModel.getGroupItem())) {
                        List<String> itemNames = Lists.newArrayList();
                        String[] itemArray = dtlModel.getGroupItem().split(",");
                        for (int i = 0; i < itemArray.length;i++) {
                            itemNames.add(ConvertorUtil.getName(dicData, DataDictionaryConstant.GROUP_DISPATCH_NEW, String.valueOf(itemArray[i])));
                        }
                        cfgDtlDTO.setGroupItemName(itemNames.stream().collect(Collectors.joining(",")));
                    }
                    groupCfgDtlDTOList.add(cfgDtlDTO);
                }
                criteriaCfgDtl.setRestriction(Restrictions.and(r1));
                criteriaCfgDtl.orderAscBy(SysGroupCfgDtlModel::getGroupNumber);
                List<SysGroupCfgDtlModel> cfgDtlModels2 = sysGroupCfgDtlMapper.findByCriteria(criteriaCfgDtl);
                if (ToolKits.isNotEmpty(cfgDtlModels2)) {
                    List<String> itemNames = Lists.newArrayList();
                    List<String> cfgItemNames = cfgDtlModels2.stream().map(SysGroupCfgDtlModel::getGroupItem).collect(Collectors.toList());
                    for (String item:cfgItemNames) {
                        String[] subItems = item.split(",");
                        List<String> subItemNames = Lists.newArrayList();
                        for (int j=0; j < subItems.length;j++) {
                            subItemNames.add(ConvertorUtil.getName(dicData, DataDictionaryConstant.GROUP_DISPATCH_NEW, String.valueOf(subItems[j])));
                        }
                        itemNames.add(subItemNames.stream().collect(Collectors.joining(",")));
                    }
                    cfgHdrDTO.setGroupItemNames(itemNames);
                }

                cfgHdrDTO.setGroupCfgDtlDTOList(groupCfgDtlDTOList);
                sysGroupCfgHdrDTOList.add(cfgHdrDTO);
            }
        }
        return sysGroupCfgHdrDTOList;
    }

    /**
     * 分组配置保存
     *
     * @param cfgSaveVOS
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveGroupCfg(List<SysGroupCfgSaveVO> cfgSaveVOS) {
        ToolKits.isParamNull(cfgSaveVOS, "分组配置保存请求不为空");
        if (cfgSaveVOS.stream().anyMatch(cfg->ToolKits.isEmpty(cfg.getGroupName()))) {
            throw new PrologException("分组名称不为空");
        }
        if (cfgSaveVOS.stream().anyMatch(cfg->ToolKits.isEmpty(cfg.getCfgDtlVOList()))) {
            throw new PrologException("分组设置明细不为空");
        }
        if (cfgSaveVOS.stream().anyMatch(cfg->ToolKits.isEmpty(cfg.getCfgDtlVOList()))) {
            throw new PrologException("分组设置明细不为空");
        }

        List<String> groupNames = cfgSaveVOS.stream().map(SysGroupCfgSaveVO::getGroupName).collect(Collectors.toList());
        long disCnt = groupNames.stream().distinct().collect(Collectors.toList()).size();
        if (groupNames.size() != disCnt) {
            throw new PrologException("分组名称重复");
        }
        List<SysGroupCfgSaveVO> defaults = cfgSaveVOS.stream().filter(save->ToolKits.isNotEmpty(save.getDefaultFlag()) && "Y".equals(save.getDefaultFlag())).collect(Collectors.toList());
        if (ToolKits.isNotEmpty(defaults) && defaults.size() > 1) {
            throw new PrologException("只能存在一个默认分组");
        }
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");
        Date date = DateUtils.nowDate();

        // 删除当前当前用户原有的分组配置
        Criteria criteriaCfgHdr = Criteria.forClass(SysGroupCfgHdrModel.class);
        Restriction r1 = Restrictions.eq(SysGroupCfgHdrModel::getCreateperson, user.getNickname());
        Restriction r2 = Restrictions.eq(SysGroupCfgHdrModel::getEnterpriseId, user.getEnterpriseId());
        criteriaCfgHdr.setRestriction(Restrictions.and(r1, r2));
        long delCnt = sysGroupCfgHdrMapper.deleteByCriteria(criteriaCfgHdr);
        if (delCnt > 0) {
            Criteria criteriaCfgDtl = Criteria.forClass(SysGroupCfgDtlModel.class);
            r1 = Restrictions.eq(SysGroupCfgDtlModel::getCreateperson, user.getNickname());
            r2 = Restrictions.eq(SysGroupCfgDtlModel::getEnterpriseId, user.getEnterpriseId());
            criteriaCfgDtl.setRestriction(Restrictions.and(r1, r2));
            sysGroupCfgDtlMapper.deleteByCriteria(criteriaCfgDtl);
        }

        for (SysGroupCfgSaveVO cfgSaveVO:cfgSaveVOS) {
            SysGroupCfgHdrModel cfgHdrModel = new SysGroupCfgHdrModel();
            // 获取分组配置主表ID
            RestMessage<String> restMessage = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.SYS_GROUP_CFG_HDR_ID, "L");
            if (!restMessage.isSuccess()) {
                throw new RuntimeException("生成分组配置主表ID失败");
            }
            String id = restMessage.getData();
            cfgHdrModel.setId(id);
            cfgHdrModel.setGroupName(cfgSaveVO.getGroupName());
            cfgHdrModel.setDefaultFlag(cfgSaveVO.getDefaultFlag());
            cfgHdrModel.setCreatetime(date);
            cfgHdrModel.setCreateperson(user.getNickname());
            cfgHdrModel.setEnterpriseName(user.getEnterpriseName());
            cfgHdrModel.setEnterpriseId(user.getEnterpriseId());

            List<SysGroupCfgDtlSaveVO> cfgDtlSaveVOS = cfgSaveVO.getCfgDtlVOList();
            if (ToolKits.isNotEmpty(cfgDtlSaveVOS)) {
                if (cfgDtlSaveVOS.stream().anyMatch(cfg->ToolKits.isEmpty(cfg.getGroupItem()))) {
                    throw new PrologException("分组设置中,分组项目不为空");
                }
                if (cfgDtlSaveVOS.stream().anyMatch(cfg->ToolKits.isEmpty(cfg.getGroupNumber()))) {
                    throw new PrologException("分组设置中,分组顺序不为空");
                }
                cfgHdrModel.setTotalLevel(cfgDtlSaveVOS.size());
                for (SysGroupCfgDtlSaveVO cfgDtlSaveVO:cfgDtlSaveVOS) {
                    SysGroupCfgDtlModel cfgDtlModel = new SysGroupCfgDtlModel();

                    // 获取分组配置明细表ID
                    RestMessage<String> restMessageDtl = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.SYS_GROUP_CFG_DTL_ID, "L");
                    if (!restMessageDtl.isSuccess()) {
                        throw new RuntimeException("生成分组配置明细表失败");
                    }
                    String dtlId = restMessageDtl.getData();
                    cfgDtlModel.setId(dtlId);
                    cfgDtlModel.setHdrId(id);
                    cfgDtlModel.setGroupNumber(cfgDtlSaveVO.getGroupNumber());
                    cfgDtlModel.setGroupItem(cfgDtlSaveVO.getGroupItem());
                    cfgDtlModel.setCreatetime(date);
                    cfgDtlModel.setCreateperson(user.getNickname());
                    cfgDtlModel.setEnterpriseName(user.getEnterpriseName());
                    cfgDtlModel.setEnterpriseId(user.getEnterpriseId());
                    sysGroupCfgDtlMapper.save(cfgDtlModel);
                }
            }  else {
                cfgHdrModel.setTotalLevel(0);
            }
            sysGroupCfgHdrMapper.save(cfgHdrModel);
        }
    }

    /**
     * 默认分组配置
     *
     * @param cfgVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void defaultGroup(SysGroupCfgVO cfgVO) {
        ToolKits.isParamNull(cfgVO, "设置默认分组请求不为空");
        ToolKits.isParamNull(cfgVO.getId(), "分组Id不为空");
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");
        Date date = DateUtils.nowDate();

        Criteria criteriaCfgHdr = Criteria.forClass(SysGroupCfgHdrModel.class);
        Restriction r1 = Restrictions.eq(SysGroupCfgHdrModel::getCreateperson, user.getNickname());
        Restriction r2 = Restrictions.eq(SysGroupCfgHdrModel::getEnterpriseId, user.getEnterpriseId());
        Restriction r3 = Restrictions.eq(SysGroupCfgHdrModel::getDefaultFlag, "Y");
        Restriction r4 = Restrictions.ne(SysGroupCfgHdrModel::getId, cfgVO.getId());
        criteriaCfgHdr.setRestriction(Restrictions.and(r1, r2,r3,r4));
        Map<String, Object> mapN = Maps.newHashMap();
        mapN.put("defaultFlag", "N");
        mapN.put("updatetime", date);
        mapN.put("updateperson", user.getNickname());
        sysGroupCfgHdrMapper.updateMapByCriteria(mapN,criteriaCfgHdr);

        Map<String, Object> mapY = Maps.newHashMap();
        mapY.put("defaultFlag", "Y");
        mapY.put("updatetime", date);
        mapY.put("updateperson", user.getNickname());
        sysGroupCfgHdrMapper.updateMapById(cfgVO.getId(),mapY,SysGroupCfgHdrModel.class);
    }

    /**
     * 删除分组配置
     *
     * @param cfgVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteGroup(SysGroupCfgVO cfgVO) {
        ToolKits.isParamNull(cfgVO, "删除分组请求不为空");
        ToolKits.isParamNull(cfgVO.getId(), "分组Id不为空");
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        long delCnt = sysGroupCfgHdrMapper.deleteById(cfgVO.getId(),SysGroupCfgHdrModel.class);
        if (delCnt > 0) {
            Criteria criteriaCfgDtl = Criteria.forClass(SysGroupCfgDtlModel.class);
            Restriction r1 = Restrictions.eq(SysGroupCfgDtlModel::getHdrId, cfgVO.getId());
            criteriaCfgDtl.setRestriction(Restrictions.and(r1));
            sysGroupCfgDtlMapper.deleteByCriteria(criteriaCfgDtl);
        }
    }
}
