package com.ho.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.Device;
import com.ho.business.entity.TabSort;
import com.ho.business.entity.TabTag;
import com.ho.business.entity.TabTagDefaultValue;
import com.ho.business.feignclient.UserFeignClient;
import com.ho.business.mapper.DeviceMapper;
import com.ho.business.mapper.TabSortWebMapper;
import com.ho.business.mapper.TabTagDefaultValueMapper;
import com.ho.business.mapper.TabTagWebMapper;
import com.ho.business.service.DeviceService;
import com.ho.business.service.TabSortWebService;
import com.ho.business.vo.DeviceTransfer;
import com.ho.business.vo.req.TabReqVo;
import com.ho.business.vo.req.TabSortReqVo;
import com.ho.business.vo.resp.DeviceRespVO;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.service.RedisService;
import com.ho.datacollect.api.constant.DataCollectConstant;
import com.ho.user.api.vo.req.SysSubDictVO;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class TabSortWebServiceImpl implements TabSortWebService {

    @Autowired
    private TabSortWebMapper tabSortWebMapper;

    @Autowired
    private TabTagWebMapper tabTagWebMapper;

    @Autowired
    private TabTagDefaultValueMapper tabTagDefaultValueMapper;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    DeviceService deviceService;

    @Autowired
    RedisService redisService;

    @Autowired
    DeviceMapper deviceMapper;

    @Override
    public void addTabSort(TabSortReqVo tabSortReqVo) {
        //添加新页签，先看这个站点有没有其他页签 如果有 拿到版本号时间
        TabSort tabSort = new TabSort();
        BeanUtil.copyProperties(tabSortReqVo,tabSort);
        if(tabSortReqVo!=null){
            // 如果名称重复了给出提示
            List<TabSort> list = tabSortWebMapper.queryTabSortList(tabSortReqVo.getStationId());
            Date versionNo = null;
            if(list!=null&&list.size()>0){
                versionNo = list.get(0).getVersionNo();
                tabSort.setVersionNo(versionNo);
            }else{
                tabSort.setVersionNo(new Date());
            }
            tabSort.setStatus(1);

            if( checkTabSortName(tabSortReqVo.getStationId(),tabSortReqVo.getTabName(),null) ){
                throw new BusinessException(BaseResponseCode.TAB_NAME_EXISTS);
            }
            tabSortWebMapper.insert(tabSort);
        }
    }

    /**
     * 判断电站下页签名称是否重复,如果已经存在返回true
     * @return
     */
    private boolean checkTabSortName(Integer stationId,String tabName,Integer tabId){
        int i = tabSortWebMapper.checkTabName(stationId, tabName,tabId);
        if( i>0 ){
            return true;
        }
        return false;
    }

    @Override
    public void updateByTabId(TabSortReqVo tabSortReqVo) {
        // 编辑的时候先查询一下原来的数据
        if( tabSortReqVo == null ){
            throw new BusinessException(BaseResponseCode.NON_DATA);
        }
        TabSort tabSort = tabSortWebMapper.getTabSortById(tabSortReqVo.getTabId());
        if( checkTabSortName(tabSort.getStationId(),tabSortReqVo.getTabName(),tabSortReqVo.getTabId()) ){
            throw new BusinessException(BaseResponseCode.TAB_NAME_EXISTS);
        }
        tabSortWebMapper.updateByTabId(tabSortReqVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTabSort(Integer id) {
        //删除主页签和附属子页签及默认值
        List<TabTag> tabTagList = tabTagWebMapper.queryTabTagList(id);
        List<Integer> list = tabTagList.stream().map(TabTag::getTagId).collect(Collectors.toList());
        if(!list.isEmpty()){
            tabTagDefaultValueMapper.deleteTagIds(list);
        }
        tabTagWebMapper.deleteTabTags(id);
        tabSortWebMapper.deleteTabSort(id);
    }

    @Override
    public List<TabSort> queryTabSortList(Integer stationId) {
        if(stationId!=null){
            List<TabSort> tabSortList = tabSortWebMapper.queryTabSortList(stationId);
            if( !tabSortList.isEmpty() ){
                for (TabSort tabSort : tabSortList) {
                    TabTag tabTag = tabSortWebMapper.queryTabTag(tabSort.getTabId());
                    if( tabTag != null && tabTag.getDeviceType() != null && tabTag.getSrcId() != null && tabTag.getCol() != null ){
                        DeviceTransfer deviceTransfer = (DeviceTransfer)redisService.hget(tabTag.getDeviceType() + ":" + stationId + ":" + tabTag.getSrcId(), tabTag.getCol());
                        tabSort.setChangeover(deviceTransfer != null && deviceTransfer.getValue() != null ? deviceTransfer.getValue().compareTo(BigDecimal.ZERO)>0?1 : 0 : 0);
                    }
                }
            }
            return tabSortList;
        }
        return null;
    }

    @Override
    public List<TabTag> queryTabTags(Integer tabId,Integer stationId) {
        if(tabId!=null){
            List<TabTag> tabTagList = tabTagWebMapper.queryTabTags(tabId);
            if(tabTagList!=null&&tabTagList.size()>0){
                SysSubDictVO componentTypeVO = new SysSubDictVO();
                componentTypeVO.setType("componentType");
                Map<String, String> componentType = userFeignClient.getSysSubDict(componentTypeVO);
                tabTagList.stream().map(tabTag -> {
                    tabTag.setTagLabel(componentType.get(tabTag.getTagType()+""));
                    if ( tabTag.getDeviceType() != null && tabTag.getSrcId() != null && tabTag.getCol() != null) {
                        DeviceTransfer deviceTransfer = (DeviceTransfer)redisService.hget(tabTag.getDeviceType() + ":" + stationId + ":" + tabTag.getSrcId(), tabTag.getCol());
                        tabTag.setCurrentValue(deviceTransfer != null && deviceTransfer.getValue() != null ? deviceTransfer.getValue().toString() : "");
                    }
                    return tabTag;
                }).collect(Collectors.toList());
            }
            return tabTagList;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void oneKeyCopy(Integer stationId, Integer copyStationId) {
        List<TabSort> tabSortList = tabSortWebMapper.getList(stationId);
        for(TabSort tabSort:tabSortList){
            Integer tabId=tabSort.getTabId();
            tabSort.setStationId(copyStationId);
            tabSortWebMapper.insert(tabSort);
            List<TabTag> tabTagList = tabTagWebMapper.queryTabTagList(tabId);
            if(tabTagList!=null&&tabTagList.size()>0){
                for(TabTag tabTag:tabTagList){
                    Integer tagId=tabTag.getTagId();
                    tabTag.setTabId(tabSort.getTabId());
                    tabTag.setSrcId(null);
                    tabTagWebMapper.insert(tabTag);
                    List<TabTagDefaultValue> tabTagDefaultValueList = tabTagDefaultValueMapper.queryTabTagDefaultValueList(tagId);
                    if(tabTagDefaultValueList!=null&&tabTagDefaultValueList.size()>0){
                        for (TabTagDefaultValue tabTagDefaultValue:tabTagDefaultValueList){
                            tabTagDefaultValue.setTagId(tabTag.getTagId());
                            tabTagDefaultValueMapper.insert(tabTagDefaultValue);
                        }
                    }
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void toggleVersion(TabReqVo tabReqVo) {
        tabSortWebMapper.toggleVersion(tabReqVo);
        tabSortWebMapper.updateVersion(tabReqVo);
    }

    @Override
    public List<Map<String,Object>> queryVersion(@Param("stationId") Integer stationId) {
        if(stationId!=null){
            List<Map<String,Object>> tabSortList = tabSortWebMapper.queryVersion(stationId);
            return tabSortList;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void operateTabTag(TabSort tabSort) {
        //整体删除
        //1.先删除标签默认值表
        if(tabSort!=null){
            List<TabTag> tabTags = tabTagWebMapper.queryTabTags(tabSort.getTabId());
            for(TabTag tabTag:tabTags){
                tabTagDefaultValueMapper.deleteByTagId(tabTag.getTagId());
            }
            tabTagWebMapper.deleteTabTags(tabSort.getTabId());
            //2.插入,这里不能批量插入，需要拿到上级的id
            if(tabSort.getChilds()!=null&&tabSort.getChilds().size()>0){
                for(TabTag tabTag:tabSort.getChilds()){
                    tabTag.setTabId(tabSort.getTabId());
                    if ( tabTag.getSrcId() != null && tabSort.getStationId() != null ) {
                        Device device = deviceMapper.selectByStationIdAndSrcId(tabSort.getStationId(), Integer.parseInt(tabTag.getSrcId()));
                        if ( device != null && device.getDeviceType() != null ) {
                            tabTag.setDeviceType(device.getDeviceType());
                        }
                    }
                    tabTagWebMapper.insert(tabTag);
                    if(tabTag.getValues()!=null&&tabTag.getValues().size()>0){
                        for(TabTagDefaultValue tabTagDefaultValue:tabTag.getValues()){
                            tabTagDefaultValue.setTagId(tabTag.getTagId());
                            tabTagDefaultValueMapper.insert(tabTagDefaultValue);
                        }
                    }
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void exclListToDb(List<TabSort> tabSortList,Integer stationId) {
        //整体删除
        Date date = new Date();
        List<TabSort> list = tabSortWebMapper.getList(stationId);
        if(list!=null){
            if(list.size()==5){
                //如果库里已经有5个了，将删除最早的一个
                List<TabSort> tabSorts = tabSortWebMapper.showTabSortList(stationId, list.get(0).getVersionNo());
                for (TabSort tabSort:tabSorts){
                    List<TabTag> tabTags = tabTagWebMapper.queryTabTags(tabSort.getTabId());
                    for(TabTag tabTag:tabTags){
                        tabTagDefaultValueMapper.deleteByTagId(tabTag.getTagId());
                    }
                    tabTagWebMapper.deleteTabTags(tabSort.getTabId());
                }
                tabSortWebMapper.deleteTabSortLater(stationId,list.get(0).getVersionNo());
            }
            //将库里改站点所有的status变成0
            tabSortWebMapper.updateExclVersion(stationId);

            for(TabSort tabSort:tabSortList){
                tabSort.setStatus(1);
                tabSort.setVersionNo(date);
                tabSortWebMapper.insert(tabSort);
                if(tabSort.getChilds()!=null&&tabSort.getChilds().size()>0){
                    for(TabTag tabTag:tabSort.getChilds()){
                        tabTag.setTabId(tabSort.getTabId());
                        tabTagWebMapper.insert(tabTag);
                        if(tabTag.getValues()!=null&&tabTag.getValues().size()>0){
                            for(TabTagDefaultValue tabTagDefaultValue:tabTag.getValues()){
                                tabTagDefaultValue.setTagId(tabTag.getTagId());
                                tabTagDefaultValueMapper.insert(tabTagDefaultValue);
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public List<TabSort> showVersion(TabReqVo tabReqVo) {
        Date versionNo = tabReqVo.getVersionNo();
        Integer stationId = tabReqVo.getStationId();
        List<TabSort> tabSortList = tabSortWebMapper.showTabSortList(stationId, versionNo);
        if(tabSortList!=null&&tabSortList.size()>0){
            for (TabSort tabSort:tabSortList){
                Integer tabId = tabSort.getTabId();
                List<TabTag> tabTagList = tabTagWebMapper.queryTabTags(tabId);
                tabSort.setChilds(tabTagList);
            }
            return tabSortList;
        }
        return null;
    }

    @Override
    public JSONObject getStationStatus(Integer stationId) {
        JSONObject jsonObject = new JSONObject();
        Integer stationStatus = CommonConstant.ZERO;
        BigDecimal systemStatus = BigDecimal.ZERO;
        Integer flowDirection = CommonConstant.ONE;
        List<DeviceRespVO> deviceRespVOS = deviceService.getListByDeviceType(stationId, DeviceTypeConstant.PCS);
        Map<Integer,Integer> statusMap = new HashMap<Integer,Integer>();
        if(deviceRespVOS.isEmpty()){
            deviceRespVOS = deviceService.getListByFuzzyDeviceType(stationId, DeviceTypeConstant.PCS);
        }
        if(deviceRespVOS!=null&&deviceRespVOS.size()>0){
            for (DeviceRespVO deviceRespVO:deviceRespVOS){
                String deviceType=deviceRespVO.getDeviceType();
                Integer srcId = deviceRespVO.getSrcId();
                flowDirection = deviceRespVO.getFlowDirection();
                String deviceKey = deviceType + ":" + stationId + ":" + srcId;
                if (redisService.hasKey(deviceKey)) {
                    Map<Object, Object> infos = redisService.hgetall(deviceKey);
                    if(!infos.isEmpty()){
                        //当电站点表中单独配置了PCS运行状态runningState，此时取3合一判断
                        DeviceTransfer runStateTransfer = (DeviceTransfer) infos.get(DataCollectConstant.PCS_POINT.runState);
                        DeviceTransfer runningStateDeviceTransfer = (DeviceTransfer) infos.get(DataCollectConstant.PCS_POINT.runningState);
                        Integer runState = runStateTransfer != null && runStateTransfer.getValue() != null? Integer.parseInt(runStateTransfer.getValue().toString()):0;
                        if (runningStateDeviceTransfer != null && runningStateDeviceTransfer.getValue() != null) {
                            runState = getRunState(infos);
                        }
                        if(runState!=null){
                            statusMap.put(runState,null);
                        }
                    }
                    DeviceTransfer outputPower = (DeviceTransfer) redisService.hget(deviceKey, "outputPower");
                    if (outputPower != null) {
                        systemStatus = systemStatus.add(outputPower.getValue());
                    }
                }
            }
            //如果map的key只包含1且不包含0
            if(!statusMap.isEmpty()&&statusMap.size()>0){
                if(statusMap.containsKey(CommonConstant.ONE)&&!statusMap.containsKey(CommonConstant.ZERO)){
                    stationStatus = CommonConstant.ONE;
                }else{
                    stationStatus = CommonConstant.ZERO;
                }
            }
        }
        //电站状态
        jsonObject.put("stationStatus",stationStatus);
        jsonObject.put("systemStatus",systemStatus);
        jsonObject.put("flowDirection",flowDirection==null?CommonConstant.ONE:flowDirection);
        return jsonObject;
    }
    private static Integer getRunState(Map<Object, Object> infos) {
        Integer runState = null;
        //PCS待机状态
        DeviceTransfer deviceStateStandDeviceTransfer = (DeviceTransfer) infos.get(DataCollectConstant.PCS_POINT.deviceStateStand);
        //PCS运行状态
        DeviceTransfer runningStateDeviceTransfer = (DeviceTransfer) infos.get(DataCollectConstant.PCS_POINT.runningState);
        //PCS停机状态
        DeviceTransfer runStateDeviceTransfer = (DeviceTransfer) infos.get(DataCollectConstant.PCS_POINT.runState);
        //停机
        if (runStateDeviceTransfer != null && runStateDeviceTransfer.getValue() != null) {
            if (BigDecimal.ONE.compareTo(runStateDeviceTransfer.getValue()) == 0) {
                runState = CommonConstant.ZERO;
            }
        }
        //运行
        if (runningStateDeviceTransfer != null && runningStateDeviceTransfer.getValue() != null) {
            if (BigDecimal.ONE.compareTo(runningStateDeviceTransfer.getValue()) == 0) {
                runState = CommonConstant.ONE;
            }
        }
        //待机
        if (deviceStateStandDeviceTransfer != null && deviceStateStandDeviceTransfer.getValue() != null) {
            if (BigDecimal.ONE.compareTo(deviceStateStandDeviceTransfer.getValue()) == 0) {
                runState = CommonConstant.ONE;
            }
        }
        return runState;
    }

    @Override
    public void chooseState(Integer tagId,Integer tabId) {
        // 首先查询标签对应的tabId,修改所有这个tabId下的changeover属性为0
        if( tabId != null ){
            tabSortWebMapper.updateChangeover(tabId);
        }
        if ( tagId != null ) {
            tabSortWebMapper.chooseState(tagId);
        }
    }

    @Override
    public int queryTabTagIsChangeover(Integer tabId) {
        return tabSortWebMapper.queryTabTagIsChangeover(tabId);
    }
}
