package com.fjhx.iot.service.tda.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.iot.constants.RedisConstant;
import com.fjhx.iot.entity.tda.dto.EbcDto;
import com.fjhx.iot.entity.tda.dto.TdaDeviceDto;
import com.fjhx.iot.entity.tda.dto.TdaDeviceSelectDto;
import com.fjhx.iot.entity.tda.po.TdaApplication;
import com.fjhx.iot.entity.tda.po.TdaDevice;
import com.fjhx.iot.entity.tda.po.TdaProduct;
import com.fjhx.iot.entity.tda.vo.TdaDeviceVo;
import com.fjhx.iot.mapper.tda.TdaDeviceMapper;
import com.fjhx.iot.service.tda.TdaApplicationService;
import com.fjhx.iot.service.tda.TdaDeviceService;
import com.fjhx.iot.service.tda.TdaProductService;
import com.fjhx.iot.utils.IoTDAUtil;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.common.utils.wrapper.SqlField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * <p>
 * 设备管理 服务实现类
 * </p>
 *
 * @author zlj
 * @since 2023-03-21
 */
@Service
public class TdaDeviceServiceImpl extends ServiceImpl<TdaDeviceMapper, TdaDevice> implements TdaDeviceService {

    @Lazy
    @Autowired
    private TdaProductService tdaProductService;

    @Lazy
    @Autowired
    private TdaApplicationService tdaApplicationService;

    @Autowired
    private RedisCache redisCache;

    @Override
    public Page<TdaDeviceVo> getPage(TdaDeviceSelectDto dto) {
        IWrapper<TdaDevice> wrapper = getWrapper();
        wrapper.orderByDesc("td", TdaDevice::getId);
        wrapper.keyword(dto, new SqlField("td.device_name"));
        Page<TdaDeviceVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);

        List<TdaDeviceVo> records = page.getRecords();

        if (records.size() == 0) {
            return page;
        }

        for (TdaDeviceVo record : records) {

            HashMap<String, Object> other = new HashMap<>();
            record.setOther(other);

            // 设备id
            String deviceId = record.getDeviceId();

            // 产品设备类型
            String deviceType = record.getDeviceType();

            if (StrUtil.isBlank(deviceId)) {
                continue;
            }

            Object obj = redisCache.getCacheObject(RedisConstant.DEVICE_PREFIX + deviceId);
            if (obj == null) {
                continue;
            }

            switch (deviceType) {
                case "ebc":
                    EbcDto ebcDto = (EbcDto) obj;
                    EbcDto.Status status = ebcDto.getStatus();
                    String sysSta = status.getSys_sta();
                    record.setStatus(sysSta);
                    record.setEventTime(ebcDto.getEventTime());

                    other.put("ebc", "1");
                    other.put("jiaka", status.getJiaka());
                    other.put("hengyi", status.getHengyi());
                    break;
            }

        }


        return page;
    }

    @Override
    public TdaDeviceVo detail(Long id) {
        TdaDevice TdaDevice = this.getById(id);
        TdaDeviceVo result = BeanUtil.toBean(TdaDevice, TdaDeviceVo.class);
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(TdaDeviceDto tdaDeviceDto) {
        String nodeId = tdaDeviceDto.getNodeId();
        String deviceName = tdaDeviceDto.getDeviceName();
        Long tdaProductId = tdaDeviceDto.getTdaProductId();

        // 查询资源所在空间和产品id
        TdaProduct tdaProduct = tdaProductService.getById(tdaProductId);
        String productId = tdaProduct.getProductId();

        TdaApplication tdaApplication = tdaApplicationService.getById(tdaProduct.getTdaApplicationId());

        // 华为ioDta添加设备
        IoTDAUtil.DeviceKey deviceKey = IoTDAUtil.addDevice(tdaApplication.getTdaConfigId(),
                nodeId, deviceName, tdaProduct.getAppId(), productId, tdaDeviceDto.getSecret());

        tdaDeviceDto.setProductId(productId);
        tdaDeviceDto.setDeviceId(tdaDeviceDto.getNodeId());

        // tdaDeviceDto.setSecret(deviceKey.getSecret());

        this.save(tdaDeviceDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(Long id) {

        TdaDevice tdaDevice = getById(id);
        TdaProduct tdaProduct = tdaProductService.getById(tdaDevice.getTdaProductId());
        TdaApplication tdaApplication = tdaApplicationService.getById(tdaProduct.getTdaApplicationId());

        IoTDAUtil.deleteDevice(tdaApplication.getTdaConfigId(), tdaDevice.getDeviceId());

        this.removeById(id);
    }

    @Override
    public List<JSONObject> getComputerList(TdaDeviceSelectDto dto) {
        Set<String> computerKeys = redisCache.scan(RedisConstant.DEVICE_COMPUTER_PREFIX + "*");

        List<JSONObject> computerList = computerKeys.stream().map(item -> (JSONObject) redisCache.getCacheObject(item))
                .filter(Objects::nonNull).collect(Collectors.toList());

        return computerList;
    }

}
