package com.izouma.dingdong.service;

import cn.hutool.core.util.ObjectUtil;
import com.izouma.dingdong.domain.OrderInfo;
import com.izouma.dingdong.domain.OrderRefundApply;
import com.izouma.dingdong.domain.User;
import com.izouma.dingdong.enums.*;
import com.izouma.dingdong.exception.BusinessException;
import com.izouma.dingdong.repo.OrderInfoRepo;
import com.izouma.dingdong.repo.OrderRefundApplyRepo;
import com.izouma.dingdong.repo.UserRepo;
import com.izouma.dingdong.repo.merchant.MerchantRepo;
import com.izouma.dingdong.repo.rider.RiderRepo;
import com.izouma.dingdong.service.merchant.MerchantService;
import com.izouma.dingdong.service.merchant.MerchantSettingsService;
import com.izouma.dingdong.service.rider.RiderService;
import com.izouma.dingdong.utils.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;


@Service
@Slf4j
public class OrderRefundApplyService {

    @Autowired
    private OrderRefundApplyRepo orderRefundApplyRepo;

    @Autowired
    private OrderInfoRepo orderInfoRepo;

    @Autowired
    private UserRepo userRepo;

    @Autowired
    private MerchantRepo merchantRepo;

    @Autowired
    private MerchantSettingsService merchantSettingsService;

    @Autowired
    private RiderService riderService;

    @Autowired
    private RiderRepo riderRepo;

    private OrderStatus status;

    /**
     * 申请退款
     *
     * @param orderId 订单号
     * @param reason  退款缘由
     * @param remark  备注
     */
    public OrderRefundApply apply(Long orderId, RefundReason reason, String remark) {
        OrderInfo order = orderInfoRepo.findById(orderId).orElseThrow(new BusinessException("无记录"));
        //记录原来的订单状态
        status = order.getStatus();
        switch (status) {
            case UNPAID:
                throw new BusinessException("暂未支付");
            case REFUNDED:
                throw new BusinessException("订单已退");
            case CANCELLED:
                throw new BusinessException("订单已取消");
            case REFUNDED_PENDING:
                throw new BusinessException("申请中");
        }

        order.setStatus(OrderStatus.REFUNDED_PENDING);
        order.setReason(reason);
        orderInfoRepo.save(order);

        return orderRefundApplyRepo.save(OrderRefundApply.builder()
                .status(RefundStatus.PENDING)
                .applyTime(LocalDateTime.now())
                .reason(reason)
                .remark(remark)
                .orderId(orderId)
                .report(false)
                .build());
    }

    /**
     * 商家审核退款 线下退
     *
     * @param applyId       申请退款ID
     * @param merchantAgree 商家是否通过
     */
    public void audit(Long applyId, Boolean merchantAgree, Boolean payRider) {
        OrderRefundApply apply = orderRefundApplyRepo.findById(applyId).orElseThrow(new BusinessException("无记录"));
        if (apply.getStatus() != RefundStatus.PENDING) {
            return;
        }

        OrderInfo orderInfo = apply.getOrderInfo();
        userRepo.findById(orderInfo.getUserId()).orElseThrow(new BusinessException("无用户"));
        if (merchantAgree) {

            String refundId = String.valueOf(new SnowflakeIdWorker(1, 1).nextId());
            apply.setStatus(RefundStatus.SUCCESS);
            apply.setMerchantAgree(true);

            //商家同意损失都由商家承担
            apply.setMerchantLiability(BigDecimal.ONE);
            apply.setRiderLiability(BigDecimal.ZERO);
            apply.setPlatformLiability(BigDecimal.ZERO);

            if (StringUtils.isEmpty(apply.getRefundId())) {
                apply.setRefundId(refundId);
            }

            //退款，线下退款订单完成商家才得款


            //骑手得应得的
            if (payRider) {
                //运费
                BigDecimal deliveryAmount = orderInfo.getDeliveryAmount();
                //骑手收入
                Long merId = merchantRepo.findUserIdById(orderInfo.getMerchantId());
                riderService.income(orderInfo.getRiderId(), merId, deliveryAmount, FinancialType.INCOME);
                //商家支出
                Long riderUserId = userRepo.findById(riderRepo.findUserIdById(orderInfo.getRiderId())).orElseThrow(new BusinessException("无用户")).getId();
                merchantSettingsService.income(apply.getMerchantId(), riderUserId, deliveryAmount, FinancialType.LOSE_MONEY);
            }

        } else {

            apply.setStatus(RefundStatus.PENDING);
            apply.setMerchantAgree(false);
            //申请退款中
            orderInfo.setStatus(OrderStatus.REFUNDED_PENDING);
            //apply.getOrderInfo().setStatus((status != null) ? status : OrderStatus.PAID);
            //上报到后台
            apply.setReport(true);
        }

        apply.setAuditTime(LocalDateTime.now());
        orderInfoRepo.save(orderInfo);
        orderRefundApplyRepo.save(apply);


    }

