package com.zt.plat.module.qms.iot.tcpserver.device;

import com.zt.plat.framework.tenant.core.context.TenantContextHolder;
import com.zt.plat.module.qms.iot.tcpserver.IotUtils;
import com.zt.plat.module.qms.iot.tcpserver.core.ChannelContextConstant;
import com.zt.plat.module.qms.iot.tcpserver.core.IotDeviceSessionForRedisContext;
import com.zt.plat.module.qms.iot.tcpserver.publisher.IotDeviceRegisterPublisher;
import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceInfomationDO;
import com.zt.plat.module.qms.resource.device.service.DeviceInfomationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import tech.zzjc.tio.core.ChannelContext;
import tech.zzjc.tio.core.Tio;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class RedisSessionComponent {

    @Autowired private RedisTemplate redisTemplate;
    @Autowired private DeviceInfomationService deviceInfomationService;
    private final long timeoutSeconds = 60;

    public void update(IotDeviceSessionForRedisContext context){
        String deviceId = IotUtils.transDeviceCodeToId(context.getDeviceCode());
        context.setRegTime(new Date());
        String key = getRedisKeyByDeviceId(deviceId);
//        log.info("key={}", key);
        redisTemplate.opsForValue().set(key, context, timeoutSeconds, TimeUnit.SECONDS);
    }

    public void clearControlByDeviceCode(String deviceCode, ChannelContext channelContext){
        IotDeviceSessionForRedisContext context = getByDeviceCode(deviceCode);
        context.setControlRealName("");
        context.setControlChannelContext(null);
        channelContext.set(ChannelContextConstant.CONTROL_DEVICE_ID, "");
        redisTemplate.opsForValue().set(getRedisKeyByDeviceCode(deviceCode), context, timeoutSeconds, TimeUnit.SECONDS);
    }

    public void clearControlByDeviceId(String deviceId, ChannelContext channelContext){
        IotDeviceSessionForRedisContext context = getByDeviceId(deviceId);
        context.setControlRealName("");
        context.setControlChannelContext(null);
        channelContext.set(ChannelContextConstant.CONTROL_DEVICE_ID, "");
        redisTemplate.opsForValue().set(getRedisKeyByDeviceId(deviceId), context, timeoutSeconds, TimeUnit.SECONDS);
    }

    public void deleteByDeviceId(String deviceId){
        redisTemplate.delete(getRedisKeyByDeviceCode(deviceId));
    }

    public IotDeviceSessionForRedisContext getByDeviceCode(String deviceCode){
        String deviceId = IotUtils.transDeviceCodeToId(deviceCode);
        return getByDeviceId(deviceId);
    }

    public IotDeviceSessionForRedisContext getByDeviceId(String deviceId){
        return (IotDeviceSessionForRedisContext) redisTemplate.opsForValue().get(getRedisKeyByDeviceId(deviceId));
    }

    public String getRedisKeyByDeviceCode(String deviceCode){
        String deviceId = IotUtils.transDeviceCodeToId(deviceCode);
        return getRedisKeyByDeviceId(deviceId);
    }
    public String getRedisKeyByDeviceId(String deviceId){
        String redisKey = IotDeviceSessionForRedisContext.DEFAULT_DEVICE_SESSION_CONTEXT_KEY + "-" + deviceId;
        return redisKey;
    }

    public void regDevice(ChannelContext channelContext, String deviceCode, String deviceType){
        IotDeviceSessionForRedisContext deviceContext = getByDeviceCode(deviceCode);
        if(deviceContext != null && Tio.getByBsId(channelContext.getTioConfig(), deviceCode) != null){
            return;
        }

        TenantContextHolder.setIgnore(true);
        try{
            String deviceId = IotUtils.transDeviceCodeToId(deviceCode);
            DeviceInfomationDO deviceInfo = deviceInfomationService.getDeviceInfomation(Long.valueOf(deviceId));
            IotDeviceSessionForRedisContext context = new IotDeviceSessionForRedisContext();
            context.setDeviceId(deviceId);
            context.setDeviceType(deviceType);
            context.setDeviceCode(deviceCode);
            if(deviceInfo != null){
                context.setDeviceName(deviceInfo.getProductName());
                context.setTenantId(deviceInfo.getTenantId().toString());
                deviceInfo.setIsConnect("1");
                deviceInfo.setLastConnectTime(LocalDateTime.now());
                deviceInfomationService.updateDeviceInfomation(deviceInfo);
            }
            context.setRegTime(new Date());
            context.setControlRealName( "");
            redisTemplate.opsForValue().set(getRedisKeyByDeviceId(deviceId), context, timeoutSeconds, TimeUnit.SECONDS);

            channelContext.set("regTime", new Date());
            //绑定业务id
            Tio.bindBsId(channelContext, deviceCode);
            //设备注册事件
            IotDeviceRegisterPublisher.publishEvent(deviceCode, deviceType);
        }catch (Exception e){
            e.printStackTrace();
            log.error("设备注册异常：{}", e.getMessage());
        }finally {
            TenantContextHolder.clear();
        }

    }


}
