package cn.gintone.service;

import cn.gintone.ErrorInfo;
import cn.gintone.config.IotDbConfig;
import cn.gintone.controller.vo.DeviceConnetRuleInfoPageReqVO;
import cn.gintone.controller.vo.DeviceConnetRuleInfoRespVO;
import cn.gintone.controller.vo.DeviceConnetRuleInfoSaveReqVO;
import cn.gintone.controller.vo.VisitInfoSaveReqVO;
import cn.gintone.dal.DeviceConnetRuleInfoMapper;
import cn.gintone.dal.DeviceTypeMapper;
import cn.gintone.dal.PtDeptInfoMapper;
import cn.gintone.dto.*;
import cn.gintone.entity.DeviceConnetRuleInfoDO;
import cn.gintone.entity.DeviceTypeDO;
import cn.gintone.entity.VisitInfoDO;
import cn.gintone.iotdbUtils.MyIotDbUtils;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.xml.crypto.Data;

import org.springframework.validation.annotation.Validated;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 设备规则配置细则 Service 实现类
 *
 * @author 胡懿
 */
@Service
@Validated
public class DeviceConnetRuleInfoServiceImpl implements DeviceConnetRuleInfoService {

    @Resource
    private DeviceConnetRuleInfoMapper connetRuleInfoMapper;
    @Autowired
    private IotDbConfig iotDbConfig;

    @Autowired
    private DeviceTypeMapper deviceTypeMapper;

    @Override
    public Long createConnetRuleInfo(DeviceConnetRuleInfoSaveReqVO createReqVO) {
        // 插入
        DeviceConnetRuleInfoDO connetRuleInfo = BeanUtils.toBean(createReqVO, DeviceConnetRuleInfoDO.class);
        connetRuleInfoMapper.insert(connetRuleInfo);
        // 返回
        return connetRuleInfo.getId();
    }

    @Override
    public void updateConnetRuleInfo(DeviceConnetRuleInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateConnetRuleInfoExists(updateReqVO.getId());
        // 更新
        DeviceConnetRuleInfoDO updateObj = BeanUtils.toBean(updateReqVO, DeviceConnetRuleInfoDO.class);
        connetRuleInfoMapper.updateById(updateObj);
    }

    @Override
    public void deleteConnetRuleInfo(Long id) {
        // 校验存在
        validateConnetRuleInfoExists(id);
        // 删除
        connetRuleInfoMapper.deleteById(id);
    }

    private void validateConnetRuleInfoExists(Long id) {
        if (connetRuleInfoMapper.selectById(id) == null) {
            throw exception(ErrorInfo.CONNET_RULE_INFO_NOT_EXISTS);
        }
    }

    @Override
    public DeviceConnetRuleInfoDO getConnetRuleInfo(Long id) {
        return connetRuleInfoMapper.selectById(id);
    }

    @Override
    public PageResult<DeviceConnetRuleInfoDO> getConnetRuleInfoPage(DeviceConnetRuleInfoPageReqVO pageReqVO) {
        return connetRuleInfoMapper.selectPage(pageReqVO);
    }

    @Override
    public List<DeviceType> getDeviceType() {
        List<DeviceType> deviceTypeList = new ArrayList<>();
        long id1 = 111111l;
        long id2 = 2222222l;
        for (int i = 0; i < 10; i++) {
            DeviceType deviceType = new DeviceType();
            deviceType.setId(id1);
            deviceType.setName("设备类型" + id1);

            List<DeviceInfo> deviceInfoList = new ArrayList<>();
            for (int j = 0; j < 10; j ++) {
                DeviceInfo deviceInfo = new DeviceInfo();
                deviceInfo.setId(id2++);
                deviceInfo.setName("设备" + id2 + j);
                deviceInfo.setIp("192.168." + id2 + "." + j);
                deviceInfo.setMac("192.168.19" + id2 + "." + j);
                deviceInfo.setPort("2093_" + id2);
                deviceInfo.setParentId(id1);
                deviceInfoList.add(deviceInfo);
            }
            id1 ++;
            deviceType.setDeviceInfoList(deviceInfoList);
            deviceTypeList.add(deviceType);
        }


        return deviceTypeList;
    }

