package com.gyee.alarm.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.gyee.alarm.init.Cache.PointUnitCache;
import com.gyee.alarm.init.Cache.WindturbineCache;
import com.gyee.alarm.mapper.auto.*;
import com.gyee.alarm.model.auto.*;
import com.gyee.alarm.model.vo.TreeNode;
import com.gyee.alarm.service.auto.impl.ProBasicDeviceMetricsServiceImpl;
import com.gyee.alarm.service.auto.impl.ProBasicDeviceModelMetricsServiceImpl;
import com.gyee.alarm.service.auto.impl.ProBasicEquipmentPointServiceImpl;
import com.gyee.alarm.service.auto.initalcache.CacheService;
import com.gyee.alarm.util.SnowflakeGenerator;
import com.gyee.alarm.util.StringUtils;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 设备管理相关数据服务
 */
@Service
@Slf4j
public class DeviceService {
    @Resource
    private WindturbineCache windturbineCache;

    @Resource
    private ProBasicDeviceMetricsServiceImpl proBasicDeviceMetricsService;
    @Resource
    private ProBasicDeviceModelMetricsServiceImpl proBasicDeviceModelMetricsService;
    @Resource
    private ProBasicEquipmentPointServiceImpl proBasicEquipmentPointService;
    @Resource
    private PointUnitCache pointUnitCache;

    @Resource
    private ProBasicDeviceMapper proBasicDeviceMapper;

    @Resource
    private ProBasicDeviceStructureMapper proBasicDeviceStructureMapper;

    @Resource
    private ProBasicDeviceMetricsMapper proBasicDeviceMetricsMapper;

    @Resource
    private ProBasicDeviceModelMapper proBasicDeviceModelMapper;

