package com.zd.chemical.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.zd.chemical.domain.HxpAlarmRecord;
import com.zd.chemical.domain.HxpChemical;
import com.zd.chemical.domain.HxpChemicalClassify;
import com.zd.chemical.domain.HxpStock;
import com.zd.chemical.domain.vo.*;
import com.zd.chemical.mapper.HxpAlarmRecordMapper;
import com.zd.chemical.mapper.HxpChemicalClassifyMapper;
import com.zd.chemical.mapper.HxpChemicalMapper;
import com.zd.chemical.mapper.HxpUserecordMapper;
import com.zd.chemical.service.IHxpChemicalService;
import com.zd.chemical.util.SmsSydUtil;
import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.Pinyin4jUtil;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.StringUtils;
import com.zd.common.core.web.domain.AjaxResult;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.security.utils.DictUtils;
import com.zd.common.security.utils.SaveUtil;
import com.zd.system.api.alarm.RemoteAlarmService;
import com.zd.system.api.alarm.domain.AlarmEntrty;
import com.zd.system.api.alarm.domain.Routes;
import com.zd.system.api.alarm.domain.SendTypes;
import com.zd.system.api.domain.SysDictData;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.DoubleAdder;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 化学品信息Service业务层处理
 *
 * @author liubo
 * @date 2022-06-16
 */
@Service
public class HxpChemicalServiceImpl implements IHxpChemicalService {
    @Autowired
    private HxpChemicalMapper hxpChemicalMapper;
    @Autowired
    private HxpChemicalClassifyMapper hxpChemicalClassifyMapper;
    @Autowired
    private IHxpChemicalService hxpChemicalService;
    @Autowired
    private HxpUserecordMapper hxpUserecordMapper;
    @Autowired
    private HxpAlarmRecordMapper hxpAlarmRecordMapper;
    @Autowired
    private RemoteAlarmService remoteAlarmService;
    @Resource
    private SmsSydUtil smsSydUtil;


    /**
     * 查询化学品信息
     *
     * @param id 化学品信息主键
     * @return 化学品信息
     */
    @Override
    public HxpChemical selectHxpChemicalById(Long id) {
        return hxpChemicalMapper.selectHxpChemicalById(id);
    }

    /**
     * 查询化学品信息列表
     *
     * @param hxpChemicalSearch 化学品信息
     * @return 化学品信息
     */
    @Override
    @DataScope(deptAlias = "su", userAlias = "su", permi = PerPrefix.HPX_CHEMICAL)
    public List<HxpChemicalVo> selectHxpChemicalList(HxpChemicalSearch hxpChemicalSearch) {
        List<HxpChemicalVo> hxpChemicalList = hxpChemicalMapper.selectHxpChemicalList(hxpChemicalSearch);
        return hxpChemicalList;
    }

    @Override
    public List <HxpChemicalByExcel> importUserByChemical(List <HxpChemicalByExcel> chemicalList, String operName, HxpChemicalByExcel hxpChemicalByExcel) {
        if (StringUtils.isNull(chemicalList) || chemicalList.size() == 0) {
            throw new ServiceException("导入危险品数据不能为空！");
        }
        List<HxpChemicalByExcel> failChemicalList = new ArrayList<>();
        for (HxpChemicalByExcel chemical : chemicalList) {
            //流水线验证
            flowLineCheck(chemical,failChemicalList, hxpChemicalByExcel);
        }
        return failChemicalList;
    }

