package com.yonge.cooleshow.biz.dal.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yonge.cooleshow.biz.dal.dao.UserOrderDao;
import com.yonge.cooleshow.biz.dal.entity.UserOrder;
import com.yonge.cooleshow.biz.dal.entity.UserOrderPayment;
import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
import com.yonge.cooleshow.biz.dal.service.UserOrderPaymentService;
import com.yonge.cooleshow.biz.dal.service.UserOrderService;
import com.yonge.cooleshow.biz.dal.service.UserPaymentOrderService;
import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
import com.yonge.cooleshow.common.enums.EPaymentVersion;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.payment.base.enums.TradeStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery;

/**
 * 平台订单表
 * 2022-12-20 19:09:34
 */
@Slf4j
@Service
public class UserPaymentOrderServiceImpl  implements UserPaymentOrderService {

    @Autowired
    private UserOrderService userOrderService;

    @Autowired
    private UserOrderPaymentService userOrderPaymentService;

    @Autowired
    private UserOrderDao userOrderDao;


    /**
     * 用户支付订单信息
     *
     * @param merOrderNo 订单编号
     * @return UserPaymentOrder
     */
    @Override
    public UserPaymentOrderWrapper.UserPaymentOrder getUserPaymentOrderByOrderNo(String merOrderNo) {

        // 查询订单信息
        UserOrder one = userOrderService.lambdaQuery()
                .eq(UserOrder::getOrderNo, merOrderNo)
                .last("LIMIT 1")
                .one();

        if (one == null) {
            return null;
        }

        if (one.getPaymentVersion().equals(EPaymentVersion.V1)) {
            throw new BizException("支付方式不支持");
        }

        // 查询订单支付信息
        UserOrderPayment newestPayment = userOrderPaymentService.getNewestPayment(null, merOrderNo);

        return UserPaymentOrderWrapper.UserPaymentOrder.from(one, newestPayment);


    }


    /**
     * 分页查询
     * @param page IPage<com.cooleshow.edu.domain.wrapper.UserPaymentOrderWrapper.UserPaymentOrder>
     * @param query UserPaymentOrderWrapper.UserPaymentOrderQuery
     * @return IPage<com.cooleshow.edu.domain.wrapper.UserPaymentOrderWrapper.UserPaymentOrder>
     */
    @Override
    public IPage<UserPaymentOrderWrapper.UserPaymentOrder> selectPage(IPage<UserPaymentOrderWrapper.UserPaymentOrder> page,
                                                                      UserPaymentOrderWrapper.UserPaymentOrderQuery query) {

        List<UserOrder> userOrders = userOrderDao.selectPaymentOrderPage(page, query);

        if (CollectionUtils.isEmpty(userOrders)) {
            return page;
        }

        // 获取订单号
        List<String> orderNos = userOrders.stream().map(o -> o.getOrderNo()).collect(Collectors.toList());

        Map<String, UserOrderPayment> paymentMap = userOrderPaymentService.getNewestPaymentMapByOrderNos(orderNos);

        List<UserPaymentOrderWrapper.UserPaymentOrder> paymentOrders = new ArrayList<>(userOrders.size());
        for (UserOrder userOrder : userOrders) {
            paymentOrders.add(UserPaymentOrderWrapper.UserPaymentOrder.from(userOrder, paymentMap.get(userOrder.getOrderNo())));
        }

        return page.setRecords(paymentOrders);
    }


    /**
     * 用户支付订单
     *
     * @param userId     用户Id
     * @param merOrderNo 商户订单编号
     * @return UserPaymentOrder
     */
    @Override
    public UserPaymentOrderWrapper.UserPaymentOrder getUserPaymentOrderByUserId(Long userId, String merOrderNo) {

        UserOrder userOrder = userOrderService.lambdaQuery()
//                .eq(UserOrder::getUserId, userId)
                .eq(UserOrder::getOrderNo, merOrderNo)
                .last("LIMIT 1")
                .one();
        if (userOrder == null) {
            return null;
        }

        if (userOrder.getPaymentVersion().equals(EPaymentVersion.V1)) {
            throw new BizException("支付方式不支持");
        }
        // 查询订单支付信息
        UserOrderPayment newestPayment = userOrderPaymentService.getNewestPayment(null, merOrderNo);

        return UserPaymentOrderWrapper.UserPaymentOrder.from(userOrder, newestPayment);


    }


