package cn.sikey.hmd.service.activation;

import cn.sikey.framework.common.exception.ServiceException;
import cn.sikey.framework.common.pojo.CommonResult;
import cn.sikey.hmd.api.hmd.dto.activation.DeviceActivationDTO;
import cn.sikey.hmd.api.hmd.vo.plans.PlansRespVO;
import cn.sikey.hmd.api.hmd.vo.qr.RemainingExpireTimeRespVO;
import cn.sikey.hmd.convert.DeviceActivationConvert;
import cn.sikey.hmd.dal.dataobject.DeviceActivationDO;
import cn.sikey.hmd.dal.mysql.DeviceActivationMapper;
import cn.sikey.hmd.enums.ValidityEnum;
import cn.sikey.hmd.service.plans.PlansService;
import cn.sikey.hmd.util.DateToolUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;

/**
 * @Author: qin
 * @Date: 2025/3/31
 * @Description: 设备激活
 */
@Service
@Slf4j
public class DeviceActivationServiceImpl implements DeviceActivationService {

    @Resource
    private DeviceActivationMapper deviceActivationMapper;

    @Resource
    private PlansService plansService;

    /**
     * 更新设备激活
     *
     * @param deviceId        设备编码
     * @param freeExpireTime  普通用户到期时间
     * @param finalExpireTime 最终到期时间
     * @param now             现在时间
     * @param plansValidity   套餐
     * @return
     */
    @Override
    public void updateDeviceActivation(String deviceId, LocalDateTime freeExpireTime,
                                       LocalDateTime finalExpireTime,
                                       LocalDateTime now, int plansValidity) {
        PlansRespVO plansRespVO = plansService.queryPlans(plansValidity);
        if (Objects.isNull(plansRespVO)) {
            log.warn("[更新设备激活]不存在默认套餐");
            throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "不存在默认套餐");
        }
        Long addSeconds = Optional.ofNullable(plansRespVO.getValiditySecond()).orElse(0L);
        // 最终时间
        LocalDateTime fExpireTime = DateToolUtil.calculateFinalExpireTime(freeExpireTime, finalExpireTime, now, addSeconds);
        log.info("[更新设备激活]设备编码：{}，普通用户到期时间：{}，原最终到期时间：{}，当前时间：{}", deviceId, freeExpireTime, finalExpireTime, now);
        deviceActivationMapper.updateDeviceActivation(deviceId, fExpireTime, plansValidity);
        log.info("[更新设备激活]更新数据库成功，设备编码：{}，普通用户到期时间：{}，最终到期时间：{}", deviceId, freeExpireTime, fExpireTime);
    }

    /**
     * 查询到期时间
     *
     * @param deviceId 设备唯一标识
     * @param apiType  类型
     * @return
     */
    @Override
    public CommonResult<RemainingExpireTimeRespVO> queryExpireTime(String deviceId, String apiType) {
        DeviceActivationDO deviceActivationDO = deviceActivationMapper.queryDeviceActivation(deviceId);
        RemainingExpireTimeRespVO remainingTimesExpireTimeVO = new RemainingExpireTimeRespVO();
        long remainingDays;
        long remainingSeconds;
        LocalDateTime now = LocalDateTime.now();
        if (Objects.isNull(deviceActivationDO)) {
            // 激活设备
            PlansRespVO plansRespVO = plansService.queryPlans(ValidityEnum.ZERO.getValue());
            if (Objects.isNull(plansRespVO)) {
                log.warn("[查询到期时间]不存在默认套餐");
                throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "不存在默认套餐");
            }

            remainingSeconds = Optional.ofNullable(plansRespVO.getValiditySecond()).orElse(0L).intValue();
            remainingDays = (remainingSeconds / DateToolUtil.DAY_SECOND);

            saveDeviceActivation(deviceId, apiType, remainingSeconds);


            remainingTimesExpireTimeVO.setPlansValidity(plansRespVO.getValidity());
        } else {
            // 已激活设备
            DeviceActivationDTO deviceActivationDTO = DeviceActivationConvert.INSTANCE.convertDeviceActivationDTO(deviceActivationDO);

            LocalDateTime finalExpireTime = deviceActivationDTO.getFinalExpireTime();

            remainingDays = DateToolUtil.calculateRemainingDays(finalExpireTime, now);
            remainingTimesExpireTimeVO.setPlansValidity(deviceActivationDTO.getPlansValidity());

            remainingSeconds = DateToolUtil.calculateRemainingSeconds(finalExpireTime, now);
        }

        remainingTimesExpireTimeVO.setRemainingSeconds(remainingSeconds);
        remainingTimesExpireTimeVO.setDeviceId(deviceId);
        remainingTimesExpireTimeVO.setApiType(apiType);
        remainingTimesExpireTimeVO.setRemainingDays(remainingDays);


        log.info("[查询到期时间]返回结果：{}", remainingTimesExpireTimeVO);
        return CommonResult.success(remainingTimesExpireTimeVO);
    }

    @Override
    public DeviceActivationDTO queryDeviceActivation(String deviceId) {
        DeviceActivationDO deviceActivationDO = deviceActivationMapper.queryDeviceActivation(deviceId);
        return DeviceActivationConvert.INSTANCE.convertDeviceActivationDTO(deviceActivationDO);
    }

    /**
     * 保存设备激活
     *
     * @param deviceId        设备编码
     * @param apiType         类型
     * @param remainingSecond 剩余秒
     */
    private void saveDeviceActivation(String deviceId, String apiType, Long remainingSecond) {
        LocalDateTime now = LocalDateTime.now();
        DeviceActivationDO deviceActivationDO = new DeviceActivationDO();
        deviceActivationDO.setDeviceId(deviceId);
        deviceActivationDO.setApiType(apiType);
        // 激活时间
        deviceActivationDO.setActivationTime(now);
        // 普通用户到期时间
        deviceActivationDO.setFreeExpireTime(DateToolUtil.calculateFutureDate(remainingSecond, now));
        // 最终到期时间
        deviceActivationDO.setFinalExpireTime(DateToolUtil.calculateFutureDate(remainingSecond, now));
        deviceActivationDO.setCreator(deviceId);
        deviceActivationDO.setCreateTime(now);
        deviceActivationDO.setUpdater(deviceId);
        deviceActivationDO.setUpdateTime(now);
        deviceActivationMapper.insert(deviceActivationDO);
    }

}