    @Resource
    private ProBasicDeviceModelMetricsMapper roBasicDeviceModelMetricsMapper;
    public JSONObject getTestingPointByStructCode(String deviceId, String structCode, String windturbineId, int pageSize, int pageNum) {
        JSONObject resultObject = new JSONObject();
        List<JSONObject> jsonArrayList = new ArrayList<>();
        String modelId = "";
        ProBasicEquipment windturbine = windturbineCache.getWindturbine(windturbineId);
        if (windturbine != null)
        {
            modelId = windturbine.getModelId();
        }



        if (StringUtils.isNotBlank(structCode)) {
            List<ProBasicDeviceMetrics> metricsList = proBasicDeviceMetricsService.getDeviceMetricsByStructureCode(deviceId, structCode);

            List<String> collect = metricsList.stream().map(s -> s.getMetricCode()).collect(Collectors.toList());

            if (collect.size() > 0) {
                List<ProBasicDeviceModelMetrics> deviceModelMetricsList = proBasicDeviceModelMetricsService.getDeviceModelMetrics(collect, modelId);
                List<String> uniformcodeList = deviceModelMetricsList.stream().map(s -> s.getUniformCode()).collect(Collectors.toList());

                List<String> uniformcodeList_AI = uniformcodeList.stream().filter(s -> s.toUpperCase().contains("AI")).collect(Collectors.toList());
                List<String> uniformcodeList_DI = uniformcodeList.stream().filter(s -> s.toUpperCase().contains("DI")).collect(Collectors.toList());

                List<ProBasicEquipmentPoint> testingPointAIS = new ArrayList<>();
                if (uniformcodeList_AI.size() > 0)
                    testingPointAIS = proBasicEquipmentPointService.getPointListAI(windturbineId, uniformcodeList_AI);
                List<ProBasicEquipmentPoint> testingPointDIS = new ArrayList<>();
                if (uniformcodeList_DI.size() > 0)
                    testingPointDIS = proBasicEquipmentPointService.getPointListDI(windturbineId, uniformcodeList_DI);

                Map<String, ProBasicDeviceMetrics> mapByModel = pointUnitCache.getMapByModel(modelId);

                List<JSONObject> array_ai = new ArrayList<>();
                List<JSONObject> array_di = new ArrayList<>();
                for (ProBasicEquipmentPoint ai :
                        testingPointAIS) {

                    if(ai.getUniformCode()==null||!ai.getUniformCode().toUpperCase().startsWith("AI"))
                        continue;
                    JSONObject obj = new JSONObject();

                    obj.put("englishName", ai.getEnglishName());
                    obj.put("modelId", ai.getModelId());
                    obj.put("name", ai.getName());
                    obj.put("valueUnit", ai.getValueUnit());
                    obj.put("model", ai.getModel());
                    obj.put("typeId", ai.getTypeId());
                    obj.put("id", ai.getId());
                    obj.put("uniformCode", ai.getUniformCode());


                    String unitName = "";
                    String unitNameCn = "";
                    if (mapByModel != null) {
                        if (mapByModel.containsKey(ai.getUniformCode())) {
                            unitName = mapByModel.get(ai.getUniformCode()).getUnitName();
                            unitNameCn = mapByModel.get(ai.getUniformCode()).getUnitNamecn();
                        }
                    }
                    obj.put("unitName", unitName);
                    obj.put("unitNameCn", unitNameCn);
                    array_ai.add(obj);

                }

                for (ProBasicEquipmentPoint di :
                        testingPointDIS) {
                    if(di.getUniformCode()==null||!di.getUniformCode().toUpperCase().startsWith("DI"))
                        continue;
                    JSONObject obj = new JSONObject();

                    obj.put("englishName", di.getEnglishName());
                    obj.put("modelId", di.getModelId());
                    obj.put("name", di.getName());
                    obj.put("valueUnit", di.getValueUnit());
                    obj.put("model", di.getModel());
                    obj.put("typeId", di.getTypeId());
                    obj.put("id", di.getId());
                    obj.put("uniformCode", di.getUniformCode());
                    String unitName = "";
                    String unitNameCn = "";
                    if (mapByModel != null) {
                        if (mapByModel.containsKey(di.getUniformCode())) {
                            unitName = mapByModel.get(di.getUniformCode()).getUnitName();
                            unitNameCn = mapByModel.get(di.getUniformCode()).getUnitNamecn();
                        }
                    }
                    obj.put("unitName", unitName);
                    obj.put("unitNameCn", unitNameCn);
                    array_di.add(obj);

                }

                jsonArrayList.addAll(array_ai);
                jsonArrayList.addAll(array_di);

                List<List<JSONObject>> partition = Lists.partition(jsonArrayList, pageSize);

                if (partition.size() > 0)
                    resultObject.put("records", partition.get(pageNum - 1));
                else
                    resultObject.put("records", new ArrayList<>());
                resultObject.put("total", jsonArrayList.size());
                resultObject.put("pages", partition.size());
                resultObject.put("current", pageNum);

            }
        } else {

            List<ProBasicEquipmentPoint> aiPointList = proBasicEquipmentPointService.getPointListAI(windturbineId, new ArrayList<>());
            List<ProBasicEquipmentPoint> diPointList = proBasicEquipmentPointService.getPointListDI(windturbineId, new ArrayList<>());

            Map<String, ProBasicDeviceMetrics> mapByModel = pointUnitCache.getMapByModel(modelId);

            List<JSONObject> array_ai = new ArrayList<>();
            List<JSONObject> array_di = new ArrayList<>();
            for (ProBasicEquipmentPoint ai :
                    aiPointList) {
                if(ai.getUniformCode()==null||!ai.getUniformCode().toUpperCase().startsWith("AI"))
                    continue;
                JSONObject obj = new JSONObject();
                obj.put("englishName", ai.getEnglishName());
                obj.put("modelId", ai.getModelId());
                obj.put("name", ai.getName());
                obj.put("valueUnit", ai.getValueUnit());
                obj.put("model", ai.getModel());
                obj.put("typeId", ai.getTypeId());
                obj.put("id", ai.getId());
                obj.put("uniformCode", ai.getUniformCode());
                String unitName = "";
                String unitNameCn = "";
                if (mapByModel != null) {
                    if (mapByModel.containsKey(ai.getUniformCode())) {
                        unitName = mapByModel.get(ai.getUniformCode()).getUnitName();
                        unitNameCn = mapByModel.get(ai.getUniformCode()).getUnitNamecn();
                    }
                }

                obj.put("unitName", unitName);
                obj.put("unitNameCn", unitNameCn);
                array_ai.add(obj);

            }

            for (ProBasicEquipmentPoint di :
                    diPointList) {
                if(di.getUniformCode()==null||!di.getUniformCode().toUpperCase().startsWith("DI"))
                    continue;
                JSONObject obj = new JSONObject();
                obj.put("englishName", di.getEnglishName());
                obj.put("modelId", di.getModelId());
                obj.put("name", di.getName());
                obj.put("valueUnit", di.getValueUnit());
                obj.put("model", di.getModel());
                obj.put("typeId", di.getTypeId());
                obj.put("id", di.getId());
                obj.put("uniformCode", di.getUniformCode());

                String unitName = "";
                String unitNameCn = "";
                if (mapByModel != null) {
                    if (mapByModel.containsKey(di.getUniformCode())) {
                        unitName = mapByModel.get(di.getUniformCode()).getUnitName();
                        unitNameCn = mapByModel.get(di.getUniformCode()).getUnitNamecn();
                    }
                }

                obj.put("unitName", unitName);
                obj.put("unitNameCn", unitNameCn);
                array_di.add(obj);

            }
            jsonArrayList.addAll(array_ai);
            jsonArrayList.addAll(array_di);

            List<List<JSONObject>> partition = Lists.partition(jsonArrayList, pageSize);

            if (partition.size() > 0)
                resultObject.put("records", partition.get(pageNum - 1));
            else
                resultObject.put("records", new ArrayList<>());
            resultObject.put("total", jsonArrayList.size());
            resultObject.put("pages", partition.size());
            resultObject.put("current", pageNum);
        }
        return resultObject;


    }


