package com.zd.laboratory.config;

import cn.hutool.core.util.NumberUtil;
import com.zd.common.core.enums.HardwareTypeEnum;
import com.zd.common.core.enums.SenseType;
import com.zd.common.core.utils.Assert;
import com.zd.system.api.laboratory.domain.FunctionStatus;
import com.zd.system.api.laboratory.domain.SensorFunctionStatus;
import com.zd.system.api.laboratory.domain.vo.SenseValVO;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;

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

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

/**
 * 设备功能状态配置
 *
 * @Author: zhoupan
 * @Date: 2021/09/27/15:48
 * @Description:
 */
@ConfigurationProperties(prefix = "app-config.hardware")
@RefreshScope
public class HardwareFunctionStatusConfig {

    private Map<HardwareTypeEnum, List<FunctionStatus>> hardwareFunctionStatusListMap = Collections.emptyMap();

    private Map<String ,FunctionStatus> cache = Collections.emptyMap();
    /**
     * 传感器功能配置
     */
    private Map<SenseType, List<SensorFunctionStatus>> sensorFunctionStatusListMap = Collections.emptyMap();

    /**
     * 传感器及功能VO对象集合
     */
    private List<SenseValVO> senseValVOS;

    public Map <String, FunctionStatus> getCache() {
        return cache;
    }

    /**
     * 传感器的功能列表
     */
    private List<SensorFunctionStatus> sensorFunctionStatuses;

    private Map<String,SensorFunctionStatus> mapFunNum = Collections.emptyMap();


    public Map<String, SensorFunctionStatus> getMapFunNum() {
        return mapFunNum;
    }

    public List<SensorFunctionStatus> getSensorFunctionStatuses() {
        return sensorFunctionStatuses;
    }

    public List<SenseValVO> getSenseValVOS() {
        return senseValVOS;
    }



    /**
     * 获取设备功能：根据值转换-如果没有则应用默认值
     * @param hardwareTypeEnum 设备配型
     * @param code 功能编码
     * @return
     */
    public FunctionStatus conversionByCode(HardwareTypeEnum hardwareTypeEnum, String code) {

        return Optional.ofNullable(hardwareFunctionStatusListMap.get(hardwareTypeEnum))
                .orElseGet(Collections::emptyList)
                .stream()
                .filter(a -> a.getCode().equals(code))
                .findFirst()
                .orElseGet(() -> Optional.ofNullable(hardwareFunctionStatusListMap.get(hardwareTypeEnum))
                        .orElseGet(Collections::emptyList)
                        .stream()
                        .filter(FunctionStatus::getDefaultStatus)
                        .findFirst().orElse(null));

    }

    public List<FunctionStatus> getFunctionStatus(HardwareTypeEnum hardwareTypeEnum) {
        return hardwareFunctionStatusListMap.get(hardwareTypeEnum);
    }


    public Map<HardwareTypeEnum, List<FunctionStatus>> getHardwareFunctionStatusListMap() {
        return hardwareFunctionStatusListMap;
    }

    public void setHardwareFunctionStatusListMap(Map<HardwareTypeEnum, List<FunctionStatus>> hardwareFunctionStatusListMap) {


        this.hardwareFunctionStatusListMap = hardwareFunctionStatusListMap;
        cache = new HashMap <>();
        Optional.ofNullable(        hardwareFunctionStatusListMap)
                .filter(a->a.size()>0)
                .orElseGet(Collections::emptyMap)
                .entrySet()
                .stream()
                .forEach(a->{

                    a.getValue().forEach(c->{

                        cache.put(a.getKey().getCode()+"-"+c.getCode(),c);
                    });
                });

    }


    public Map<SenseType, List<SensorFunctionStatus>> getSensorFunctionStatusListMap() {
        return sensorFunctionStatusListMap;
    }

    public void setSensorFunctionStatusListMap(Map<SenseType, List<SensorFunctionStatus>> sensorFunctionStatusListMap) {

        this.sensorFunctionStatusListMap = sensorFunctionStatusListMap;
        List<SensorFunctionStatus> list = new ArrayList<>(20);
        Set<String>  temp = new HashSet<>();
        senseValVOS = Optional.ofNullable(this.sensorFunctionStatusListMap)
                .orElse(Collections.emptyMap())
                .entrySet()
                .stream()
                .map(a->{
                    temp.clear();
                    SenseValVO senseValVO = new SenseValVO();
                    senseValVO.setSenseType(a.getKey());

                    //排序
                    List<SensorFunctionStatus> value = a.getValue().stream()
                            .map(c->{
                                Assert.isFalse(temp.contains(c.getFunNum()),a.getKey().getName()+"::"+c.getFunNum()+":测点功能定义重复");
                                temp.add(c.getFunNum());
                                return c;
                            })
                            .sorted((c,d)->NumberUtil.compare(c.getOrder(),d.getOrder()) )
                            .collect(Collectors.toList());
                    list.addAll(value);
                    senseValVO.setSensorFunctionStatusesList(value);
                    return senseValVO;
                }).collect(Collectors.toList());

        sensorFunctionStatuses =Optional.ofNullable(list).filter(a->a.size()>0)
                .orElse(Collections.emptyList())
                .stream()
                .sorted((c,d)->NumberUtil.compare(c.getOrder(),d.getOrder()) )
                .collect(collectingAndThen(
                        toCollection(() -> new TreeSet<>(Comparator.comparing(SensorFunctionStatus::getFunNum))), ArrayList::new));
        mapFunNum = Optional.ofNullable(sensorFunctionStatuses)
                .orElseGet(Collections::emptyList)
                .stream()
                .collect(Collectors.toMap(a -> a.getFunNum(), Function.identity()));

    }
}