    /*
    取消退款
     */
    public void cancelRefundApply(Long orderId) {
        orderInfoRepo.findById(orderId).orElseThrow(new BusinessException("无订单"));
        OrderRefundApply apply = orderRefundApplyRepo.findByOrderIdAndStatus(orderId, RefundStatus.PENDING).orElseThrow(new BusinessException("未申请退款"));
        apply.setStatus(RefundStatus.CANCEL);
        apply.getOrderInfo().setStatus((status != null) ? status : OrderStatus.PAID);
        orderInfoRepo.save(apply.getOrderInfo());
        orderRefundApplyRepo.save(apply);
    }

    /*
    商家的所有退款订单
     */
    public List<OrderRefundApply> merchantRefund(Long id) {
        return orderRefundApplyRepo.findAllByMerchantId(id);
    }

    //商家同意 商家不同意

    //平台
    public void platformAudit(Long applyId, Boolean agree, BigDecimal merchantLiability, BigDecimal riderLiability) {

        OrderRefundApply apply = orderRefundApplyRepo.findById(applyId).orElseThrow(new BusinessException("无记录"));
        if (ObjectUtil.isNull(merchantLiability)) {
            merchantLiability = BigDecimal.ZERO;
        }
        if (ObjectUtil.isNull(riderLiability)) {
            riderLiability = BigDecimal.ZERO;
        }
        if (agree) {
            apply.setPlatformAgree(true);
            apply.setPlatformLiability(BigDecimal.ONE.subtract(riderLiability).subtract(merchantLiability));
            apply.setRiderLiability(riderLiability);
            apply.setMerchantLiability(merchantLiability);

            if (!merchantLiability.equals(BigDecimal.ZERO)) {
                //商家所赔金额
                BigDecimal merAmount = apply.getOrderInfo().getRealAmount().multiply(merchantLiability);
                merchantSettingsService.income(apply.getMerchantId(), apply.getOrderInfo().getUserId(), merAmount, FinancialType.REFUND);
            }

            if (!riderLiability.equals(BigDecimal.ZERO)) {
                //骑手赔付金额
                BigDecimal riderAmount = apply.getOrderInfo().getRealAmount().multiply(riderLiability);
                riderService.income(apply.getOrderInfo().getRiderId(), apply.getOrderInfo().getUserId(), riderAmount, FinancialType.REFUND);
            }

            apply.getOrderInfo().setStatus(OrderStatus.REFUNDED);
        } else {
            apply.setPlatformAgree(false);
            //原状态
            apply.getOrderInfo().setStatus(status);
            apply.getOrderInfo().setCancel(false);
        }

        orderInfoRepo.save(apply.getOrderInfo());

        apply.setPlatformAuditTime(LocalDateTime.now());
        orderRefundApplyRepo.save(apply);
    }
}