    public List<ProBasicDevice> getAllDevice() {
        QueryWrapper<ProBasicDevice> queryWrapper = new QueryWrapper<>();
        return proBasicDeviceMapper.selectList(queryWrapper);
    }

    public List<ProBasicDeviceStructure> getAllDeviceStructure() {
        QueryWrapper<ProBasicDeviceStructure> queryWrapper = new QueryWrapper<>();
        return proBasicDeviceStructureMapper.selectList(queryWrapper);
    }


    public List<ProBasicDeviceStructure> getDeviceStructureByDeviceId(String deviceId) {
        return proBasicDeviceStructureMapper.getDeviceStructureByDeviceId(deviceId);
    }

    public List<ProBasicDeviceStructure> getDeviceStructureChildNode(String deviceId, String nodeCode) {
        return proBasicDeviceStructureMapper.getDeviceStructureChildNode(deviceId, nodeCode);
    }

    public ProBasicDeviceStructure getDeviceStructureByCode(String deviceId, String nodeCode) {
        return proBasicDeviceStructureMapper.getDeviceStructureByCode(deviceId, nodeCode);
    }

    public TreeNode<ProBasicDeviceStructure> getDeviceStructureTree(String deviceId) {

        if (CacheService.deviceStructureMap == null) {
            CacheService.deviceStructureMap = new HashMap<>();
        }

        if (CacheService.deviceStructureMap.containsKey(deviceId))
            return CacheService.deviceStructureMap.get(deviceId);

        List<ProBasicDeviceStructure> lst = proBasicDeviceStructureMapper.getDeviceStructureChildNode(deviceId, "0");
        if (lst != null && lst.size() > 0) {
            ProBasicDeviceStructure ds = lst.get(0);
            TreeNode<ProBasicDeviceStructure> treeNode = getSubDeviceStructureTreeNode(ds);
            CacheService.deviceStructureMap.put(ds.getDeviceId(), treeNode);
            return treeNode;
        }

        return null;
    }

