package com.njcn.device.pq.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.biz.enums.DeviceResponseEnum;
import com.njcn.device.pq.mapper.FlowStrategyDicMapper;
import com.njcn.device.pq.mapper.FlowStrategyMapper;
import com.njcn.device.pq.mapper.RateOfFlowMapper;
import com.njcn.device.pq.mapper.StrategydicFunMapper;
import com.njcn.device.pq.pojo.param.FlowStrategyParam;
import com.njcn.device.pq.pojo.po.FlowStrategy;
import com.njcn.device.pq.pojo.po.FlowStrategyDic;
import com.njcn.device.pq.pojo.po.StrategydicFun;
import com.njcn.device.pq.pojo.vo.FlowStrategyVO;
import com.njcn.device.pq.pojo.vo.ShowFlowStrategyVO;
import com.njcn.device.pq.service.FlowStrategyService;
import com.njcn.web.utils.RequestUtil;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @version 1.0.0
 * @author: chenchao
 * @date: 2022/05/18 14:52
 */
@Service
@AllArgsConstructor
public class FlowStrategyServiceImpl extends ServiceImpl<FlowStrategyMapper, FlowStrategy> implements FlowStrategyService {

    private final RateOfFlowMapper rateOfFlowMapper;

    private final FlowStrategyMapper flowStrategyMapper;

    private final StrategydicFunMapper strategyDicFunMapper;

    private final FlowStrategyDicMapper flowStrategyDicMapper;