    private void flowLineCheck(HxpChemicalByExcel chemical, List<HxpChemicalByExcel> failChemicalList, HxpChemicalByExcel hxpChemicalByExcel){
        // 校验是否装入错误数据
        boolean checkBox = true;

        //创建化学品对象
        HxpChemical hxpChemical = new HxpChemical();

        //验证化学品名称不能为空
        if(StringUtils.isEmpty(chemical.getChemicalName())){
            if(checkBox){
                chemical.getFailRemark().append("失败：");
                failChemicalList.add(chemical);
                checkBox = false;
            }
            chemical.getFailRemark().append("化学品名称不能为空、");
        }else{
            if(chemical.getChemicalName().length()>30){
                if(checkBox){
                    chemical.getFailRemark().append("失败：");
                    failChemicalList.add(chemical);
                    checkBox = false;
                }
                chemical.getFailRemark().append("化学品名称最多三十个字符、");
            }
        }
        hxpChemical.setChemicalName(chemical.getChemicalName());

        //分类名称
        if(StringUtils.isEmpty(chemical.getClassifyName())){
            if(checkBox){
                chemical.getFailRemark().append("失败：");
                failChemicalList.add(chemical);
                checkBox = false;
            }
            chemical.getFailRemark().append("分类名称不能为空、");
        }else{
            HxpChemicalClassify hxpChemicalClassify = new HxpChemicalClassify();
            hxpChemicalClassify.setClassifyName(chemical.getClassifyName());
            List<HxpChemicalClassify> classifyList = hxpChemicalClassifyMapper.selectHxpChemicalClassifyList(hxpChemicalClassify);
            if(classifyList.size()>0){
                HxpChemicalClassify classify = classifyList.get(0);
                hxpChemical.setChemicalClassify(classify.getId());
            }else{
                if(checkBox){
                    chemical.getFailRemark().append("失败：");
                    failChemicalList.add(chemical);
                    checkBox = false;
                }
                chemical.getFailRemark().append("分类名称不存在、");
            }
        }

        //形态
        if(StringUtils.isEmpty(chemical.getChemicalShapeInfo())){
            if(checkBox){
                chemical.getFailRemark().append("失败：");
                failChemicalList.add(chemical);
                checkBox = false;
            }
            chemical.getFailRemark().append("形态不能为空、");
        }else{
            List<SysDictData> proDictDatas = DictUtils.getDictCache("chemical_shape");
            for(SysDictData dictData : proDictDatas){
                if(dictData.getDictLabel().equals(chemical.getChemicalShapeInfo())){
                    hxpChemical.setChemicalShape(Integer.parseInt(dictData.getDictValue()));
                }
            }
            if(StringUtils.isNull(hxpChemical.getChemicalShape())){
                if(checkBox){
                    chemical.getFailRemark().append("失败：");
                    failChemicalList.add(chemical);
                    checkBox = false;
                }
                chemical.getFailRemark().append("形态不存在、");
            }
        }

//        Map<String,Integer> labelMap = new HashMap<>();
//        labelMap.put("RFID",1);
//        labelMap.put("二维码",2);
//        //标签类型
//        if(StringUtils.isEmpty(chemical.getLabelContent())){
//            if(checkBox){
//                chemical.getFailRemark().append("失败：");
//                failChemicalList.add(chemical);
//                checkBox = false;
//            }
//            chemical.getFailRemark().append("标签类型不能为空、");
//        }else{
//            if(StringUtils.isNotNull(labelMap.get(chemical.getLabelContent()))){
//                hxpChemical.setLabelType(labelMap.get(chemical.getLabelContent()));
//            }else{
//                if(checkBox){
//                    chemical.getFailRemark().append("失败：");
//                    failChemicalList.add(chemical);
//                    checkBox = false;
//                }
//                chemical.getFailRemark().append("标签类型不存在、");
//            }
//        }

        //属性
        if(StringUtils.isNotEmpty(chemical.getClassifyAttribute())){
            Optional.ofNullable(DictUtils.getDictCache("hxp_classifyattribute")).orElseGet(Collections::emptyList).stream()
                    .forEach(a->Optional.ofNullable(chemical.getClassifyAttribute().split(",")).map(b->{
                        for(int i=0;i<b.length;i++){
                            if(a.getDictLabel().equals(b[i])){
                                hxpChemical.setClassifyAttribute(hxpChemical.getClassifyAttribute()==null?","+a.getDictValue():hxpChemical.getClassifyAttribute()+","+a.getDictValue());
                            }
                        }
                        return a;
                    }));
            if(StringUtils.isNotEmpty(hxpChemical.getClassifyAttribute())){
                hxpChemical.setClassifyAttribute(hxpChemical.getClassifyAttribute().substring(1));
            }else{
                if(checkBox){
                    chemical.getFailRemark().append("失败：");
                    failChemicalList.add(chemical);
                    checkBox = false;
                }
                chemical.getFailRemark().append("属性不存在、");
            }
        }

        //cas号
        if(StringUtils.isNotEmpty(chemical.getCasNum())){
            HxpChemicalSearch hxpChemicalSearch = new HxpChemicalSearch();
            hxpChemicalSearch.setCasNum(chemical.getCasNum());
            List<HxpChemicalVo> hxpChemicalVoList = hxpChemicalMapper.selectHxpChemicalList(hxpChemicalSearch);
            if(hxpChemicalVoList.size()>0){
                if(checkBox){
                    chemical.getFailRemark().append("失败：");
                    failChemicalList.add(chemical);
                    checkBox = false;
                }
                chemical.getFailRemark().append("CAS号重复、");
            }
        }
        hxpChemical.setCasNum(chemical.getCasNum());

        //别名
        hxpChemical.setAnotherName(chemical.getAnotherName());

        //纯度
        hxpChemical.setPurity(chemical.getPurity());

        //生产厂家
        if(chemical.getFactory().length()>30){
            if(checkBox){
                chemical.getFailRemark().append("失败：");
                failChemicalList.add(chemical);
                checkBox = false;
            }
            chemical.getFailRemark().append("生产厂家最多三十个字符、");
        }
        hxpChemical.setFactory(chemical.getFactory());


        if(StringUtils.isNotEmpty(chemical.getFailRemark())){
            chemical.getFailRemark().deleteCharAt(chemical.getFailRemark().length()-1);
        }

        if(StringUtils.isEmpty(chemical.getFailRemark())){
            //这里目前先写死
            hxpChemical.setMeasuringMethod(1);
            hxpChemical.setChemicalUnit("g");
            hxpChemicalService.insertHxpChemical(hxpChemical);
        }
    }

