package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.equiplog;

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesEquipVariableRwExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.api.iservice.base.IConfigService;
import cn.estsh.i3plus.platform.common.tool.HttpClientTool;
import cn.estsh.i3plus.platform.common.tool.JsonUtilTool;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesConfig;
import cn.estsh.i3plus.pojo.mes.bean.MesEquipmentVariable;
import cn.estsh.i3plus.pojo.mes.bean.MesEquipmentVariableCfg;
import cn.estsh.i3plus.pojo.mes.model.MesEquipVariableRwModel;
import cn.estsh.i3plus.pojo.mes.model.MesEquipVariableRwResult;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MesEquipmentRwExtService implements IMesEquipVariableRwExtService {

    public static final Logger LOGGER = LoggerFactory.getLogger(MesEquipmentRwExtService.class);

    @Autowired
    private IConfigService configService;

    @Override
    public MesEquipVariableRwModel getRwRequestUrl(MesEquipVariableRwModel equipVariableRwModel) {

        if (StringUtils.isEmpty(equipVariableRwModel.getOrganizeCode())) return equipVariableRwModel;

        //根据cfgCode查询缓存的配置数据
        List<MesConfig> configList = configService.doCachedConfigList(MesPcnExtConstWords.EQUIP_VARIABLE_RW_CFG, equipVariableRwModel.getOrganizeCode());

        //搜集读标志数据根据kepwareFlag分组
        Map<String, List<MesConfig>> readUrlMap = getConfigMap(configList, MesExtEnumUtil.READ_WRITE_FLAG.READ.getValueStr());
        //搜集写标志数据根据kepwareFlag分组
        Map<String, List<MesConfig>> writeUrlMap = getConfigMap(configList, MesExtEnumUtil.READ_WRITE_FLAG.WRITE.getValueStr());

        if (CollectionUtils.isEmpty(readUrlMap) && CollectionUtils.isEmpty(writeUrlMap)) return equipVariableRwModel;

        //赋值读/写访问地址
        return equipVariableRwModel.readRequestUrl(getRequestUrl(readUrlMap, equipVariableRwModel.getKepwareFlag())).writeRequestUrl(getRequestUrl(writeUrlMap, equipVariableRwModel.getKepwareFlag()));

    }

    private String getRequestUrl(Map<String, List<MesConfig>> urlMap, String kepwareFlag) {
        if (!CollectionUtils.isEmpty(urlMap) && urlMap.containsKey(kepwareFlag)) return urlMap.get(kepwareFlag).get(0).getCfgValue();
        if (!CollectionUtils.isEmpty(urlMap) && urlMap.containsKey(MesPcnExtConstWords.DEFAULT_KEPWARE_FLAG)) return urlMap.get(MesPcnExtConstWords.DEFAULT_KEPWARE_FLAG).get(0).getCfgValue();
        return null;
    }

    private Map<String, List<MesConfig>> getConfigMap(List<MesConfig> configList, String cfgType) {
        List<MesConfig> filterList = CollectionUtils.isEmpty(configList) ? null :
                configList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCfgType()) && !StringUtils.isEmpty(o.getCfgKey()) && o.getCfgType().equals(cfgType))).collect(Collectors.toList());
        return CollectionUtils.isEmpty(filterList) ? null : filterList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesConfig::getCfgKey));
    }

    @Override
    public MesEquipVariableRwResult writeVariable(MesEquipVariableRwModel equipVariableRwModel) {

        MesEquipVariableRwResult result = checkBefore(equipVariableRwModel, MesExtEnumUtil.READ_WRITE_FLAG.WRITE.getValueStr());

        if (!result.getIsSuccessed()) return result;

        if (StringUtils.isEmpty(equipVariableRwModel.getValue())) return result.noSuccessed().isNoCfg().message("入参缺失必要参数[value]!");

        Map<String, String> params = new HashMap<>();
        params.put(MesPcnExtConstWords.VALUE, equipVariableRwModel.getValue());
        params.put(MesPcnExtConstWords.CLIENT_HANDLE, equipVariableRwModel.getClientHandle().toString());
        params.put(MesPcnExtConstWords.CHANNEL, equipVariableRwModel.getChannel());
        params.put(MesPcnExtConstWords.EQUIPMENT_ID, equipVariableRwModel.getEquipId().toString());

        String data = HttpClientTool.doHttpUrl(CommonEnumUtil.HTTP_METHOD_TYPE.POST, false, equipVariableRwModel.getWriteRequestUrl(), params, null, null);
        LOGGER.info("设备数据变量写值-> 地址:{}, params={}, data:{} ", equipVariableRwModel.getWriteRequestUrl(), params, data);

        result = !StringUtils.isEmpty(data) ? JsonUtilTool.decode(data, MesEquipVariableRwResult.class).obj(JSONObject.toJSONString(equipVariableRwModel)) : result.noSuccessed();
        return result.obj(JSONObject.toJSONString(equipVariableRwModel)).message(String.format("%s设备数据变量写值%s! CLIENT_HANDLE[%s] CHANNEL[%s] EQUIPMENT_ID[%s] VALUE[%s] TAG_NAME[%s] EQUIP_VARIABLE_ID[%s]",
                !StringUtils.isEmpty(result.getMessage()) ? String.format("%s!", result.getMessage()) : MesPcnExtConstWords.EMPTY,
                result.getIsSuccessed() ? "成功" : "失败",
                equipVariableRwModel.getClientHandle(), equipVariableRwModel.getChannel(), equipVariableRwModel.getEquipId(), equipVariableRwModel.getValue(), equipVariableRwModel.getTagName(), equipVariableRwModel.getEquipVariableId()));

    }

    private MesEquipVariableRwResult checkBefore(MesEquipVariableRwModel equipVariableRwModel, String readWriteFlag) {

        if (null == equipVariableRwModel) return new MesEquipVariableRwResult().noSuccessed().isNoCfg().message("入参为空!");

        if (StringUtils.isEmpty(equipVariableRwModel.getOrganizeCode()) || StringUtils.isEmpty(equipVariableRwModel.getChannel()) || StringUtils.isEmpty(equipVariableRwModel.getEquipId()) || StringUtils.isEmpty(equipVariableRwModel.getClientHandle()))
            return new MesEquipVariableRwResult().noSuccessed().isNoCfg().message("入参缺失必要参数,请检查参数[organizeCode][channel][equipId][clientHandle]是否缺失!");

        if (StringUtils.isEmpty(equipVariableRwModel.getWriteRequestUrl()) || StringUtils.isEmpty(equipVariableRwModel.getReadRequestUrl())) getRwRequestUrl(equipVariableRwModel);

        if (MesExtEnumUtil.READ_WRITE_FLAG.READ.getValueStr().equals(readWriteFlag) && StringUtils.isEmpty(equipVariableRwModel.getReadRequestUrl()))
            return new MesEquipVariableRwResult().noSuccessed().isNoCfg().message(String.format("工厂[%s]缺失系统配置信息[%s]读地址URL配置!", equipVariableRwModel.getOrganizeCode(), MesPcnExtConstWords.EQUIP_VARIABLE_RW_CFG));

        if (MesExtEnumUtil.READ_WRITE_FLAG.WRITE.getValueStr().equals(readWriteFlag) && StringUtils.isEmpty(equipVariableRwModel.getWriteRequestUrl()))
            return new MesEquipVariableRwResult().noSuccessed().isNoCfg().message(String.format("工厂[%s]缺失系统配置信息[%s]写地址URL配置!", equipVariableRwModel.getOrganizeCode(), MesPcnExtConstWords.EQUIP_VARIABLE_RW_CFG));

        return new MesEquipVariableRwResult();

    }

    @Override
    public MesEquipVariableRwResult readVariable(MesEquipVariableRwModel equipVariableRwModel) {

        MesEquipVariableRwResult result = checkBefore(equipVariableRwModel, MesExtEnumUtil.READ_WRITE_FLAG.READ.getValueStr());

        if (!result.getIsSuccessed()) return result;

        Map<String, String> params = new HashMap<>();
        params.put(MesPcnExtConstWords.CLIENT_HANDLE, equipVariableRwModel.getClientHandle().toString());
        params.put(MesPcnExtConstWords.CHANNEL, equipVariableRwModel.getChannel());
        params.put(MesPcnExtConstWords.EQUIPMENT_ID, equipVariableRwModel.getEquipId().toString());

        String data = HttpClientTool.doHttpUrl(CommonEnumUtil.HTTP_METHOD_TYPE.POST, false, equipVariableRwModel.getReadRequestUrl(), params, null, null);
        if (!StringUtils.isEmpty(data)) return JsonUtilTool.decode(data, MesEquipVariableRwResult.class);
        else return result.noSuccessed().message(String.format("设备数据变量读值失败! 数据信息:[%s]!", JSONObject.toJSONString(equipVariableRwModel)));

    }
    @Override
    public MesEquipVariableRwResult writeVariable(MesEquipmentVariableCfg equipmentVariableCfg, MesEquipmentVariable equipmentVariable, String kepwareFlag) {
        MesEquipVariableRwModel equipVariableRwModel = new MesEquipVariableRwModel();
        BeanUtils.copyProperties(equipmentVariable, equipVariableRwModel);
        return writeVariable(equipVariableRwModel.tagName(equipmentVariable.getId(), equipmentVariable.getTagName()).value(equipmentVariableCfg.getValue()).kepwareFlag(kepwareFlag));
    }

    @Override
    public MesEquipVariableRwResult writeVariable(String value, MesEquipmentVariable equipmentVariable, String kepwareFlag) {
        MesEquipVariableRwModel equipVariableRwModel = new MesEquipVariableRwModel();
        BeanUtils.copyProperties(equipmentVariable, equipVariableRwModel);
        return writeVariable(equipVariableRwModel.tagName(equipmentVariable.getId(), equipmentVariable.getTagName()).value(value).kepwareFlag(kepwareFlag));
    }

}