    public TreeNode<ProBasicDeviceStructure> getDeviceStructureTree(String deviceId, String nodeCode) {

        ProBasicDeviceStructure ds = proBasicDeviceStructureMapper.getDeviceStructureByCode(deviceId, nodeCode);
        return getSubDeviceStructureTreeNode(ds);
    }

    private TreeNode<ProBasicDeviceStructure> getSubDeviceStructureTreeNode(ProBasicDeviceStructure ds) {

        TreeNode<ProBasicDeviceStructure> rootNode = new TreeNode<>();
        if (ds == null)
            return rootNode;
        rootNode.setNode(ds);

        List<ProBasicDeviceStructure> dsList = proBasicDeviceStructureMapper.getDeviceStructureChildNode(ds.getDeviceId(), ds.getCode());
        if (dsList != null && dsList.size() > 0) {
            List<TreeNode> children = new ArrayList<>();
            for (ProBasicDeviceStructure ds1 : dsList) {
                children.add(getSubDeviceStructureTreeNode(ds1));
            }
            rootNode.setChildren(children);
        }

        return rootNode;

    }

    public int deleteDeviceStructure(String dsId) {
        int code = proBasicDeviceStructureMapper.deleteById(dsId);
        if (code >= 1) {
            //树结构变化清空树结构缓存
            CacheService.deviceStructureMap.clear();
        }
        return code;
    }

    public int saveOrUpdateDeviceStructure(ProBasicDeviceStructure ds) {
        int result = 0;
        if (StringUtils.empty(ds.getId())) {
            //如果id为空，则通过雪花算法 生成一个id
            ds.setId(String.valueOf(SnowflakeGenerator.generateId()));
            result = proBasicDeviceStructureMapper.insert(ds);
        } else {
            ProBasicDeviceStructure oldData = proBasicDeviceStructureMapper.selectById(ds.getId());
            if (oldData != null) {
                result = proBasicDeviceStructureMapper.updateById(ds);
            } else {
                result = proBasicDeviceStructureMapper.insert(ds);
            }
        }
        //树结构变化清空树结构缓存
        CacheService.deviceStructureMap.clear();
        return result;

    }

    public List<ProBasicDeviceMetrics> getDeviceMetricsByDeviceId(String deviceId) {
        return proBasicDeviceMetricsMapper.getDeviceMetricsByDeviceId(deviceId);
    }

    public List<ProBasicDeviceMetrics> getDeviceMetricsByStructureCode(String deviceId, String structureCode) {
        return proBasicDeviceMetricsMapper.getDeviceMetricsByStructureCode(deviceId, structureCode);
    }

    public ProBasicDeviceMetrics getDeviceMetricsByCode(String deviceId, String metricCode) {
        return proBasicDeviceMetricsMapper.getDeviceMetricsByCode(deviceId, metricCode);
    }

    public int deleteDeviceMetric(String metricId) {
        return proBasicDeviceMetricsMapper.deleteById(metricId);
    }

    public int saveOrUpdateDeviceMetric(ProBasicDeviceMetrics metrics, List<ProBasicDeviceModelMetrics> deviceModelMetrics) {

        int result = 0;
        if ( StringUtils.empty(metrics.getId())) {
            //如果id为空，则通过雪花算法 生成一个id
            metrics.setId(String.valueOf(SnowflakeGenerator.generateId()));
            result = proBasicDeviceMetricsMapper.insert(metrics);
        } else {
            ProBasicDeviceMetrics oldData = proBasicDeviceMetricsMapper.selectById(metrics.getId());
            if (oldData != null) {
                result = proBasicDeviceMetricsMapper.updateById(metrics);
            } else {
                result = proBasicDeviceMetricsMapper.insert(metrics);
            }
        }
        if (deviceModelMetrics != null && deviceModelMetrics.size() > 0) {
            for (ProBasicDeviceModelMetrics deviceModelMetrics1 : deviceModelMetrics) {
                if (StringUtils.empty(deviceModelMetrics1.getId())) {
                    //如果id为空，则通过雪花算法 生成一个id
                    deviceModelMetrics1.setId(String.valueOf(SnowflakeGenerator.generateId()));
                    result = roBasicDeviceModelMetricsMapper.insert(deviceModelMetrics1);
                } else {
                    ProBasicDeviceModelMetrics deviceModelMetrics2 = roBasicDeviceModelMetricsMapper.selectById(deviceModelMetrics1.getId());
                    if (deviceModelMetrics2 != null) {
                        result = roBasicDeviceModelMetricsMapper.updateById(deviceModelMetrics1);
                    } else {
                        result = roBasicDeviceModelMetricsMapper.insert(deviceModelMetrics1);
                    }
                }
            }
        }

        return result;

    }


