package com.heyu.api.admin.http.api.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.constants.RedisConstans;
import com.heyu.api.data.dao.calca.CalcaFaceConfigDao;
import com.heyu.api.data.dto.AccountDTO;
import com.heyu.api.data.dto.CalcaAccountLogDTO;
import com.heyu.api.data.dto.RequestLogDTO;
import com.heyu.api.data.entity.calca.CalcaAccountEntity;
import com.heyu.api.data.entity.calca.CalcaAccountLogEntity;
import com.heyu.api.data.entity.calca.CalcaFaceConfigEntity;
import com.heyu.api.data.service.calca.CalcaAccountService;
import com.heyu.api.data.service.calca.CalcaFaceConfigService;
import com.heyu.api.data.utils.*;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;


@Component
@Slf4j
public class AccountQueueSimpleRabbitListener {

    @Autowired
    private CalcaFaceConfigService calcaFaceConfigService;

    @Autowired
    private CalcaAccountService calcaAccountService;

    @Autowired
    private RedisUtils redisUtils;


    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value("${eb.config.rabbitQueue.accountLogName}")
    private String accountLogNameQueue;


    @Autowired
    private CalcaFaceConfigDao calcaFaceConfigDao;


    @RabbitHandler
    @RabbitListener(queues = "#{accountAmountQueue.name}", containerFactory = "accountAmountQueueSimpleRabbitListenerContainerFactory")
    public void consumeMessage(@Payload String message, @Header(AmqpHeaders.DELIVERY_TAG) long delivertTag, Channel channel) {
        String userName = "";
        try {
            RequestLogDTO requestLogDTO = JSON.parseObject(message, RequestLogDTO.class);
            userName = requestLogDTO.getUserName();
            String newTraceId = requestLogDTO.getTraceId() + "_" + OrderUtil.getUserPoolOrder("xx");
            MDC.put(ApiConstants.TRACE_ID, newTraceId);
            log.info("accountAmountQueue接收到的的数据是:{}", JSON.toJSONString(requestLogDTO));
            Date currentTime = new Date();

            CalcaFaceConfigEntity calcaFaceConfigEntity = calcaFaceConfigDao.selectCalcaFaceConfigByFace(requestLogDTO.getFace());

            String accountRedisKey = ApiConstants.ACCOUNT_INFO + requestLogDTO.getUserName();
            CalcaAccountEntity calcaAccountEntity = calcaAccountService.selectCalcaAccountByUserName(requestLogDTO.getUserName());

            handleAmount(currentTime,
                    requestLogDTO.getToken(),
                    accountRedisKey,
                    calcaFaceConfigEntity.getEveryInvokeAmount(),
                    requestLogDTO.getUserName(),
                    calcaAccountEntity,
                    newTraceId, requestLogDTO);


        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**
     * @param currentTime
     * @param accountRedisKey
     * @param everyInvokeFaceAmount
     * @param userName
     * @param calcaAccountEntity
     * @return
     */
    public void handleAmount(Date currentTime, String token, String accountRedisKey, BigDecimal everyInvokeFaceAmount, String userName,
                             CalcaAccountEntity calcaAccountEntity, String newTraceId, RequestLogDTO requestLogDTO) {
        String lock = ApiConstants.UPDATE_ACCOUNT_AMOUNT_LOCK + userName;
        try {
            boolean flag = redisUtils.lockTryTimes(lock, RedisConstans.ONE_MINUTE, RedisConstans.ONE_MINUTE);
            if (flag) {
                // 减少everyInvokeFaceAmount的金额
                String accountRedisValue2 = redisUtils.get(accountRedisKey);
                if (StringUtils.isEmpty(accountRedisValue2)) {
                    log.info("accountRedisValue2 is null ");
                    return;
                }

                handle(calcaAccountEntity,
                        currentTime,
                        userName,
                        token,
                        newTraceId,
                        everyInvokeFaceAmount,
                        accountRedisValue2,
                        requestLogDTO);


            }
        } catch (Exception e) {
            log.error("handleAmount异常", e);
        }
    }

    public void handle(CalcaAccountEntity calcaAccountEntity, Date currentTime, String userName,
                       String token, String newTraceId, BigDecimal everyInvokeFaceAmount, String accountRedisValue,
                       RequestLogDTO requestLogDTO) {
        // redis 的有效期限为秒
        int betweenSecond = DateUtils.betweenSecond(currentTime, DateUtils.addDays(currentTime, 1));
        BigDecimal preAmount = calcaAccountEntity.getCurrentAmount();
        BigDecimal currentAmount = BigDecimalUtil.subtract(preAmount, everyInvokeFaceAmount);
        AccountDTO accountDTO = JSONObject.parseObject(accountRedisValue, AccountDTO.class);

        accountDTO.setAmount(currentAmount);
        String key = ApiConstants.ACCOUNT_INFO + userName;
        redisUtils.set(key, JSON.toJSONString(accountDTO), betweenSecond);
        log.info("设置账号金额成功key:{} value:{}", key, JSON.toJSONString(accountDTO));

        calcaAccountEntity.setCurrentAmount(currentAmount);

        CalcaAccountLogEntity calcaAccountLogEntity = new CalcaAccountLogEntity();

        calcaAccountLogEntity.setBeforeAmount(preAmount);
        calcaAccountLogEntity.setAfterAmount(currentAmount);
        calcaAccountLogEntity.setUserName(userName);
        calcaAccountLogEntity.setOptAmount(everyInvokeFaceAmount);
        calcaAccountLogEntity.setFace(requestLogDTO.getFace());
        calcaAccountLogEntity.setToken(requestLogDTO.getToken());
        calcaAccountLogEntity.setRole(ApiConstants.SYSTEM);

        calcaAccountLogEntity.setYyyyMm(DateUtils.formatDate(currentTime, DateUtils.yyyyMM));
        calcaAccountLogEntity.setYyyyMmDd(DateUtils.formatDate(currentTime, DateUtils.yyyyMMdd));
        calcaAccountLogEntity.setYyyyMmDdHh(DateUtils.formatDate(currentTime, DateUtils.yyyyMMddHH));
        calcaAccountLogEntity.setYyyyMmDdHhMm(DateUtils.formatDate(currentTime, DateUtils.yyyyMMddHHmm));


        CalcaAccountLogDTO calcaAccountLogDTO = new CalcaAccountLogDTO();
        calcaAccountLogDTO.setToken(token);
        calcaAccountLogDTO.setCalcaAccountLogEntity(calcaAccountLogEntity);
        calcaAccountLogDTO.setUserName(userName);
        calcaAccountLogDTO.setTraceId(newTraceId);
        calcaAccountLogDTO.setMsgSendTime(System.currentTimeMillis());
        String sendLog = JSON.toJSONString(calcaAccountLogDTO);
        log.info(" rabbitmq calcaAccountLogDTO 发送的数据 " + sendLog);
        rabbitTemplate.convertAndSend(accountLogNameQueue, sendLog);
        calcaAccountService.updateCalcaAccountById(calcaAccountEntity);
    }

}