package com.njcn.csdevice.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.csdevice.enums.AlgorithmResponseEnum;
import com.njcn.csdevice.mapper.CsDataArrayMapper;
import com.njcn.csdevice.pojo.dto.DataArrayDTO;
import com.njcn.csdevice.pojo.param.DataArrayParam;
import com.njcn.csdevice.pojo.po.CsDataArray;
import com.njcn.csdevice.pojo.vo.DataArrayTreeVO;
import com.njcn.csdevice.pojo.vo.DeviceManagerDetailVO;
import com.njcn.csdevice.service.ICsDataArrayService;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.api.EpdFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.system.pojo.po.EleEpdPqd;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * <p>
 * 详细数据表 服务实现类
 * </p>
 *
 * @author xuyang
 * @since 2023-05-31
 */
@Service
@AllArgsConstructor
public class CsDataArrayServiceImpl extends ServiceImpl<CsDataArrayMapper, CsDataArray> implements ICsDataArrayService {

    private final EpdFeignClient epdFeignClient;
    private final DicDataFeignClient dicDataFeignClient;

    @Override
    public List<CsDataArray> getArrayBySet(String dataSet) {
        return this.lambdaQuery().eq(CsDataArray::getPid,dataSet).orderByAsc(CsDataArray::getSort).list();
    }

    @Override
    public List<DeviceManagerDetailVO> getTargetById(String id) {
        List<DeviceManagerDetailVO> list = new ArrayList<>();
        List<String> l = this.baseMapper.getDictData(id).stream().map(CsDataArray::getDataId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(l)){
            log.error(AlgorithmResponseEnum.DATA_ARRAY_MISSING.getMessage());
            return list;
        }
        List<EleEpdPqd> result = epdFeignClient.selectByIds(l).getData();
        Map<String,List<EleEpdPqd>> map = result.stream().collect(Collectors.groupingBy(EleEpdPqd::getShowName,LinkedHashMap::new,Collectors.toList()));
        for (Map.Entry<String, List<EleEpdPqd>> entry : map.entrySet()) {
            DeviceManagerDetailVO vo = new DeviceManagerDetailVO();
            EleEpdPqd eleEpdPqd = entry.getValue().get(0);
            if (Objects.equals(eleEpdPqd.getPhase(),"T")){
                vo.setPhasic("/");
            } else {
                vo.setPhasic(entry.getValue().stream()
                        .map(EleEpdPqd::getPhase)
                        .map(phase -> "T".equals(phase) ? "总" : phase)
                        .collect(Collectors.joining(",")));
            }
            vo.setName(entry.getKey());
            vo.setType(eleEpdPqd.getType());
            if(Objects.isNull(eleEpdPqd.getUnit())) {
                vo.setUnit("/");
            } else {
                vo.setUnit(eleEpdPqd.getUnit());
            }
            if (Objects.isNull(eleEpdPqd.getHarmStart()) && Objects.isNull(eleEpdPqd.getHarmEnd())){
                vo.setStartTimes("/");
                vo.setEndTimes("/");
            } else {
                if(Objects.equals(eleEpdPqd.getHarmStart(),1) && Objects.equals(eleEpdPqd.getHarmEnd(),50)) {
                    vo.setStartTimes("0.5");
                    vo.setEndTimes("49.5");
                } else {
                    vo.setStartTimes(Integer.toString(eleEpdPqd.getHarmStart()));
                    vo.setEndTimes(Integer.toString(eleEpdPqd.getHarmEnd()));
                }
            }
            list.add(vo);
        }
        return list;
    }

