package com.tax.file.service.async.token;

import com.tax.file.model.FileToken;
import com.tax.file.model.TkTaxUser;
import com.tax.file.model.TkTaxUserExample;
import com.tax.file.model.token.TokenInfoModel;
import com.tax.file.service.api.FileTokenService;
import com.tax.file.service.api.TkTaxUserService;
import com.yxcheng.token.common.cache.RedisService;
import com.yxcheng.token.utils.DateUtils;
import com.yxcheng.token.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;

@Component
public class TokenCheckService {

    private static final Logger logger = LoggerFactory.getLogger(TokenCheckService.class);

    @Autowired
    protected TkTaxUserService tkTaxUserService;
    @Autowired
    protected FileTokenService fileTokenService;
    @Autowired
    private RedisService redisService;

    @Async("tokenExecutor")
    public Future<String> doTokenCheck(String uuidFlag, CountDownLatch latch, FileToken fileToken) {
        String taxno = fileToken.getTaxno();
        try {

            TkTaxUserExample taxUserExample = new TkTaxUserExample();
            taxUserExample.createCriteria().andTaxnoEqualTo(taxno).andUserNameEqualTo(fileToken.getUserName());
            TkTaxUser taxUser = tkTaxUserService.getOne(taxUserExample);

            int errorNum = 0;
            if (checkTokenNum(taxno)) {
                errorNum = getTokenNum(taxno);
            }
            String oldToken = "";
            if(StringUtil.isNotEmpty(fileToken.getToken())) {
                oldToken = fileToken.getToken();
            }
            if (errorNum < 60) {
                TokenInfoModel tokenModel = fileTokenService.getTokenCodeByUrl(taxUser);
                String retCode = tokenModel.getToken();
                if (StringUtil.isNotEmpty(retCode) && !retCode.equals(oldToken)) {
                    fileToken.setTokenStatus(FileToken.TOKEN_STATUS_ON);
                    fileToken.setToken(retCode);
                    fileTokenService.updateToken(fileToken);
                    logger.info(uuidFlag + " doTokenCheck " + taxno + " save is success!" + retCode);
                } else {
                    if(tokenModel.isStop(taxUser.getUserName())) {
                        tkTaxUserService.updateTaxUser(taxUser);
                        logger.info(uuidFlag + " doTokenCheck " + taxno + " is stop! " + tokenModel);
                    } else {
                        setTokenNum(taxno);
                        logger.info(uuidFlag + " doTokenCheck " + taxno + " errorNum is " + errorNum);
                    }
                }
            } else {
                if(null!=taxUser.getKeyType() && taxUser.getKeyType().equals("0")) {
                    tkTaxUserService.updateTaxUser(taxUser);
                    logger.info(uuidFlag + " doTokenCheck " + taxno + " is timeout!taxnoType" + taxUser.getKeyType());
                } else {
                    if(null!=fileToken.getUpdateDate() && DateUtils.getDaySub(fileToken.getUpdateDate(), DateUtils.getDate()) > 2) {
                        tkTaxUserService.updateTaxUser(taxUser);
                        logger.info(uuidFlag + " doTokenCheck " + taxno + " is timeout!");
                    } else {
                        logger.info(uuidFlag + " doTokenCheck " + taxno + " run temp stop!");
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.info(uuidFlag + " doTokenCheck " + taxno + " error is " + e.getMessage());
        }finally {
            latch.countDown();
        }
        return new AsyncResult<>("TokenCheckService taxno="+taxno+" accomplished!");
    }

    public boolean checkTokenNum(String taxno) {
        return redisService.exists("token:num:" + taxno);
    }

    public int getTokenNum(String taxno) {
        return Integer.parseInt(redisService.get("token:num:" + taxno));
    }

    public void setTokenNum(String taxno) {
        redisService.incr("token:num:" + taxno, 5 * 60);
    }
}
