package com.xy.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yitter.idgen.YitIdHelper;
import com.xy.collections.map.JHashMap;
import com.xy.dto.DeviceVersionUpDto;
import com.xy.entity.DeviceVersionUp;
import com.xy.mapper.DeviceVersionUpMapper;
import com.xy.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static com.xy.utils.PlusBeans.toIPage;
import static com.xy.utils.PlusBeans.toPageBean;


/**
 * <p>
 * 设备版本升级记录表 服务实现类
 * </p>
 *
 * @author lijin
 * @since 2023-06-09
 */
@Service
@RequiredArgsConstructor
@Api(tags = "设备版本升级记录表")
public class DeviceVersionUpServiceImpl extends ServiceImpl<DeviceVersionUpMapper, DeviceVersionUp> implements DeviceVersionUpService {

    private final RedisService<UpInfo> redisService;

    public static String upInfoKey = "device:version:up:%s";

    @PostMapping("page")
    @ApiOperation("分页查询")
    public R<PageBean<DeviceVersionUpDto.Vo>> page(@RequestBody DeviceVersionUpDto.Page page) {
        PageBean pageBean = page.getPage();
        LambdaQueryWrapper<DeviceVersionUp> lambdaQueryWrapper = new MybatisPlusQuery()
                .eqWrapper(page, DeviceVersionUp.class)
                .build()
                .orderByDesc(DeviceVersionUp::getCreateTime);
        IPage<DeviceVersionUp> iPage = page(toIPage(pageBean), lambdaQueryWrapper);
        return R.ok(toPageBean(DeviceVersionUpDto.Vo.class, iPage));
    }

    @ApiOperation("添加/修改")
    @PostMapping("saveOrUpdate")
    public R saveOrUpdate(@RequestBody @Validated DeviceVersionUpDto.SaveOrUpdate saveOrUpdate) {
        LambdaQueryWrapper<DeviceVersionUp> lambdaQueryWrapper = new LambdaQueryWrapper<DeviceVersionUp>()
                .eq(DeviceVersionUp::getDeviceId, saveOrUpdate.getDeviceId())
                .eq(DeviceVersionUp::getDeviceVersion, saveOrUpdate.getDeviceVersion());
        DeviceVersionUp deviceVersionUp = getOne(lambdaQueryWrapper);
        LocalDateTime now = LocalDateTime.now();
        if (deviceVersionUp == null) {
            deviceVersionUp = Beans.copy(DeviceVersionUp.class, saveOrUpdate)
                    .setId(YitIdHelper.nextId())
                    .setCreateTime(now)
                    .setUpdateTime(now);
        } else {
            saveOrUpdate.setId(deviceVersionUp.getId());
            deviceVersionUp = Beans.copy(deviceVersionUp, saveOrUpdate).setUpdateTime(now);
            if (Emptys.check(saveOrUpdate.getAccumSendNum())) {
                deviceVersionUp.setSendNum(deviceVersionUp.getSendNum() + saveOrUpdate.getAccumSendNum());
            }
        }
        saveOrUpdate(deviceVersionUp);
        return R.ok();
    }

    @PostMapping("saveUpdateUpInfoTask")
    @ApiOperation("添加修改版本升级任务")
    public R saveUpdateUpInfoTask(@RequestBody @Validated UpInfo upInfo) {
        redisService.set(String.format(upInfoKey, upInfo.getAppKey()), upInfo);
        return R.ok();
    }

    @PostMapping("queryUpInfoTask")
    @ApiOperation("查询版本升级任务")
    public R<List<UpInfo>> queryUpInfoTask() {
        Map<String, UpInfo> like = redisService.like("device:version:up");
        if (!Emptys.check(like)) {
            return R.ok();
        }
        return R.ok(new JHashMap<>(like).getValues());
    }

    @PostMapping("delUpInfoTask")
    @ApiOperation("清除版本升级任务")
    public R delUpInfoTask(@RequestBody @Validated UpInfoAppKey upInfoAppKey) {
        redisService.remove(String.format(upInfoKey, upInfoAppKey.getAppKey()));
        return R.ok();
    }

    @Data
    @Accessors(chain = true)
    public static class UpInfo {

        @NotBlank(message = "version不能为空")
        @ApiModelProperty(value = "版本号", required = true)
        private String version;

        @NotBlank(message = "appId不能为空")
        @ApiModelProperty(value = "appId", required = true)
        private String appId;

        @NotBlank(message = "appKey不能为空")
        @ApiModelProperty(value = "appKey", required = true)
        private String appKey;

        @NotBlank(message = "src不能为空")
        @ApiModelProperty(value = "升级地址", required = true)
        private String src;

        @ApiModelProperty(value = "是否开启 默认=true")
        private Boolean enable = true;
    }

    @Data
    @Accessors(chain = true)
    public static class UpInfoAppKey {

        @NotBlank(message = "appKey不能为空")
        @ApiModelProperty(value = "appKey", required = true)
        private String appKey;
    }
}