    public List<ProBasicDeviceModel> getDeviceModelsById(String id) {
        return proBasicDeviceModelMapper.getDeviceModelsById(id);
    }

    public int deleteDeviceModel(int id) {
        return proBasicDeviceModelMapper.deleteById(id);
    }

    public ProBasicDeviceModel getDeviceModelByCode(String deviceid, String code) {
        return proBasicDeviceModelMapper.getDeviceModelByCode(deviceid, code);
    }

    public int saveOrUpdateDeviceModel(ProBasicDeviceModel deviceModel) {
        int result = 0;
        if (StringUtils.notEmp(deviceModel.getId())) {
            //如果id为空，则通过雪花算法 生成一个id
            deviceModel.setId(String.valueOf(SnowflakeGenerator.generateId()));
            result = proBasicDeviceModelMapper.insert(deviceModel);
        } else {
            ProBasicDeviceModel oldData = proBasicDeviceModelMapper.selectById(deviceModel.getId());
            if (oldData != null) {
                result = proBasicDeviceModelMapper.updateById(deviceModel);
            } else {
                result = proBasicDeviceModelMapper.insert(deviceModel);
            }
        }

        return result;
    }

    public List<ProBasicDeviceModel> getDeviceModelList() {
        QueryWrapper<ProBasicDeviceModel> queryWrapper = new QueryWrapper<>();
        return proBasicDeviceModelMapper.selectList(queryWrapper);
    }

    public List<ProBasicDeviceModelMetrics> getDeviceModelMetricsList() {
        QueryWrapper<ProBasicDeviceModelMetrics> queryWrapper = new QueryWrapper<>();
        return roBasicDeviceModelMetricsMapper.selectList(queryWrapper);
    }

    public IPage<ProBasicDeviceMetrics> pageQueryAll(Page page, String deviceId, String structureCode) {

        if(StringUtils.empty(deviceId))
        {
            deviceId=null;
        }
        if(StringUtils.empty(structureCode))
        {
            structureCode=null;
        }
        return proBasicDeviceMetricsMapper.pageQueryAll(page, deviceId, structureCode);
    }

    public int insertOrUpdate(List<ProBasicDeviceMetrics> deviceMetrics) {
        int s = 0;
        for (ProBasicDeviceMetrics deviceMetrics1 : deviceMetrics) {
            ProBasicDeviceMetrics deviceMetrics2 = proBasicDeviceMetricsMapper.selectByMetriccode(deviceMetrics1.getMetricCode());
            if (deviceMetrics2 != null) {
                deviceMetrics1.setId(deviceMetrics2.getId());
                s = proBasicDeviceMetricsMapper.updateById(deviceMetrics1);
            } else {
                deviceMetrics1.setDeviceId("windturbine");
                deviceMetrics1.setId(String.valueOf(SnowflakeGenerator.generateId()));
                s = proBasicDeviceMetricsMapper.insert(deviceMetrics1);
            }
        }
        return s;
    }

   

    public IPage<ProBasicDeviceModel> pageQueryDeviceModel(Page<ProBasicDeviceModel> page, String code, String stationname) {
        QueryWrapper<ProBasicDeviceModel> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(code))
            wrapper.like("code", code);
        if (StringUtils.isNotBlank(stationname))
            wrapper.like("station_name", stationname);
        return proBasicDeviceModelMapper.selectPage(page, wrapper);
    }
}