    @Override
    public Boolean saveAll(List<DeviceConnetRuleInfoRespVO> deviceConnetRuleInfoRespVOList) {
        if (deviceConnetRuleInfoRespVOList != null && !deviceConnetRuleInfoRespVOList.isEmpty()) {
            List<DeviceConnetRuleInfoDO> deviceConnetRuleInfoDOS = new ArrayList<>();
            for (DeviceConnetRuleInfoRespVO deviceConnetRuleInfoRespVO : deviceConnetRuleInfoRespVOList) {
                DeviceConnetRuleInfoDO deviceConnetRuleInfoDO = BeanUtils.toBean(deviceConnetRuleInfoRespVO, DeviceConnetRuleInfoDO.class);
                deviceConnetRuleInfoDOS.add(deviceConnetRuleInfoDO);
            }
            return connetRuleInfoMapper.insertBatch(deviceConnetRuleInfoDOS);
        }

        return false;
    }

    @Override
    public void deleteByRuleId(Long ruleId) {
        connetRuleInfoMapper.delete(new QueryWrapper<DeviceConnetRuleInfoDO>().lambda().eq(DeviceConnetRuleInfoDO::getDeviceRuleId, ruleId));
    }

    @Override
    public Boolean updateAll(List<DeviceConnetRuleInfoRespVO> deviceConnetRuleInfoRespVOList) {
        if (deviceConnetRuleInfoRespVOList != null && !deviceConnetRuleInfoRespVOList.isEmpty()) {
            List<DeviceConnetRuleInfoDO> deviceConnetRuleInfoDOS = new ArrayList<>();
            connetRuleInfoMapper.delete(new QueryWrapper<DeviceConnetRuleInfoDO>().lambda().eq(DeviceConnetRuleInfoDO::getDeviceRuleId, deviceConnetRuleInfoRespVOList.get(0).getDeviceRuleId()));
            for (DeviceConnetRuleInfoRespVO deviceConnetRuleInfoRespVO : deviceConnetRuleInfoRespVOList) {
                DeviceConnetRuleInfoDO deviceConnetRuleInfoDO = BeanUtils.toBean(deviceConnetRuleInfoRespVO, DeviceConnetRuleInfoDO.class);
                deviceConnetRuleInfoDOS.add(deviceConnetRuleInfoDO);
            }
            return connetRuleInfoMapper.insertBatch(deviceConnetRuleInfoDOS);
        }
        return false;
    }

