package com.ho.business.service.impl;

import com.ho.business.entity.ModelTypeCol;
import com.ho.business.entity.*;
import com.ho.business.mapper.DeviceTypeColMapper;
import com.ho.business.service.*;
import com.ho.business.vo.req.deviceModel.DeviceCol;
import com.ho.business.vo.req.deviceModel.*;
import com.ho.common.tools.constant.RedisKeyConstant;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.service.RedisService;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author gyan
 * @desc: TODO
 * @DateTime: 2023/3/7 17:44
 */
@Service
@Slf4j
public class DeviceModelServiceImpl implements DeviceModelService {

    @Autowired
    DeviceTypeColMapper deviceTypeColMapper;

    @Autowired
    ModelDeviceColService modelDeviceColService;

    @Autowired
    DeviceTypeService deviceTypeService;

    @Autowired
    ModelTypeService modelTypeService;

    @Autowired
    ModelTypeColService modelTypeColService;

    @Autowired
    DeviceTypeConfigService deviceTypeConfigService;

    @Autowired
    RedisService redisService;

    @Override
    public void addBatchDevice(DeviceModelAddReqVo vo) {
        //判断col是否存在重复（入参中是否存在）
        List<DeviceCol> colList = vo.getColList();
        List<String> collect = colList.stream().map(DeviceCol::getCol)
                .collect(Collectors.toList());
        List<String> colName = colList.stream().map(DeviceCol::getColName)
                .collect(Collectors.toList());
        long colCount = collect.stream().distinct().count();
        if (collect.size() != colCount || colName.size() != colCount) {
            throw new BusinessException(BaseResponseCode.EXISTS_DUPLICATE_DATA);
        }

        //修改时判断col是否在关联表中使用
        List<Integer> updateColIdList = new ArrayList<>();
        List<DeviceCol> updateList = new ArrayList<>();
        List<DeviceCol> addColList = new ArrayList<>();
        for (DeviceCol deviceCol : colList) {
            if (deviceCol.getId() != null) {
                updateColIdList.add(deviceCol.getId());
                updateList.add(deviceCol);
            } else {
                addColList.add(deviceCol);
            }
        }
        //通过id查看是否在关联表中使用
  /*      List<ModelDeviceCol> cols = new ArrayList<>();
        if (!updateColIdList.isEmpty()) {
            cols = modelDeviceColService.selectByDeviceIds(updateColIdList, vo.getDeviceType());
        }
        if (!cols.isEmpty()) {
            throw new BusinessException(BaseResponseCode.MODIFIED_DATA_REFERENCED_CANNOT_CHANGED);
        }*/

        //在表中是（device_type_col）否存在
        List<String> addCollect = addColList.stream().map(DeviceCol::getCol)
                .collect(Collectors.toList());
        if (!addCollect.isEmpty()) {
            List<DeviceTypeCol> deviceTypeCols = deviceTypeColMapper.selectSameCol(vo.getDeviceType(), addCollect,null);
            if (!deviceTypeCols.isEmpty()) {
                throw new BusinessException(BaseResponseCode.THE_SAME_DATA_EXISTS_DATABASE_PLEASE_CHECK);
            }
        }

        //根据deviceType 查询到设备名称以及设备srcId
//        DeviceType deviceType = deviceTypeService.selectByDeviceType(vo.getDeviceType());
//        if (deviceType == null) {
//            throw new BusinessException(BaseResponseCode.DEVICE_NOT_EXIST);
//        }
        // 修正：由原来从DeviceType中查设备名称修改为从DeviceTypeConfig中查，
        DeviceTypeConfig deviceTypeConfig = deviceTypeConfigService.selectByDeviceType(vo.getDeviceType(),vo.getGroupId());
        if (deviceTypeConfig == null) {
            throw new BusinessException(BaseResponseCode.DEVICE_NOT_EXIST);
        }
        //对修改新增做区分
        if (!updateList.isEmpty()) {
            List<DeviceTypeCol> deviceTypeColList = new ArrayList<>();
            for (DeviceCol deviceCol : updateList) {
                DeviceTypeCol deviceTypeCol = new DeviceTypeCol();
                deviceTypeCol.setId(deviceCol.getId());
                deviceTypeCol.setDeviceType(vo.getDeviceType());
                deviceTypeCol.setCol(deviceCol.getCol());
                deviceTypeCol.setColName(deviceCol.getColName());
                deviceTypeCol.setDeviceTypeId(null);
                deviceTypeCol.setDeviceTypeName(deviceTypeConfig.getName());
                deviceTypeCol.setSensType(deviceCol.getSensType());
                deviceTypeCol.setIsShow(deviceCol.getIsShow());
                deviceTypeCol.setIsSave(deviceCol.getIsSave());
                deviceTypeCol.setMaxValue(deviceCol.getMaxValue());
                deviceTypeCol.setMinValue(deviceCol.getMinValue());
                deviceTypeCol.setSpecifiedValue(deviceCol.getSpecifiedValue());
                deviceTypeCol.setOffsetValue(deviceCol.getOffsetValue());
                deviceTypeCol.setFactor(deviceCol.getFactor());
                deviceTypeCol.setUnit(deviceCol.getUnit());
                deviceTypeColList.add(deviceTypeCol);
            }
            for (DeviceTypeCol deviceTypeCol : deviceTypeColList) {
                deviceTypeColMapper.updateByPrimaryKey(deviceTypeCol);
            }
        }
        if (!addColList.isEmpty()) {
            List<DeviceTypeCol> deviceTypeColList = new ArrayList<>();
            for (DeviceCol deviceCol : addColList) {
                DeviceTypeCol deviceTypeCol = new DeviceTypeCol();
                deviceTypeCol.setDeviceType(vo.getDeviceType());
                deviceTypeCol.setCol(deviceCol.getCol());
                deviceTypeCol.setColName(deviceCol.getColName());
                deviceTypeCol.setDeviceTypeId(null);
                deviceTypeCol.setDeviceTypeName(deviceTypeConfig.getName());
                deviceTypeCol.setSensType(deviceCol.getSensType());
                deviceTypeCol.setIsShow(deviceCol.getIsShow());
                deviceTypeCol.setIsSave(deviceCol.getIsSave());
                deviceTypeCol.setMaxValue(deviceCol.getMaxValue());
                deviceTypeCol.setMinValue(deviceCol.getMinValue());
                deviceTypeCol.setSpecifiedValue(deviceCol.getSpecifiedValue());
                deviceTypeCol.setOffsetValue(deviceCol.getOffsetValue());
                deviceTypeCol.setFactor(deviceCol.getFactor());
                deviceTypeCol.setUnit(deviceCol.getUnit());
                deviceTypeColList.add(deviceTypeCol);
            }
            deviceTypeColMapper.addBatchDevice(deviceTypeColList);
        }

    }

