package com.sikey.wa04.business.infrastructure.adapter.dao;

import com.sikey.wa04.business.domain.adapter.ChildQueryAdapter;
import com.sikey.wa04.business.domain.adapter.DeviceConfigAdapter;
import com.sikey.wa04.business.domain.adapter.MessageCenterAdapter;
import com.sikey.wa04.business.domain.dto.DeviceConfigReqVO;
import com.sikey.wa04.business.domain.entity.MessageCenter;
import com.sikey.wa04.business.infrastructure.dto.model.ChildModel;
import com.sikey.wa04.business.infrastructure.dto.model.DeviceBindModel;
import com.sikey.wa04.business.infrastructure.dto.model.DeviceConfigModel;
import com.sikey.wa04.business.infrastructure.repository.ChildRepository;
import com.sikey.wa04.business.infrastructure.repository.DeviceBindRepository;
import com.sikey.wa04.business.infrastructure.repository.DeviceConfigRepository;
import com.sikey.wa04.common.dto.header.GenericManufacturerHeader;
import com.sikey.wa04.common.enums.MessageCenterType;
import com.sikey.wa04.common.enums.SignalStepBatteryStepEnum;
import com.sikey.wa04.common.exception.BusinessException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.Instant;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * @Author: nelson
 * @Date: 2025/5/27
 * @Description: 设备配置 消息中心
 */
@Slf4j
@Component
public class DeviceConfigAdapterImpl implements DeviceConfigAdapter {

    @Resource
    private DeviceBindRepository deviceBindRepository;

    @Resource
    private DeviceConfigRepository deviceConfigRepository;

    @Resource
    private ChildRepository childRepository;

    @Resource
    private MessageCenterAdapter messageCenterAdapter;

    @Qualifier("myTaskExecutor")
    @Autowired
    private ThreadPoolTaskExecutor myTaskExecutor;

    @Resource
    private ChildQueryAdapter childQueryAdapter;