    @Override
    public List<DataArrayTreeVO> getDataArray(List<String> list) {
        List<DataArrayTreeVO> result = new ArrayList<>();
        List<DataArrayDTO> dataArrayList = this.baseMapper.getData(list);
        Map<String,List<DataArrayDTO>> map = dataArrayList.stream().collect(Collectors.groupingBy(DataArrayDTO::getDataSetName));
        map.forEach((k,v)->{
            List<DataArrayTreeVO> list2 = new ArrayList<>();
            DataArrayTreeVO vo1 = new DataArrayTreeVO();
            vo1.setName(k);
            vo1.setShowName(k);
            v.forEach(item->{
                vo1.setId(item.getDataSetId());
                DataArrayTreeVO vo2 = new DataArrayTreeVO();
                List<DataArrayTreeVO> list3 = new ArrayList<>();
                vo2.setId(item.getDataSetId() + item.getDataArrayName());
                vo2.setName(item.getDataArrayName());
                vo2.setShowName(item.getDataArrayShowName());
                List<String> phaseList = Arrays.asList(item.getPhase().split(","));
                phaseList.forEach(item2->{
                    List<DataArrayTreeVO> list4 = new ArrayList<>();
                    DataArrayTreeVO vo3 = new DataArrayTreeVO();
                    vo3.setId(item.getDataSetId() + item.getDataArrayName()+item2);
                    vo3.setName(item2);
                    if (Objects.equals(item2,"T")){
                        vo3.setShowName("无相别");
                    } else {
                        vo3.setShowName(item2);
                    }
                    if (Objects.isNull(item.getStatMethod())){
                        DataArrayTreeVO vo4 = new DataArrayTreeVO();
                        vo4.setId(item.getDataSetId() + item.getDataArrayName()+item2+"M");
                        vo4.setName("M");
                        vo4.setShowName("无数据类型");
                        list4.add(vo4);
                    } else {
                        List<String> statMethodList = Arrays.asList(item.getStatMethod().split(","));
                        statMethodList.forEach(item3->{
                            DataArrayTreeVO vo4 = new DataArrayTreeVO();
                            vo4.setId(item.getDataSetId() + item.getDataArrayName()+item2 + item3);
                            vo4.setName(item3);
                            switch (item3) {
                                case "avg":
                                    vo4.setShowName("平均值");
                                    break;
                                case "max":
                                    vo4.setShowName("最大值");
                                    break;
                                case "min":
                                    vo4.setShowName("最小值");
                                    break;
                                case "cp95":
                                    vo4.setShowName("CP95");
                                    break;
                                default:
                                    vo4.setShowName(item3);
                                    break;
                            }
                            list4.add(vo4);
                        });
                    }
                    vo3.setChildren(list4);
                    list3.add(vo3);
                });
                vo2.setChildren(list3);
                list2.add(vo2);
            });
            vo1.setChildren(list2);
            result.add(vo1);
        });
        return result;
    }

    @Override
    public List<CsDataArray> getGroupData(String dataSet) {
        return this.baseMapper.getGroupData(dataSet);
    }

    @Override
    public List<CsDataArray> getDataArrayById(String pid, String name) {
        return this.lambdaQuery().eq(CsDataArray::getPid,pid).eq(CsDataArray::getName,name).list();
    }

    @Override
    public List<CsDataArray> getDataArrayByIds(List<String> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return  new ArrayList<>();
        }
        return this.lambdaQuery().in(CsDataArray::getId,ids).list();
    }

    @Override
    public List<CsDataArray> findListByParam(DataArrayParam param) {
        List<CsDataArray> list = this.baseMapper.findListByParam(param);
        if (!CollectionUtils.isEmpty(list)) {
            DictData pqd = dicDataFeignClient.getDicDataByCode(DicDataEnum.PQD.getCode()).getData();
            if (ObjectUtil.isNotNull(pqd) && ObjectUtil.isNotNull(pqd.getId())) {
                List<EleEpdPqd> epdList = epdFeignClient.dictMarkByDataType(pqd.getId()).getData();
                if (!CollectionUtils.isEmpty(epdList)) {
                    Map<String, EleEpdPqd> epdPqdMap = epdList.stream().collect(Collectors.toMap(EleEpdPqd::getId, Function.identity()));
                    list.forEach(item->{
                        EleEpdPqd epdPqd = epdPqdMap.get(item.getDataId());
                        if (!Objects.isNull(epdPqd)) {
                            if (epdPqd.getOtherName() == null || epdPqd.getOtherName().isEmpty()) {
                                item.setInfluxDbName(epdPqd.getName());
                            } else {
                                String[] parts = item.getName().split("_");
                                String lastPart = parts[parts.length - 1];
                                boolean isLastNumeric = lastPart.matches("\\d+");
                                if (isLastNumeric) {
                                    item.setInfluxDbName(epdPqd.getOtherName() + "_" + lastPart);
                                } else {
                                    item.setInfluxDbName(epdPqd.getOtherName());
                                }
                            }
                        }
                    });
                }
            }
        }
        return list;
    }

    @Override
    public List<CsDataArray> getDataArrayByDataSetIds(List<String> dataSetIds) {
        return this.lambdaQuery()
                .in(CsDataArray::getPid,dataSetIds)
                .list();
    }
}