    @Override
    public void addDeviceTypeCol(DeviceTypeColAddReq vo) {
        DeviceTypeCol deviceCol = deviceTypeColMapper.selectTypeAndCol(vo.getCol(), vo.getDeviceType(),null);
        if (deviceCol != null && vo.getId() == null) {
            throw new BusinessException(BaseResponseCode.THE_SAME_DATA_EXISTS_DATABASE_PLEASE_CHECK);
        }
        if (deviceCol != null) {
            BeanUtils.copyProperties(vo, deviceCol);
            deviceTypeColMapper.updateByPrimaryKey(deviceCol);
        } else {
            DeviceTypeCol deviceTypeCol = new DeviceTypeCol();
            BeanUtils.copyProperties(vo, deviceTypeCol);
            deviceTypeCol.setDeviceTypeId(null);
            deviceTypeColMapper.insertSelective(deviceTypeCol);
        }
    }

    @Override
    public void deleteBatchDevice(DeviceModelDeleteReqVo vo) {
        //删除前到关联表中进行 判断是否被使用
        List<ModelDeviceCol> deviceColList = modelDeviceColService.selectByDeviceIds(vo.getIds(), null);
        if (!deviceColList.isEmpty()) {
            throw new BusinessException(BaseResponseCode.REFERENCES_EXIST_DELETED_DATA);
        } else {
            deviceTypeColMapper.deleteBatchDevice(vo.getIds());
        }
    }

    @Override
    public List<DeviceTypeCol> deviceColPage(DeviceColSelectReqVo vo) {
        DeviceTypeCol deviceTypeCol = new DeviceTypeCol();
        deviceTypeCol.setDeviceType(vo.getType());
        deviceTypeCol.setCol(vo.getCol());
        deviceTypeCol.setColName(vo.getColName());
        List<DeviceTypeCol> deviceTypeCols = deviceTypeColMapper.selectByParam(deviceTypeCol);
        if(vo.getType()!=null && StringUtil.isEmpty(vo.getCol()) && StringUtil.isEmpty(vo.getColName()) && deviceTypeCols!=null){
            cleanRedisDeviceTypeCol(vo.getType(),deviceTypeCols);
        }
        return deviceTypeCols;
    }

    @Override
    public List<ModelTypeCol> ModelColPage(DeviceColSelectReqVo vo) {
        List<ModelTypeCol> list = modelTypeColService.selectByModelType(vo);
        return list;
    }

