package com.heyu.api.data.service.impl;


import com.heyu.api.data.enums.ReverseUploadSceneEnums;


import com.heyu.api.data.dao.vv.*;
import com.heyu.api.data.entity.vv.*;
import com.heyu.api.data.utils.BigDecimalUtil;
import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.SanUtils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
@Slf4j
public class ReverseOrderServiceImpl implements ReverseOrderService {

    @Autowired
    private VvTradeOrderDao vvTradeOrderDao;


    @Autowired
    private VvReverseOrderLineDao vvReverseOrderLineDao;

    @Autowired
    private VvReverseOrderDao vvReverseOrderDao;

    @Autowired
    private VvTradeOrderLineDao vvTradeOrderLineDao;

    @Autowired
    private VvReverseOrderProveDao vvReverseOrderProveDao;



    @Override
    public R createReverseOrder(List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList, AppliyReverseRequest appliyReverseRequest) {
        List<Long> tradeOrderLineIds = SanUtils.list2FieldList(vvTradeOrderLineEntityList, VvTradeOrderLineEntity::getId);
        Map<Long, VvTradeOrderLineEntity> vvTradeOrderLineEntityMap = SanUtils.groupByFiled2Map(vvTradeOrderLineEntityList, VvTradeOrderLineEntity::getId);
        Long tradeOrderId = SanUtils.findAnyNotNull(vvTradeOrderLineEntityList, VvTradeOrderLineEntity::getTradeOrderId);
        VvTradeOrderEntity vvTradeOrderEntity = vvTradeOrderDao.selectVvTradeOrderById(tradeOrderId);
        VvReverseOrderEntity vvReverseOrderEntity = new VvReverseOrderEntity();
        vvReverseOrderEntity.setTradeOrderId(vvTradeOrderEntity.getId());
        vvReverseOrderEntity.setStatus(appliyReverseRequest.getStatus());

        BigDecimal realRefundAmount = appliyReverseRequest.getRefundAmount() == null
                ? SanUtils.sum(vvTradeOrderLineEntityList, VvTradeOrderLineEntity::getPayAmount)
                : appliyReverseRequest.getRefundAmount();

        // 设置退款金额
        vvReverseOrderEntity.setRefundAmount(realRefundAmount);

        BigDecimal originRefundAmount = SanUtils.sum(vvTradeOrderLineEntityList, VvTradeOrderLineEntity::getPayAmount); // 本来应该退款金额
        if (realRefundAmount.compareTo(originRefundAmount) > 0) {
            log.info("createReverseOrder realRefundAmount not 大于 originRefundAmount，realRefundAmount:{},originRefundAmount:{}",realRefundAmount,originRefundAmount);
            return R.error("退款金额不能大于原来金额");
        }

        vvReverseOrderEntity.setRefundTradeOrderLineCount(tradeOrderLineIds.size());
        vvReverseOrderEntity.setRefundType(appliyReverseRequest.getRefundType());
        vvReverseOrderEntity.setGmtBuyerApplyRefund(new Date());
        vvReverseOrderEntity.setCreateTimestamp(System.currentTimeMillis());
        vvReverseOrderEntity.setModifyTimestamp(System.currentTimeMillis());
        vvReverseOrderEntity.setRefundCount(tradeOrderLineIds.size());
        vvReverseOrderEntity.setGmtBuyerApplyRefund(new Date());
        vvReverseOrderEntity.setRefundReason(appliyReverseRequest.getRefundReason());

        vvReverseOrderDao.insertOrUpdateVvReverseOrder(vvReverseOrderEntity);
        BigDecimal preSum = BigDecimal.ZERO;

        for (int i = 0; i < tradeOrderLineIds.size(); i++) {
            Long tradeOrderLineId = tradeOrderLineIds.get(i);
            VvTradeOrderLineEntity vvTradeOrderLineEntity = vvTradeOrderLineEntityMap.get(tradeOrderLineId);
            VvReverseOrderLineEntity vvReverseOrderLineEntity = new VvReverseOrderLineEntity();
            vvReverseOrderLineEntity.setReverseOrderId(vvReverseOrderEntity.getId());
            vvReverseOrderLineEntity.setTradeOrderId(vvTradeOrderEntity.getId());
            vvReverseOrderLineEntity.setTradeOrderLineId(tradeOrderLineId);
            if (appliyReverseRequest.getRefundAmount() == null) {
                vvReverseOrderLineEntity.setRefundAmount(vvTradeOrderLineEntity.getPayAmount());
            } else {
                if (i == tradeOrderLineIds.size() - 1) {
                    BigDecimal lastRefundAmount = BigDecimalUtil.subtract(realRefundAmount, preSum);
                    vvReverseOrderLineEntity.setRefundAmount(lastRefundAmount);
                } else {
                    BigDecimal subLineRefundAmount = BigDecimalUtil.multiply(vvTradeOrderLineEntity.getPayAmount(),
                            BigDecimalUtil.divide(realRefundAmount, originRefundAmount));

                    preSum = preSum.add(subLineRefundAmount);
                    vvReverseOrderLineEntity.setRefundAmount(subLineRefundAmount);
                }
            }

            vvReverseOrderLineEntity.setSellerId(vvTradeOrderLineEntity.getSellerId());
            vvReverseOrderLineEntity.setSellerName(vvTradeOrderLineEntity.getSellerName());
            vvReverseOrderLineEntity.setProductId(vvTradeOrderLineEntity.getProductId());
            vvReverseOrderLineEntity.setProductName(vvTradeOrderLineEntity.getProductName());
            vvReverseOrderLineEntity.setSkuImageUrl(vvTradeOrderLineEntity.getSkuImageUrl());

            // 保存逆向子单
            vvReverseOrderLineDao.insertVvReverseOrderLine(vvReverseOrderLineEntity);

            // 设置退款相关的东西
            vvTradeOrderLineEntity.setRefundCount(1);
            vvTradeOrderLineEntity.setRefundAmount(vvReverseOrderLineEntity.getRefundAmount());

            // 更新子单的逆向状态
            vvTradeOrderLineEntity.setReverseStatus(appliyReverseRequest.getStatus());
            vvTradeOrderLineDao.updateVvTradeOrderLineById(vvTradeOrderLineEntity);
        }
        if (CollectionUtils.isNotEmpty(appliyReverseRequest.getResourceDTOList())) {
            for (ResourceDTO resourceDTO : appliyReverseRequest.getResourceDTOList()) {
                VvReverseOrderProveEntity vvReverseOrderProveEntity = new VvReverseOrderProveEntity();
                vvReverseOrderProveEntity.setReverseOrderId(vvReverseOrderEntity.getId());
                vvReverseOrderProveEntity.setResourceUrl(resourceDTO.getResourceUrl());
                vvReverseOrderProveEntity.setType(resourceDTO.getType());
                vvReverseOrderProveEntity.setScene(ReverseUploadSceneEnums.upload_reverse_prove.getCode());
                vvReverseOrderProveDao.insertOrUpdateVvReverseOrderProve(vvReverseOrderProveEntity);
            }
        }


        return R.ok().setData(vvReverseOrderEntity);
    }

}
