/*
 * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.param.PayParam;
import com.yami.shop.bean.enums.OrderType;
import com.yami.shop.bean.event.PaySuccessOrderEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.OrderSettlement;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.enums.PayType;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.dao.OrderMapper;
import com.yami.shop.dao.OrderSettlementMapper;
import com.yami.shop.service.PayService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author lgh on 2018/09/15.
 */
@Slf4j
@Service
@AllArgsConstructor
public class PayServiceImpl implements PayService {

    private final OrderMapper orderMapper;
    private final OrderSettlementMapper orderSettlementMapper;
    private final ApplicationEventPublisher eventPublisher;
    private final Snowflake snowflake;

    /**
     * 不同的订单号，同一个支付流水号
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PayInfoDto pay(String userId, PayParam payParam) {
        // 支付单号
        String payNo = String.valueOf(snowflake.nextId());
        String[] orderNumbers = payParam.getOrderNumbers().split(StrUtil.COMMA);
        // 应支付的总金额
        double payAmount = 0.0;
        double payScore = 0;
        int isScore = 0;
        // 修改订单信息
        for (String orderNumber : orderNumbers) {
            OrderSettlement orderSettlement = orderSettlementMapper.selectOne(
                    new LambdaQueryWrapper<OrderSettlement>()
                            .eq(OrderSettlement::getUserId,userId)
                            .eq(OrderSettlement::getOrderNumber,orderNumber)
            );
            if (Objects.equals(orderSettlement.getPayStatus(), 1)) {
                throw new GlobalException("支付失败，订单不在未支付状态");
            }
            Order order = orderMapper.getOrderByOrderNumber(orderNumber);
            order.setPayType(payParam.getPayType());
            orderMapper.updateById(order);

            orderSettlement.setPayNo(payNo);
            orderSettlement.setPayType(payParam.getPayType());
            orderSettlement.setUserId(userId);
            orderSettlement.setOrderNumber(orderNumber);
            payAmount = Arith.add(payAmount, orderSettlement.getPayAmount());
            payScore += orderSettlement.getPayScore() == null ? 0:orderSettlement.getPayScore();
            orderSettlementMapper.updateByOrderNumberAndUserId(orderSettlement);
        }
        //如果金额小于0.01 支付积分大于0则为纯积分支付
        if(payAmount < 0.01 && payScore > 0){
            isScore = 1;
            paySuccess(payNo, null, PayType.SCOREPAY.value());
        }
        PayInfoDto payInfoDto = new PayInfoDto();
        payInfoDto.setBody("商城订单");
        payInfoDto.setPayAmount(payAmount);
        payInfoDto.setPayNo(payNo);
        payInfoDto.setIsScore(isScore);
        return payInfoDto;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<Order> paySuccess(String payNo, String bizPayNo,Integer payType) {
        List<OrderSettlement> orderSettlements = orderSettlementMapper.selectList(new LambdaQueryWrapper<OrderSettlement>().eq(OrderSettlement::getPayNo, payNo));
        OrderSettlement settlement = orderSettlements.get(0);
        List<String> orderNumbers = orderSettlements.stream().map(OrderSettlement::getOrderNumber).collect(Collectors.toList());
        // 订单已支付
        if (settlement.getPayStatus() == 1) {
            log.info("订单已支付，settlement.id：{}", settlement.getSettlementId());
            return Collections.emptyList();
        }
        // 修改订单结算信息
        if (orderSettlementMapper.updateToPay(payNo,bizPayNo, settlement.getVersion()) < 1) {
            throw new GlobalException("结算信息已更改");
        }
        // 将订单改为已支付状态
        orderMapper.updateByToPaySuccess(orderNumbers, payType);

        //快递订单
        orderMapper.updateByToPaySuccessDelivery(orderNumbers, payType);

        List<OrderItem> allOrderItem = new ArrayList<>();

        List<Order> orders = orderNumbers.stream().map(orderNumber -> {
            Order order = orderMapper.getOrderAndOrderItemByOrderNumber(orderNumber);
            allOrderItem.addAll(order.getOrderItems());
            return order;
        }).collect(Collectors.toList());
        //如果是积分订单无需改变,不是则发送支付成功事件
        if(!Objects.equals(orders.get(0).getOrderType(), OrderType.SCORE.value())){
//            OrderSettlement orderSettlement = orderSettlements.get(0);
//            Order order = orders.get(0);
//            eventPublisher.publishEvent(new UpdateUserScoreEvent(ScoreLogType.SCORE_CASH.value(),orderSettlement.getPayScore(),0,
//                    order.getOrderNumber(), "购买商品花费的积分",order.getUserId()));
//        }else {
            eventPublisher.publishEvent(new PaySuccessOrderEvent(orders, allOrderItem, payNo));
        }
        return orders;
    }
}