    @Override
    public void addBatchModel(DeviceModelAddReqVo vo) {
        //判断col是否存在重复（入参中是否存在）
        List<DeviceCol> colList = vo.getColList();
        List<String> collect = colList.stream().map(DeviceCol::getCol)
                .collect(Collectors.toList());
        List<String> colName = colList.stream().map(DeviceCol::getColName)
                .collect(Collectors.toList());
        long colCount = collect.stream().distinct().count();
        if (collect.size() != colCount || colName.size() != colCount) {
            throw new BusinessException(BaseResponseCode.EXISTS_DUPLICATE_DATA);
        }

        /*修改时根据id进行判断*/
        List<Integer> updateColIdList = new ArrayList<>();
        List<DeviceCol> updateList = new ArrayList<>();
        List<DeviceCol> addColList = new ArrayList<>();
        for (DeviceCol deviceCol : colList) {
            if (deviceCol.getId() != null) {
                updateColIdList.add(deviceCol.getId());
                updateList.add(deviceCol);
            } else {
                addColList.add(deviceCol);
            }
        }

        //对于新增的在 在模型表中看 否存在
        List<String> colIdList = addColList.stream().map(DeviceCol::getCol)
                .collect(Collectors.toList());
        if (!colIdList.isEmpty()) {
            List<ModelTypeCol> deviceTypeCols = modelTypeColService.selectSameModelCol(vo.getDeviceType(), colIdList);
            if (!deviceTypeCols.isEmpty()) {
                throw new BusinessException(BaseResponseCode.THE_SAME_DATA_EXISTS_DATABASE_PLEASE_CHECK);
            }
        }

        //通过id查看是否在关联表中使用
/*        List<ModelDeviceCol> cols = modelDeviceColService.selectByModelIds(updateColIdList, vo.getDeviceType());
        if (!cols.isEmpty()) {
            throw new BusinessException(BaseResponseCode.MODIFIED_DATA_REFERENCED_CANNOT_CHANGED);
        }*/
        //根据modeltype获取查询 model_type_name
        ModelType byModelType = modelTypeService.selectByModelType(vo.getDeviceType());

        //对修改新增做区分
        if (!updateList.isEmpty()) {
            List<ModelTypeCol> ModelTypeColTypeColList = new ArrayList<>();
            for (DeviceCol deviceCol : updateList) {
                ModelTypeCol modelTypeCol = new ModelTypeCol();
                modelTypeCol.setId(deviceCol.getId());
                modelTypeCol.setModelTypeId(byModelType.getId());
                modelTypeCol.setModelType(byModelType.getModelType());
                modelTypeCol.setModelTypeName(byModelType.getModelName());
                modelTypeCol.setCol(deviceCol.getCol());
                modelTypeCol.setColName(deviceCol.getColName());
                ModelTypeColTypeColList.add(modelTypeCol);
            }
            for (ModelTypeCol modelTypeCol : ModelTypeColTypeColList) {
                modelTypeColService.updateByPrimaryKeySelective(modelTypeCol);
            }
        }
        if (!addColList.isEmpty()) {
            List<ModelTypeCol> ModelTypeColTypeColList = new ArrayList<>();
            for (DeviceCol deviceCol : addColList) {
                ModelTypeCol modelTypeCol = new ModelTypeCol();
                modelTypeCol.setModelTypeId(byModelType.getId());
                modelTypeCol.setModelType(byModelType.getModelType());
                modelTypeCol.setModelTypeName(byModelType.getModelName());
                modelTypeCol.setCol(deviceCol.getCol());
                modelTypeCol.setColName(deviceCol.getColName());
                ModelTypeColTypeColList.add(modelTypeCol);
            }
            modelTypeColService.addBatchModel(ModelTypeColTypeColList);
        }

    }


    @Override
    public void deleteBatchModel(DeviceModelDeleteReqVo vo) {
        //删除前到关联表中进行 判断是否被使用
        List<ModelDeviceCol> modelDeviceCols = modelDeviceColService.selectByModelIds(vo.getIds(), null);
        if (!modelDeviceCols.isEmpty()) {
            throw new BusinessException(BaseResponseCode.REFERENCES_EXIST_DELETED_DATA);
        } else {
            deviceTypeColMapper.deleteBatchModel(vo.getIds());
        }
    }

    @Override
    public List<DeviceTypeCol> selectByIds(List<Integer> ids) {
        List<DeviceTypeCol> deviceTypeCols = deviceTypeColMapper.selectByIds(ids);
        return deviceTypeCols;
    }

    /**
     * 清除缓存,保持缓存的统一性
     * @param deviceType
     * @param list
     */
    private void cleanRedisDeviceTypeCol(String deviceType, List<DeviceTypeCol> list){
        String redisKey = RedisKeyConstant.DEVICE_TYPE_COL + deviceType;
        if(redisService.hasKey(redisKey)){
            List<DeviceTypeCol> deviceTypeCols = (List<DeviceTypeCol>)redisService.get(redisKey);
            if(deviceTypeCols==null || deviceTypeCols.size()==0 || !list.equals(deviceTypeCols)){
                redisService.delete(redisKey);
                log.info("cleanRedisDeviceTypeCol,清除缓存{}",redisKey);
                redisService.set(redisKey,list);
                redisService.expire(redisKey,1, TimeUnit.HOURS);
                log.info("cleanRedisDeviceTypeCol,增加缓存数据");
            }
        }
    }

}