    /**
     * 关闭用户支付订单状态
     *
     * @param id 用户支付订单Id
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
    public void closeUserPaymentOrder(Long id) {

        UserOrder userOrder = new UserOrder();
        userOrder.setId(id);
        userOrder.setStatus(OrderStatusEnum.CLOSE);
        userOrderService.updateById(userOrder);

        // 订单关闭后的数据处理流程
        userOrderService.payCancel(userOrderService.detail(id));
    }


    @Override
    @Transactional
    public void updateById(UserPaymentOrderWrapper.UserPaymentOrder order) {
        if (order == null) {
            return;
        }

        // 更新订单
        UserOrder userOrder = order.toUserOrder();
        userOrderService.updateById(userOrder);

        // 更新订单支付信息

        UserOrder order1 = userOrderService.getById(userOrder.getId());

        if (order1.getPaymentVersion().equals(EPaymentVersion.V1)) {
            throw new BizException("支付方式不支持");
        }

        UserOrderPayment newestPayment = userOrderPaymentService.getNewestPayment(null, order1.getOrderNo());
        if (newestPayment == null) {
            newestPayment = new UserOrderPayment();
        }

        newestPayment.setOrderNo(order1.getOrderNo());
        newestPayment.setPaymentVendor(order1.getPaymentVendor());
        newestPayment.setPaymentChannel(order1.getPaymentChannel());
        newestPayment.setPaymentAppId(order1.getPaymentAppId());
        newestPayment.setPaymentNo(order1.getOrderNo());
        newestPayment.setTransNo(order.getTransNo());
        newestPayment.setPayAmt(order1.getActualPrice());
        newestPayment.setFeeAmt(order.getPaymentChannelFee());
        // 状态转换
        switch (order.getStatus()) {
            case TIMEOUT:
            case FAIL:
                newestPayment.setStatus(TradeStatusEnum.failed);
                newestPayment.setPayFailMsg(order.getErrorMsg());
                break;
            case PAID:
            case REFUNDED:
                newestPayment.setStatus(TradeStatusEnum.succeeded);
                break;
            case CLOSED:
                // 关闭状态需要三方回掉
                newestPayment.setStatus(TradeStatusEnum.close);
                break;
            case PAYING:
            case WAIT_PAY:
            default:
                break;

        }
        userOrderPaymentService.saveOrUpdate(newestPayment);
    }

    /**
     * 更新订单支付三方
     *
     * @param order UserPaymentOrderWrapper.UserPaymentOrder
     */
    @Override
    public void updatePaymentVendorById(UserPaymentOrderWrapper.UserPaymentOrder order) {

        if (order == null) {
            return;
        }

        // 更新订单
        UserOrder userOrder = order.toUserOrder();
        userOrderService.updateById(userOrder);
    }

    /**
     * 创建订单
     *
     * @param orderReq
     */
    @Override
    @Transactional
    public void save(UserPaymentOrderWrapper.UserPaymentOrder orderReq) {

        // 更新订单
        UserOrder userOrder = orderReq.toUserOrder();
        userOrder.setPaymentVersion(EPaymentVersion.V2);

        userOrderService.save(userOrder);
        orderReq.setId(userOrder.getId());
    }

    @Override
    public UserPaymentOrderWrapper.UserPaymentOrder getUserPaymentOrderByTranNo(String transNo) {

        // 查询订单信息
        UserOrderPayment one = userOrderPaymentService.lambdaQuery()
            .eq(UserOrderPayment::getTransNo, transNo)
            .last("LIMIT 1")
            .one();

        if (one == null) {
            return null;
        }
        UserOrder one1 = userOrderService.lambdaQuery()
            .eq(UserOrder::getOrderNo, one.getOrderNo())
            .last("limit 1")
            .one();


        if (one1.getPaymentVersion().equals(EPaymentVersion.V1)) {
            throw new BizException("支付方式不支持");
        }

        // 查询订单支付信息

        return UserPaymentOrderWrapper.UserPaymentOrder.from(one1, one);

    }

}
