package com.liquidnet.service.platform.controller.goblin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.liquidnet.common.exception.constant.ErrorCode;
import com.liquidnet.commons.lang.util.DESUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.entity.GoblinNftTransferOrder;
import com.liquidnet.service.platform.service.impl.goblin.PlatformGoblinNftTransferOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("artwork/task")
public class GoblinUserDigitalArtworkTaskController {
    @Autowired
    private PlatformGoblinNftTransferOrderService platformGoblinNftTransferOrderService;

    /**
     * 藏品转赠过期批处理
     *
     * @param expiredSeconds 过期时间，单位秒，不传默认24小时即86400秒（这里统一延后30秒处理）
     * @return ResponseDto<String>
     */
    @PostMapping("transfer_expire")
    public ResponseDto<String> processForTransferExpire(@RequestParam(required = false) String expiredSeconds) {
        int expiredSecondsIntVal = 86400 + 30;
        if (StringUtils.isNotBlank(expiredSeconds)) {
            try {
                String decrypt = DESUtils.DES().decrypt(expiredSeconds);
                expiredSecondsIntVal = Integer.parseInt(decrypt) + 30;
            } catch (NumberFormatException e) {
                expiredSecondsIntVal = 86400 + 30;
            } catch (Exception e) {
                ErrorCode paramError = ErrorCode.HTTP_PARAM_ERROR;
                return ResponseDto.failure(paramError.getCode(), paramError.getMessage());
            }
        }
        LocalDateTime expiredTime = LocalDateTime.now().minusSeconds(expiredSecondsIntVal);
        LambdaQueryWrapper<GoblinNftTransferOrder> queryWrapper = Wrappers.lambdaQuery(GoblinNftTransferOrder.class)
                .eq(GoblinNftTransferOrder::getState, 0)
                .le(GoblinNftTransferOrder::getCreatedAt, expiredTime);
        int totalCount = platformGoblinNftTransferOrderService.count(queryWrapper), pl = 0, remainCount = totalCount, pSize = 200;
        if (totalCount > 0) {
            log.info("藏品转赠过期初始查询总数:{} >>> BEGIN BEGIN BEGIN", totalCount);
        }

        queryWrapper.select(GoblinNftTransferOrder::getMid, GoblinNftTransferOrder::getArtworkId);
        queryWrapper.orderByAsc(GoblinNftTransferOrder::getMid);
        while (remainCount > 0) {
            String lastLimitSql = "LIMIT " + 0 + "," + pSize;
            List<GoblinNftTransferOrder> list = platformGoblinNftTransferOrderService.list(queryWrapper.last(lastLimitSql));

            if (!CollectionUtils.isEmpty(list)) {
                int numSucc = platformGoblinNftTransferOrderService.processForTransferExpire(list);

                log.info("藏品转赠过期处理[单次处理:{},list.size:{},list.numSucc:{}]", lastLimitSql, list.size(), numSucc);
                if (numSucc == 0) {
                    return ResponseDto.failure(String.format("藏品转赠过期处理警告：Mysql与Redis数据不一致，请核实[expiredTime=%s]", expiredTime));
                }

                pl += numSucc;
                queryWrapper.clear();
                expiredTime = LocalDateTime.now().minusSeconds(expiredSecondsIntVal);
                queryWrapper.eq(GoblinNftTransferOrder::getState, 0).le(GoblinNftTransferOrder::getCreatedAt, expiredTime);
                queryWrapper.select(GoblinNftTransferOrder::getMid, GoblinNftTransferOrder::getArtworkId);
                queryWrapper.orderByAsc(GoblinNftTransferOrder::getMid);
            } else {
                remainCount = -1;
            }
        }

        if (totalCount > 0) {
            log.info("藏品转赠过期初始查询总数:{},最终成功处理总数:{} >>> END END END", totalCount, pl);
        }
        return ResponseDto.success(String.format("藏品转赠过期初始查询总数:%s,最终成功处理总数:%s", totalCount, pl));
    }
}