    /**
     * 新增化学品信息
     *
     * @param hxpChemical 化学品信息
     * @return 结果
     */
    @Override
    public int insertHxpChemical(HxpChemical hxpChemical) {
        //这里需要查询危险品分类的级别
        HxpChemicalClassify hxpChemicalClassify = hxpChemicalClassifyMapper.selectHxpChemicalClassifyById(hxpChemical.getChemicalClassify());
        if(StringUtils.isNull(hxpChemicalClassify)){
           throw new ServiceException("危险品分类级别未配置，请联系管理员！！");
        }
        if(hxpChemicalClassify.getClassifyName().length()<2){
            throw new ServiceException("分类名称错误，请联系管理员");
        }
        String classifyName = hxpChemicalClassify.getClassifyName().substring(0,2);
        StringBuffer hxpNum = new StringBuffer();
        hxpNum.append(generateLetter(classifyName));
//        if(hxpChemicalClassify.getHazardLevel().equals(1)){
//            hxpNum.append("WX");
//        }else if(hxpChemicalClassify.getHazardLevel().equals(2)){
//            hxpNum.append("PT");
//        }else if(hxpChemicalClassify.getHazardLevel().equals(3)){
//            hxpNum.append("QT");
//        }
        hxpChemical.setChemicalNum(generateNumber(hxpNum));
        //设置其他公共字段
        SaveUtil.setCommonAttr(hxpChemical);

        hxpChemical.setChemicalNamePinyin(Pinyin4jUtil.getPingYin(hxpChemical.getChemicalName()));
        hxpChemical.setChemicalNameChar(Pinyin4jUtil.getPinYinHeadChar(hxpChemical.getChemicalName()));
        hxpChemical.setAnotherNamePinyin(Pinyin4jUtil.getPingYin(hxpChemical.getAnotherName()));
        hxpChemical.setAnotherNameChar(Pinyin4jUtil.getPinYinHeadChar(hxpChemical.getAnotherName()));
        return hxpChemicalMapper.insertHxpChemical(hxpChemical);
    }

    public String generateNumber(StringBuffer hxpNum){
        HxpChemical hxpChemical = hxpChemicalMapper.selectHxpChemicalMaxById(hxpNum.toString());
        if(StringUtils.isNull(hxpChemical)){
            synthesisNumber("1",hxpNum);
        }else{
            String chemicalNum = hxpChemical.getChemicalNum().substring(2,hxpChemical.getChemicalNum().length());
            chemicalNum = (Integer.parseInt(chemicalNum)+1)+"";
            synthesisNumber(chemicalNum,hxpNum);
        }
        return hxpNum.toString();
    }

    public void synthesisNumber(String num,StringBuffer hxpNum){
        for(int i=0;i<6-num.length();i++){
            hxpNum.append("0");
        }
        hxpNum.append(num);
    }