    /**
     * 设备配置 消息中心
     *
     * @param cId                       儿童编码
     * @param genericManufacturerHeader header数据
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void deviceConfigMessageCenter(String cId, GenericManufacturerHeader genericManufacturerHeader) {
        Optional<ChildModel> childModel = childRepository.findById(cId);
        if (childModel.isEmpty()) {
            throw new BusinessException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "不存在儿童");
        }
        ChildModel cm = childModel.get();

        DeviceBindModel deviceBindModel = deviceBindRepository.findByChildId(cId);
        if (Objects.isNull(deviceBindModel)) {
            throw new BusinessException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "不存在设备绑定");
        }

        Long deviceId = deviceBindModel.getDeviceId();
        String childName = cm.getChildName();

        // 设备配置
        String battery = genericManufacturerHeader.getBattery();
        String signal = genericManufacturerHeader.getSignal();
        String maxSignal = genericManufacturerHeader.getMaxSignal();
        String step = genericManufacturerHeader.getStep();

        // 设备配置-电量
        DeviceConfigReqVO dc = new DeviceConfigReqVO();
        dc.setCId(cId);
        dc.setKey(SignalStepBatteryStepEnum.BATTERY.getDescription());
        dc.setValue(battery);
        dc.setBeforeValue(battery);
        dc.setBattery(true);
        deviceConfig(deviceId, dc, cId, childName);

        myTaskExecutor.execute(() -> {
            // 设备配置-信号
            DeviceConfigReqVO deviceConfigReqVO = new DeviceConfigReqVO();
            deviceConfigReqVO.setCId(cId);
            deviceConfigReqVO.setKey(SignalStepBatteryStepEnum.SIGNAL.getDescription());
            deviceConfigReqVO.setValue(signal);
            deviceConfigReqVO.setBeforeValue(signal);
            deviceConfig(deviceId, deviceConfigReqVO, cId, childName);

            // 设备配置-最大信号
            deviceConfigReqVO = new DeviceConfigReqVO();
            deviceConfigReqVO.setCId(cId);
            deviceConfigReqVO.setKey(SignalStepBatteryStepEnum.MAX_SIGNAL.getDescription());
            deviceConfigReqVO.setValue(maxSignal);
            deviceConfigReqVO.setBeforeValue(maxSignal);
            deviceConfig(deviceId, deviceConfigReqVO, cId, childName);

            // 设备配置-步数
            deviceConfigReqVO = new DeviceConfigReqVO();
            deviceConfigReqVO.setCId(cId);
            deviceConfigReqVO.setKey(SignalStepBatteryStepEnum.STEP.getDescription());
            deviceConfigReqVO.setValue(step);
            deviceConfigReqVO.setBeforeValue(step);
            deviceConfig(deviceId, deviceConfigReqVO, cId, childName);
        });

    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void deviceConfigStartupMessageCenter(String cId, int powerOnOrShutdown, GenericManufacturerHeader genericManufacturerHeader) {
        Optional<ChildModel> childModel = childRepository.findById(cId);
        if (childModel.isEmpty()) {
            throw new BusinessException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "不存在儿童");
        }
        ChildModel cm = childModel.get();

        DeviceBindModel deviceBindModel = deviceBindRepository.findByChildId(cId);
        if (Objects.isNull(deviceBindModel)) {
            throw new BusinessException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "不存在设备绑定");
        }

        Long deviceId = deviceBindModel.getDeviceId();
        String childName = cm.getChildName();

        String getPowerOnOrShutdown = String.valueOf(powerOnOrShutdown);

        // 设备配置-信号
        DeviceConfigReqVO deviceConfigReqVO = new DeviceConfigReqVO();
        deviceConfigReqVO.setCId(cId);
        deviceConfigReqVO.setKey(SignalStepBatteryStepEnum.STARTUP.getDescription());
        deviceConfigReqVO.setValue(getPowerOnOrShutdown);
        deviceConfigReqVO.setBeforeValue(getPowerOnOrShutdown);
        deviceConfig(deviceId, deviceConfigReqVO, cId, childName);
    }

    /**
     * 设备配置
     *
     * @param deviceId          设备编码
     * @param deviceConfigReqVO 设备配置
     * @param cId               儿童编码
     * @param childName         儿童名称
     * @return
     */
    private void deviceConfig(Long deviceId, DeviceConfigReqVO deviceConfigReqVO, String cId, String childName) {
        DeviceConfigModel deviceConfigModel = deviceConfigRepository.findByDeviceIdAndKey(deviceId, deviceConfigReqVO.getKey());
        if (Objects.isNull(deviceConfigModel)) {
            deviceConfigModel = new DeviceConfigModel();
            deviceConfigModel.setDeviceId(deviceId);
            deviceConfigModel.setKey(deviceConfigReqVO.getKey());
            deviceConfigModel.setValue(deviceConfigReqVO.getValue());
            deviceConfigModel.setBeforeValue(deviceConfigReqVO.getValue());
            deviceConfigRepository.save(deviceConfigModel);
        } else {
            String key = deviceConfigModel.getKey();
            String paramKey = deviceConfigReqVO.getKey();
            String paramValue = deviceConfigReqVO.getValue();
            if (StringUtils.isEmpty(key) || StringUtils.isEmpty(paramKey)) {
                throw new BusinessException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "不存在绑定设备key");
            }

            // 更新
            if (key.equals(paramKey)) {
                String lastBatteryValue = deviceConfigModel.getValue();
                DeviceConfigModel dcm = new DeviceConfigModel();
                dcm.setDeviceId(deviceId);
                dcm.setKey(key);
                dcm.setValue(paramValue);
                dcm.setBeforeValue(lastBatteryValue);
                dcm.setUpdatedAt(Instant.now());
                deviceConfigRepository.updateByDeviceIdAndKey(dcm.getDeviceId(), dcm.getKey(), dcm.getValue(), dcm.getBeforeValue(), dcm.getUpdatedAt());

                if (!deviceConfigReqVO.isBattery()) {
                    return;
                }
                // 低电量消息中心通知
                if (!StringUtils.isEmpty(lastBatteryValue) && !StringUtils.isEmpty(paramValue)) {
                    int lbValue = Integer.parseInt(lastBatteryValue);
                    int pValue = Integer.parseInt(paramValue);
                    if ((lbValue > 20 && pValue <= 20)  || (lbValue > 10 && pValue <= 10)){ // 上次电量大于20 并且 当前电量<=20 或者  上次电量大于10 并且 当前电量<=10
                        // 加入消息到消息中心
                        MessageCenter messageCenter = new MessageCenter();
                        messageCenter.setCid(cId);
                        messageCenter.setMessageType(MessageCenterType.MESSAGE_CENTER_TYPE_LOW_BATTERY_REMIND.getValue());
                        messageCenter.setMessageParams(Map.of("name", childName, "num", pValue));
                        messageCenterAdapter.save(messageCenter, MessageCenterType.MESSAGE_CENTER_TYPE_LOW_BATTERY_REMIND);
                    }
                }
            }
        }
    }


}
