package com.tzy.listener.mq;

import com.alibaba.fastjson2.JSON;
import com.rabbitmq.client.Channel;
import com.tzy.app.domain.order.PayRecord;
import com.tzy.common.constant.Constants;
import com.tzy.common.constant.MqConstans;
import com.tzy.common.utils.DateUtils;
import com.tzy.common.utils.StringUtils;
import com.tzy.framework.pay.dto.PaymentInfoResponseDto;
import com.tzy.framework.pay.service.PaymentService;
import com.tzy.framework.util.RedisUtils;
import com.tzy.member.benefits.mapper.MemberBenefitsRecordMapper;
import com.tzy.service.MallOrderService;
import com.tzy.sportcard.api.dto.ResourceData;
import com.tzy.sportcard.api.service.GroupApiService;
import com.tzy.sportcard.api.service.MineApiService;
import com.tzy.sportcard.group.domain.CardGroupOrderInfo;
import com.tzy.sportcard.group.service.ICardGroupOrderInfoService;
import com.tzy.sportcard.point.domain.AppUserPointRecord;
import com.tzy.system.service.ISysDictDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


@Slf4j
@Component
public class OrderExpiredConsumer {

    @Autowired
    private ICardGroupOrderInfoService cardGroupOrderInfoService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private MallOrderService mallOrderService;
    @Autowired
    private GroupApiService groupApiService;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private MineApiService mineApiService;
    @Resource
    private MemberBenefitsRecordMapper memberBenefitsRecordMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ISysDictDataService dictDataService;