    public String generateLetter(String china){
        HanyuPinyinOutputFormat formart = new HanyuPinyinOutputFormat();
        formart.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        formart.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        formart.setVCharType(HanyuPinyinVCharType.WITH_V);
        char[] arrays = china.trim().toCharArray();
        String result = "";
        try {
            for (int i=0;i<2;i++) {
                char ti = arrays[i];
                if(Character.toString(ti).matches("[\\u4e00-\\u9fa5]")){ //匹配是否是中文
                    String[] temp = PinyinHelper.toHanyuPinyinStringArray(ti,formart);
                    result += temp[0].substring(0,1).toUpperCase();
                }else{
                    result += ti;
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 修改化学品信息
     *
     * @param hxpChemical 化学品信息
     * @return 结果
     */
    @Override
    public int updateHxpChemical(HxpChemical hxpChemical) {
        hxpChemical.setUpdateTime(DateUtils.getNowDate());
        hxpChemical.setUpdateBy(SecurityUtils.getUsername());

        hxpChemical.setChemicalNamePinyin(Pinyin4jUtil.getPingYin(hxpChemical.getChemicalName()));
        hxpChemical.setChemicalNameChar(Pinyin4jUtil.getPinYinHeadChar(hxpChemical.getChemicalName()));
        hxpChemical.setAnotherNamePinyin(Pinyin4jUtil.getPingYin(hxpChemical.getAnotherName()));
        hxpChemical.setAnotherNameChar(Pinyin4jUtil.getPinYinHeadChar(hxpChemical.getAnotherName()));
        return hxpChemicalMapper.updateHxpChemical(hxpChemical);
    }

    /**
     * 修改化学品信息
     *
     * @param hxpChemical 化学品信息
     * @return 结果
     */
    @Override
    public int editChemicalByJoinHazard(HxpChemical hxpChemical) {
        hxpChemical.setUpdateTime(DateUtils.getNowDate());
        hxpChemical.setUpdateBy(SecurityUtils.getUsername());
        if(StringUtils.isNull(hxpChemical.getJoinHazardId())){
            hxpChemicalMapper.clearHxpChemicalByJoinHazard(hxpChemical);
        }
        return hxpChemicalMapper.updateHxpChemical(hxpChemical);
    }

    /**
     * 批量删除化学品信息
     *
     * @param ids 需要删除的化学品信息主键
     * @return 结果
     */
    @Override
    public int deleteHxpChemicalByIds(Long[] ids) {
        //删除化学品需要提示（该化学试剂有存放库存,无法删除,请先操作出库.）；回头补
        return hxpChemicalMapper.deleteHxpChemicalByIds(ids);
    }

    /**
     * 删除化学品信息信息
     *
     * @param id 化学品信息主键
     * @return 结果
     */
    @Override
    public int deleteHxpChemicalById(Long id) {
        return hxpChemicalMapper.deleteHxpChemicalById(id);
    }


    /**
     * 查询化学品信息列表
     *
     * @param hxpChemical 化学品信息
     * @return 化学品信息
     */
    @Override
    @DataScope(deptAlias = "ur", userAlias = "ur", permi = PerPrefix.HPX_HOMEPAGE)
    public HxpHomeChemicalVo chemicalUsageCount(HxpChemical hxpChemical) {
        return hxpChemicalMapper.chemicalUsageCount(hxpChemical);
    }

    /**
     * 查询化学品特别信息统计
     *
     * @param hxpChemical 化学品信息
     * @return 化学品信息
     */
    @Override
    @DataScope(deptAlias = "ur", userAlias = "ur", permi = PerPrefix.HPX_HOMEPAGE)
    public HxpHomeChemicalUnusualVo chemicalUnusualCount(HxpChemical hxpChemical) {
        return hxpChemicalMapper.chemicalUnusualCount(hxpChemical);
    }

    /**
     * 化学品使用量top6
     *
     * @param hxpChemical 化学品信息
     * @return 化学品信息
     */
    @Override
    @DataScope(deptAlias = "ur", userAlias = "ur", permi = PerPrefix.HPX_HOMEPAGE)
    public List<HxpHomeChemicalUsagesVo> chemicalUsagesCount(HxpChemical hxpChemical) {
        return hxpChemicalMapper.chemicalUsagesCount(hxpChemical);
    }

    /**
     * 化学品分类占比
     *
     * @param hxpChemical 化学品信息
     * @return 化学品信息
     */
    @Override
    @DataScope(deptAlias = "ur", userAlias = "ur", permi = PerPrefix.HPX_HOMEPAGE)
    public List<LinkedHashMap <String,String>> chemicalClassifyMix(HxpChemical hxpChemical) {
        List<LinkedHashMap <String,String>> chemicalList = hxpChemicalMapper.chemicalClassifyMix(hxpChemical);
        DoubleAdder doubleAdder = new DoubleAdder();
        Optional.ofNullable(chemicalList).orElseGet(Collections::emptyList).stream()
                .forEach(a->{
                    a.forEach((key,value)->{
                        if(key.equals("chemicalMix")){
                            doubleAdder.add(Long.parseLong(value));
                        }

                    });
                });
        Double sumMix = doubleAdder.sum();
        List<LinkedHashMap <String,String>> linkedList = Optional.ofNullable(chemicalList).orElseGet(Collections::emptyList).stream()
                .map(a->{
                    a.forEach((key,value)->{
                        if(key.equals("chemicalMix")){
                            a.put(key,(Math.round(Double.parseDouble(value)/sumMix.doubleValue()*100))+"%");
                        }
                    });
                    return a;
                }).collect(Collectors.toList());

        return linkedList;
    }


    @Override
    @DataScope(deptAlias = "ur", userAlias = "ur", permi = PerPrefix.HPX_HOMEPAGE)
    public Long stockTotal(HxpChemical hxpChemical){
        return hxpChemicalMapper.stockTotal(hxpChemical);
    }


    /**
     * 化学品分类占比
     *
     * @param hxpStock 化学品信息
     * @return 化学品信息
     */
    @Override
    @DataScope(deptAlias = "ur", userAlias = "ur", permi = PerPrefix.HPX_HOMEPAGE)
    public List<LinkedHashMap <String,String>> joinOutCount(HxpStock hxpStock) {
        List<LinkedHashMap <String,String>> stockCountList = hxpChemicalMapper.joinOutCount(hxpStock);
        return stockCountList;
    }

    @Override
    public List<Map<String, Object>> queryCriticaliBySubId(List<Long> subIds) {
        List<Map<String, Object>> list = hxpChemicalMapper.queryCriticaliBySubId(subIds);
        if(CollectionUtils.isNotEmpty(list)){
            if(list.get(0) == null){
                list.remove(0);
            }
        }
        return list;
    }

    @Override
    public void indicatorMonitoring() {
        List<Map<String, Object>> list = hxpChemicalMapper.queryCriticaliBySubId(new ArrayList<>());
        if(!list.isEmpty()){
            if(list.get(0) == null){
                list.remove(0);
            }

            list.forEach(map -> {
                if(BigDecimal.valueOf(1L).compareTo(BigDecimal.valueOf(Double.parseDouble(map.get("criticali")+""))) < 0){

                    Map<String,Object> subInfo = hxpUserecordMapper.selectSubInfoById(Long.parseLong(map.get("subId") + ""));
                    String safeUserId = "";
                    if(subInfo != null){
                        safeUserId = subInfo.get("safeUserId")==null?"":String.valueOf(subInfo.get("safeUserId"));
                    }

                    HxpAlarmRecord hxpAlarmRecord = new HxpAlarmRecord();
                    hxpAlarmRecord.setAlarmContent("房间内危化品已定为重大危险源，请确认安全存放量！");
                    hxpAlarmRecord.setAlarmType(2);
                    hxpAlarmRecord.setHasValid(1);
                    hxpAlarmRecord.setAlarmMode(3);
                    hxpAlarmRecord.setAlarmTime(DateUtils.getNowDate());
                    hxpAlarmRecord.setSubId(Long.parseLong(map.get("subId") + ""));
                    hxpAlarmRecord.setHandlingStatus(1);
                    hxpAlarmRecord.setLiableUserIds(safeUserId);

                    hxpAlarmRecordMapper.insertHxpAlarmRecord(hxpAlarmRecord);

                    // 此处需要发送短信通知

                    String[] strings = Stream.of(new String[]{subInfo.get("phones")+""})
                            .filter(a -> StrUtil.isNotBlank(a))
                            .collect(Collectors.joining(","))
                            .split(",");

                    String subName = subInfo.get("name")==null?"":subInfo.get("name")+"";
                    String content = subName + "房间内危化品已定为重大危险源，请确认安全存放量！";
                    if(HxpStockServiceImpl.phoneMode == 0){

                        AlarmEntrty alarmEntrty = new AlarmEntrty(Routes.NoticePush, strings,content);
                        remoteAlarmService.send(alarmEntrty);
                    }else if(HxpStockServiceImpl.phoneMode == 1){
                        try {
                            smsSydUtil.sendSydSms(content, 1, null, strings);
                        } catch (Exception e) {
                        }
                    }
                }
            });
        }
    }
}