    @Override
    public void checkDeviceLogInfo(DeviceLogInfo deviceLogInfo) {
        if (null == deviceLogInfo.getDeviceTypeBs()) {
            return;
        }

        DeviceTypeDO deviceTypeDO = deviceTypeMapper.selectOne(new QueryWrapper<DeviceTypeDO>().lambda()
                .eq(DeviceTypeDO::getModelCode, deviceLogInfo.getDeviceTypeBs())
        );

        String userId = deviceLogInfo.getUserId();
        if (null == userId || "".equals(userId)) {
            DeviceIllLogInfo deviceIllLogInfo = new DeviceIllLogInfo();
            deviceIllLogInfo.setRoleId(deviceLogInfo.getRoleId());
            deviceIllLogInfo.setRoleName(deviceLogInfo.getRoleName());
            deviceIllLogInfo.setUserId(deviceLogInfo.getUserId());
            deviceIllLogInfo.setUsername(deviceLogInfo.getUsername());
            deviceIllLogInfo.setDeviceId(deviceLogInfo.getDeviceId());
            deviceIllLogInfo.setDeviceName(deviceLogInfo.getDeviceName());
            deviceIllLogInfo.setDeviceTypeId(deviceTypeDO.getId() + "");
            deviceIllLogInfo.setDeviceTypeBs(deviceLogInfo.getDeviceTypeBs());
            deviceIllLogInfo.setDeviceTypeName(deviceLogInfo.getDeviceTypeName());


            deviceIllLogInfo.setAccessed(deviceLogInfo.getAccessed());
            deviceIllLogInfo.setClientIp(deviceLogInfo.getClientIp());
            deviceIllLogInfo.setRemark(deviceLogInfo.getRemark());
            deviceIllLogInfo.setIllType("noRule");
            MyIotDbUtils.inserOneDeviceLogInfo_ill(iotDbConfig, deviceIllLogInfo);
            return;
        }
        // 查询用户规则，如果配置了用户规则，则按照用户规则走
        List<DeviceConnetRuleInfoDO> deviceConnetRuleInfoDOList = connetRuleInfoMapper.selectList(new LambdaQueryWrapper<DeviceConnetRuleInfoDO>()
                .like(DeviceConnetRuleInfoDO::getUserId, deviceLogInfo.getUserId())
        );

        boolean isLegal = false;

        if (null != deviceConnetRuleInfoDOList && deviceConnetRuleInfoDOList.size() > 0) {
            if (null != deviceLogInfo && null != deviceLogInfo.getDeviceId()) { // 判断设备
                List<DeviceConnetRuleInfoDO> deviceConnetRuleInfoDOS = connetRuleInfoMapper.selectList(new LambdaQueryWrapper<DeviceConnetRuleInfoDO>()
                        .eq(DeviceConnetRuleInfoDO::getUserId, userId)
                        .like(DeviceConnetRuleInfoDO::getDeviceTypeBs, deviceLogInfo.getDeviceTypeBs())
                        .like(DeviceConnetRuleInfoDO::getDeviceSn, deviceLogInfo.getDeviceSn())
                );
                if (null != deviceConnetRuleInfoDOS && deviceConnetRuleInfoDOS.size() > 0) {
                    isLegal = true;
                }
            } else { // 判断设备类型
                List<DeviceConnetRuleInfoDO> deviceConnetRuleInfoDOS = connetRuleInfoMapper.selectList(new LambdaQueryWrapper<DeviceConnetRuleInfoDO>()
                        .eq(DeviceConnetRuleInfoDO::getUserId, userId)
                        .like(DeviceConnetRuleInfoDO::getDeviceTypeBs, deviceLogInfo.getDeviceTypeBs())
                );
                if (null != deviceConnetRuleInfoDOS && deviceConnetRuleInfoDOS.size() > 0) {
                    isLegal = true;
                }
            }
        }




        if (!isLegal) {
            DeviceIllLogInfo deviceIllLogInfo = new DeviceIllLogInfo();
            deviceIllLogInfo.setRoleId(deviceLogInfo.getRoleId());
            deviceIllLogInfo.setRoleName(deviceLogInfo.getRoleName());
            deviceIllLogInfo.setUserId(deviceLogInfo.getUserId());
            deviceIllLogInfo.setUsername(deviceLogInfo.getUsername());
            deviceIllLogInfo.setDeviceId(deviceLogInfo.getDeviceId());
            deviceIllLogInfo.setDeviceName(deviceLogInfo.getDeviceName());
            deviceIllLogInfo.setDeviceTypeId(deviceTypeDO.getId() + "");
            deviceIllLogInfo.setDeviceTypeBs(deviceLogInfo.getDeviceTypeBs());
            deviceIllLogInfo.setDeviceTypeName(deviceLogInfo.getDeviceTypeName());
            deviceIllLogInfo.setAccessed(deviceLogInfo.getAccessed());
            deviceIllLogInfo.setIllType(deviceLogInfo.getType());
            deviceIllLogInfo.setClientIp(deviceLogInfo.getClientIp());
            deviceIllLogInfo.setRemark(deviceLogInfo.getRemark());
            deviceIllLogInfo.setIllType("noRule");
            MyIotDbUtils.inserOneDeviceLogInfo_ill(iotDbConfig, deviceIllLogInfo);
        }
    }

    @Override
    public List<DeviceConnetRuleInfoDO> getList(DeviceConnetRuleInfoPageReqVO pageReqVO) {
        return connetRuleInfoMapper.selectList(pageReqVO);
    }

}