    @Override
    public List<FlowStrategyVO> getRateOfFlowStrategy() {
        List<FlowStrategyVO> flowStrategy = rateOfFlowMapper.getFlowStrategy();
        for (FlowStrategyVO f: flowStrategy) {
            f.setComPerData(Double.parseDouble(f.getComPerData()) *100+"");
            f.setWarnPerData(Double.parseDouble(f.getWarnPerData()) *100+"");
            f.setAlertPerData(Double.parseDouble(f.getAlertPerData()) *100+"");
        }
        return flowStrategy;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addRateOfFlowStrategy(FlowStrategyParam flowStrategyParam) {
        checkCode(flowStrategyParam,false);
        if (Float.parseFloat(flowStrategyParam.getComPerData()) >= Float.parseFloat(flowStrategyParam.getWarnPerData()) &&
                Float.parseFloat(flowStrategyParam.getWarnPerData()) >= Float.parseFloat(flowStrategyParam.getAlertPerData())
        ) {
            throw new BusinessException(DeviceResponseEnum.FLOW_ERROR);
        }
        FlowStrategy flowStrategy = new FlowStrategy();
        BeanUtils.copyProperties(flowStrategyParam, flowStrategy);
        for (int i=0;i<3;i++) {
            FlowStrategyDic flowStrategyDic = new FlowStrategyDic();
            flowStrategyDic.setType(i);
            if (flowStrategyDic.getType()==0) {
                Float f = Float.parseFloat(flowStrategyParam.getComPerData());
                flowStrategyDic.setValue(f/100);
            }
            if (flowStrategyDic.getType()==1) {
                Float f = Float.parseFloat(flowStrategyParam.getWarnPerData());
                flowStrategyDic.setValue(f/100);
            }
            if (flowStrategyDic.getType()==2) {
                Float f = Float.parseFloat(flowStrategyParam.getAlertPerData());
                flowStrategyDic.setValue(f/100);
            }
            flowStrategyDicMapper.insert(flowStrategyDic);
            if (flowStrategyDic.getType()==0) {
                List<String> comList = flowStrategyParam.getComList();
                for (String com: comList) {
                    StrategydicFun strategyDicFun = new StrategydicFun();
                    strategyDicFun.setStrategyDicId(flowStrategyDic.getId());
                    strategyDicFun.setFuctionId(com);
                    strategyDicFunMapper.insert(strategyDicFun);
                    flowStrategy.setComPer(flowStrategyDic.getId());
                }
            }
            if (flowStrategyDic.getType()==1) {
                List<String> warnList = flowStrategyParam.getWarnList();
                for (String war: warnList) {
                    StrategydicFun strategyDicFun = new StrategydicFun();
                    strategyDicFun.setStrategyDicId(flowStrategyDic.getId());
                    strategyDicFun.setFuctionId(war);
                    strategyDicFunMapper.insert(strategyDicFun);
                    flowStrategy.setWarnPer(flowStrategyDic.getId());
                }
            }
            if (flowStrategyDic.getType()==2) {
                List<String> alertList = flowStrategyParam.getAlertList();
                for (String ale: alertList) {
                    StrategydicFun strategyDicFun = new StrategydicFun();
                    strategyDicFun.setStrategyDicId(flowStrategyDic.getId());
                    strategyDicFun.setFuctionId(ale);
                    strategyDicFunMapper.insert(strategyDicFun);
                    flowStrategy.setAlertPer(flowStrategyDic.getId());
                }
            }
        }

        flowStrategy.setState(DataStateEnum.ENABLE.getCode());
        flowStrategy.setCreateBy(RequestUtil.getUserIndex());
        flowStrategy.setUpdateBy(RequestUtil.getUserIndex());
        flowStrategy.setCreateTime(LocalDateTime.now());
        flowStrategy.setUpdateTime(LocalDateTime.now());
        flowStrategyMapper.insert(flowStrategy);
        return true;
    }

    @Override
    public ShowFlowStrategyVO getFlowStrategyById(String id) {
        ShowFlowStrategyVO flowStrategyById = rateOfFlowMapper.getFlowStrategyById(id);
        List<String> list = new ArrayList<>();
        list.add(flowStrategyById.getCom());
        list.add(flowStrategyById.getWarn());
        list.add(flowStrategyById.getAlert());
        for (int i=0;i<3;i++) {
            List<String> ids = rateOfFlowMapper.getStrategyDicFun(list.get(i));
            if (i==0) {
                List<String> comList = new ArrayList<>();
                for (String s: ids) {
                    comList.add(rateOfFlowMapper.getDictData(s));
                    flowStrategyById.setComList(comList);
                }
            }
            if (i==1) {
                List<String> warnList = new ArrayList<>();
                for (String s: ids) {
                    warnList.add(rateOfFlowMapper.getDictData(s));
                    flowStrategyById.setWarnList(warnList);
                }
            }
            if (i==2) {
                List<String> alertList = new ArrayList<>();
                for (String s: ids) {
                    alertList.add(rateOfFlowMapper.getDictData(s));
                    flowStrategyById.setAlertList(alertList);
                }
            }
        }
        return flowStrategyById;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRateOfFlowStrategy(FlowStrategyParam.FlowStrategyUpdateParam flowStrategyUpdateParam) {
        checkCode(flowStrategyUpdateParam, true);
        if (Float.parseFloat(flowStrategyUpdateParam.getComPerData()) >= Float.parseFloat(flowStrategyUpdateParam.getWarnPerData()) &&
                Float.parseFloat(flowStrategyUpdateParam.getWarnPerData()) >= Float.parseFloat(flowStrategyUpdateParam.getAlertPerData())
        ) {
            throw new BusinessException(DeviceResponseEnum.FLOW_ERROR);
        }
        // 获取当前记录在数据库中的外键Id
        FlowStrategy strategy = flowStrategyMapper.selectById(flowStrategyUpdateParam.getId());
        String comPerId = strategy.getComPer();
        String warnPerId = strategy.getWarnPer();
        String alertPerId = strategy.getAlertPer();
        for (int i=0;i<3;i++) {
            FlowStrategyDic flowStrategyDic = new FlowStrategyDic();
            if (i==0) {
                flowStrategyDic.setId(comPerId);
                flowStrategyDic.setValue((Float.parseFloat(flowStrategyUpdateParam.getComPerData()))/100);
            }
            if (i==1) {
                flowStrategyDic.setId(warnPerId);
                flowStrategyDic.setValue((Float.parseFloat(flowStrategyUpdateParam.getWarnPerData()))/100);
            }
            if (i==2) {
                flowStrategyDic.setId(alertPerId);
                flowStrategyDic.setValue((Float.parseFloat(flowStrategyUpdateParam.getAlertPerData()))/100);
            }
            flowStrategyDicMapper.updateById(flowStrategyDic);
        }

        rateOfFlowMapper.delStrategyDicFun(comPerId);
        rateOfFlowMapper.delStrategyDicFun(warnPerId);
        rateOfFlowMapper.delStrategyDicFun(alertPerId);
        List<String> comList = flowStrategyUpdateParam.getComList();
        List<String> warnList = flowStrategyUpdateParam.getWarnList();
        List<String> alertList = flowStrategyUpdateParam.getAlertList();
        for (String c: comList) {
            StrategydicFun fun = new StrategydicFun();
            fun.setStrategyDicId(comPerId);
            fun.setFuctionId(c);
            strategyDicFunMapper.insert(fun);
        }
        for (String w: warnList) {
            StrategydicFun fun = new StrategydicFun();
            fun.setStrategyDicId(warnPerId);
            fun.setFuctionId(w);
            strategyDicFunMapper.insert(fun);
        }
        for (String a: alertList) {
            StrategydicFun fun = new StrategydicFun();
            fun.setStrategyDicId(alertPerId);
            fun.setFuctionId(a);
            strategyDicFunMapper.insert(fun);
        }

        FlowStrategy flowStrategy = new FlowStrategy();
        flowStrategy.setId(flowStrategyUpdateParam.getId());
        flowStrategy.setName(flowStrategyUpdateParam.getName());
        flowStrategy.setFlag(flowStrategyUpdateParam.getFlag());
        flowStrategy.setUpdateBy(RequestUtil.getUserIndex());
        flowStrategy.setUpdateTime(LocalDateTime.now());
        flowStrategyMapper.updateById(flowStrategy);
        return true;
    }

    @Override
    public boolean deleteRateOfFlowStrategy(String id) {
        rateOfFlowMapper.updateByStrategy(id);
        return true;
    }


    /**
     * 校验参数，检查是否存在相同编码的字典类型
     */
    private void checkCode(FlowStrategyParam flowStrategyParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<FlowStrategy> queryWrapperStrategy = new LambdaQueryWrapper<>();
        queryWrapperStrategy
                .eq(FlowStrategy::getName, flowStrategyParam.getName())
                .eq(FlowStrategy::getState, DataStateEnum.ENABLE.getCode());
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (flowStrategyParam instanceof FlowStrategyParam.FlowStrategyUpdateParam) {
                queryWrapperStrategy.ne(FlowStrategy::getId, ((FlowStrategyParam.FlowStrategyUpdateParam) flowStrategyParam).getId());
            }
        }
        int countByAccount = this.count(queryWrapperStrategy);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new BusinessException(DeviceResponseEnum.FLOW_SAME_NAME);
        }
        List<FlowStrategyVO> strategyFlag = rateOfFlowMapper.getStrategyFlag();
        if (!CollectionUtils.isEmpty(strategyFlag)) {
            if (flowStrategyParam.getFlag().equals(DataStateEnum.ENABLE.getCode())) {
                throw new BusinessException(DeviceResponseEnum.FLOW_FLAG);
            }
        }
    }


}