    private static final List<String> no_search_pay_type = Arrays.asList("merchant_pay", "商家代收");

    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue(MqConstans.QUEUE_ORDER_EXPIRED))
    public void orderExpired(Long orderId, Channel channel, Message message) throws IOException {
        orderExpiredConsumer(orderId, channel, message);
    }

    private void orderExpiredConsumer(Long orderId, Channel channel, Message message) throws IOException {
        try {
            cancelOrder(orderId);
        } catch (Exception e) {
            log.info("订单取消异常id:{}", orderId, e);
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

    private void cancelOrder(Long orderId) {
        log.info("过期订单id:{}", orderId);
        CardGroupOrderInfo orderInfo = cardGroupOrderInfoService.selectUnPayOrderById(orderId);
        if (orderInfo == null) {
            log.info("过期订单不存在,id:{}", orderId);
            return;
        }

        if (StringUtils.isNotEmpty(orderInfo.getPointType()) && orderInfo.getPointType().startsWith(Constants.POINT_TYPE_MERCHANT_ACT_PRE)) {
            //积分兑换的订单
            AppUserPointRecord userPointRecord = mineApiService.selectRecordByOrderId(orderId.toString(), orderInfo.getPointType(), orderInfo.getUserId(), false);
            log.info("订单:{},拼豆支付查询结果:{}",orderInfo.getOrderNo(),userPointRecord);
            if (userPointRecord != null && Math.abs(userPointRecord.getChangePoint()) == orderInfo.getPoint()) {
                pointCallBack(orderInfo);
            } else {
                cancelOrderByType(orderInfo);
            }
            return;
        }

        String paymentType = orderInfo.getPaymentType();
        if (StringUtils.isEmpty(paymentType)) {
            cancelOrderByType(orderInfo);
            return;
        }
        if (redisUtils.hasKey(Constants.ORDER_CALLBACK_LOCK_KEY + orderInfo.getTradeNo())) {
            return;
        }
        if (no_search_pay_type.contains(orderInfo.getPaymentType())) {
            if (new Date().after(new Date(orderInfo.getCreateTime().getTime() + 1800000))) {
                cancelOrderByType(orderInfo);
            }
            return;
        }

        //查询订单信息
        List<PayRecord> unPayRecords = cardGroupOrderInfoService.findPayRecordByOrderId(orderInfo.getId());
        PaymentInfoResponseDto paymentInfoResponseDto = null;
        for (PayRecord record : unPayRecords) {
            PaymentInfoResponseDto result = paymentService.queryPaymentOrder(record.getPaymentSubType(), record.getTradeNo());
            if (result.isSuccess()) {
                paymentInfoResponseDto = result;
                break;
            }
        }
        if (paymentInfoResponseDto == null || !paymentInfoResponseDto.isSuccess()) {
            //更新组队的出售数量
            cancelOrderByType(orderInfo);
            if (!no_search_pay_type.contains(orderInfo.getPaymentType())) {
                paymentService.close(orderInfo.getPaymentSubType(), orderInfo.getTradeNo());
            }
            log.info("取消订单,no:{}", orderInfo.getOrderNo());
            return;
        }
        log.info("订单支付成功,开始回调:{}", orderInfo.getOrderNo());
        ResourceData resourceData = buildOrderPayData(paymentInfoResponseDto);
        if (Constants.ORDER_TYPE_DRAW.equals(orderInfo.getOrderType())) {
            rabbitTemplate.convertAndSend(MqConstans.QUEUE_DRAW_ORDER_CALLBACK, JSON.toJSONString(resourceData));
        } else {
            groupApiService.paymentResult(resourceData);
        }
    }

    private static ResourceData buildOrderPayData(PaymentInfoResponseDto paymentInfoResponseDto) {
        ResourceData resourceData = new ResourceData();
        resourceData.setOut_trade_no(paymentInfoResponseDto.getOrderNo());
        SimpleDateFormat sdf2 = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        if (paymentInfoResponseDto.getPaymentSuccessTime() != null) {
            resourceData.setSuccess_time(sdf2.format(paymentInfoResponseDto.getPaymentSuccessTime()));
        } else {
            resourceData.setSuccess_time(sdf2.format(new Date()));
        }
        resourceData.setTransaction_id(paymentInfoResponseDto.getPaymentNo());
        resourceData.setTrade_state(Constants.TRADE_SUCCESS_EN);
        resourceData.setTrade_type(paymentInfoResponseDto.getPayWay());
        resourceData.setTrade_state_desc(Constants.TRADE_SUCCESS);
        double total_amount = paymentInfoResponseDto.getPaymentPrice().doubleValue() * 100;
        double buyer_pay_amount = paymentInfoResponseDto.getActualPayment().doubleValue() * 100;
        resourceData.setAmount(new ResourceData.PayAmount((int) total_amount, (int) buyer_pay_amount, null, null));
        return resourceData;
    }

    private void pointCallBack(CardGroupOrderInfo orderInfo) {
        ResourceData resourceData = new ResourceData();
        ResourceData.PayAmount payAmount = new ResourceData.PayAmount();
        payAmount.setTotal(0);
        payAmount.setPayer_total(payAmount.getTotal());
        //支付类型
        resourceData.setTrade_type(dictDataService.getMerchantPointMsg(orderInfo.getPointType()));
        resourceData.setSubPaymentType(orderInfo.getPointType());
        resourceData.setOut_trade_no(orderInfo.getOrderNo());
        resourceData.setTransaction_id(String.valueOf(System.currentTimeMillis()));
        resourceData.setSuccess_time(DateUtils.dateTime(new Date()));
        resourceData.setTrade_state("TRADE_SUCCESS");
        resourceData.setTrade_state_desc("TRADE_SUCCESS");
        resourceData.setBank_type(orderInfo.getPointType());
        resourceData.setAmount(payAmount);
        rabbitTemplate.convertAndSend(MqConstans.EXCHANGE_PRE_PAY_CALLBACK, MqConstans.ROUTING_KEY_PRE_CALLBACK, JSON.toJSONString(resourceData));
        log.info("订单支付成功,开始回调:{}", orderInfo.getOrderNo());
    }

    private void cancelOrderByType(CardGroupOrderInfo orderInfo) {
        if (Constants.ORDER_TYPE_SHOP.equals(orderInfo.getOrderType())) {
            mallOrderService.cancelOrder(orderInfo);
            // 如果是权益兑换订单  删除权益兑换记录
            String prop3 = orderInfo.getProp3();
            if (Constants.MEMBER_BENEFITS.equals(orderInfo.getOrderSubType()) && Strings.isNotEmpty(prop3)) {
                // 根据权益兑换记录id删除权益兑换记录
                memberBenefitsRecordMapper.deleteMemberBenefitsRecordById(Long.parseLong(prop3));
            }
        } else if (Constants.ORDER_TYPE_GIFT_CARD.equals(orderInfo.getOrderType())) {
            mallOrderService.cancelDrawOrder(orderInfo);
        } else if (Constants.ORDER_TYPE_DRAW.equals(orderInfo.getOrderType())) {
            mallOrderService.cancelDrawOrderNew(orderInfo.getId());
        } else if (Constants.ORDER_TYPE_GROUP.equals(orderInfo.getOrderType())) {
            cardGroupOrderInfoService.cancelOrder(orderInfo);
        } else {
            mallOrderService.cancelDrawOrder(orderInfo);
        }
        //返回所有关联优惠劵
        cardGroupOrderInfoService.returnCouponByOrderId(orderInfo.getId());
        boolean isPointOrder = StringUtils.isNotEmpty(orderInfo.getPointType()) && orderInfo.getPointType().startsWith(Constants.POINT_TYPE_MERCHANT_ACT_PRE);
        if (!isPointOrder) {
            String pointType = StringUtils.isNotEmpty(orderInfo.getPointType()) ? orderInfo.getPointType() : Constants.POINT_TYPE_COMMON_RETURN;
            //回退订单消耗积分
            mineApiService.addUserPoint(orderInfo, true, pointType);
        }
    }
}
