package com.xxfc.platform.order.biz.inner;

import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.xxfc.platform.activity.entity.Coupon;
import com.xxfc.platform.activity.feign.ActivityFeign;
import com.xxfc.platform.app.feign.ConfigFeign;
import com.xxfc.platform.order.biz.OrderAccountBiz;
import com.xxfc.platform.order.biz.OrderItemBiz;
import com.xxfc.platform.order.biz.OrderRefundBiz;
import com.xxfc.platform.order.contant.enumerate.*;
import com.xxfc.platform.order.entity.*;
import com.xxfc.platform.order.pojo.account.OrderAccountDeduction;
import com.xxfc.platform.order.pojo.account.OrderAccountDetail;
import com.xxfc.platform.order.pojo.calculate.InProgressVO;
import com.xxfc.platform.universal.feign.ThirdFeign;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 订单退款记录表
 *
 * @author zjw
 * @email nishijjo@qq.com
 * @date 2019-06-18 11:08:09
 */
@Slf4j
@Service
public class OrderCalculateBiz {

    @Autowired
    UserFeign userFeign;

    @Autowired
    ThirdFeign thirdFeign;

    @Autowired
    VehicleFeign vehicleFeign;

    @Autowired
    ConfigFeign configFeign;

    @Autowired
    ActivityFeign activityFeign;

    @Autowired
    OrderRefundBiz orderRefundBiz;

    @Autowired
    OrderItemBiz orderItemBiz;

    @Autowired
    OrderAccountBiz orderAccountBiz;

    public InProgressVO inProgressCalculate(BaseOrder baseOrder, OrderItem orderItem, Integer freeDays, Integer useDays, OrderAccountDetail oad) {
        BigDecimal refundAmount = BigDecimal.ZERO;
        InProgressVO inProgressVO = new InProgressVO();
        inProgressVO.setUsedDays(useDays);
        inProgressVO.setUsedfreeDays(freeDays);
        inProgressVO.setUsedAmount(orderItem.getUnitPrice().multiply(new BigDecimal(useDays+ "")));
        inProgressVO.setUsedFreeDaysAmount(orderItem.getUnitPrice().multiply(new BigDecimal(freeDays+ "")));

        //计算：剩余免费天数
        Integer backFreeDays = freeDays - useDays;
        //待返还的免费天数
        List<String> backCouponNos = Lists.newArrayList();
        //剩余天数
        Integer residueDays = orderItem.getTotalNum() - useDays;
        //过了出发时间取消订单 ，优先使用免费天数
        if(backFreeDays <= 0) {
            //使用天数 小于 总天数
            if(useDays < orderItem.getTotalNum()) {
                //需要扣除订单费用
                //判断是否达到优惠券条件 不符合则返还优惠券
                    //消费天数
                Integer consumeDays = 0 - backFreeDays;
                    //计算使用天数的费用
                BigDecimal consumeAmount = orderItem.getUnitPrice().multiply(new BigDecimal(consumeDays+""));
                List<BigDecimal> couponAmounts = Lists.newArrayList();
                for(String tickerNo : baseOrder.getCouponTickerNos().split(",")) {
                    BigDecimal couponAmount = activityFeign.use(baseOrder.getUserId(), Lists.newArrayList(tickerNo), baseOrder.getNo(), Coupon.CHANNEL_RENT, consumeAmount, ActivityFeign.TYPE_CHECK);
                    if(couponAmount.compareTo(BigDecimal.ZERO) > 0) {
                        //能够使用优惠券，则不返还
                        couponAmounts.add(couponAmount);
                    } else {
                        backCouponNos.add(tickerNo);
                    }
                }

                for(BigDecimal couponAmount : couponAmounts) {
                    consumeAmount = consumeAmount.subtract(couponAmount);
                }

                if(consumeAmount.compareTo(orderItem.getRealAmount()) > 0) {
                    //消费金额 大于真实的金额 增加额外费用
                    inProgressVO.setExtraAmount(consumeAmount.subtract(orderItem.getRealAmount()));
//                    consumeAmount = orderItem
                    OrderAccountDeduction extraDeduction = orderAccountBiz.initDeduction(inProgressVO.getExtraAmount(), "消费额外费用", DeductionTypeEnum.EXTRA, OrderAccountDeduction.ORIGIN_DEPOSIT);
                    oad.getDeductions().add(extraDeduction);
                }else {
                    //否则，设置返回钱
                    refundAmount = refundAmount.add(orderItem.getRealAmount().subtract(consumeAmount));
                }
            } else {

            }
        }else {
            //返回剩余免费天数，返回优惠券，订单款
            refundAmount = refundAmount.add(orderItem.getRealAmount());
            inProgressVO.setBackFreeDays(backFreeDays);

        }

        inProgressVO.setRefundOrderAmount(refundAmount);
        inProgressVO.setBackCoupons(backCouponNos);

        //计算违约金
            //residueDays * 身份价格
        if(residueDays > 0) {
            if(residueDays > 2) {
                residueDays = 2;
            }
            inProgressVO.setViolateAmount(orderItem.getUnitPrice().multiply(new BigDecimal((residueDays + ""))));
            OrderAccountDeduction violateDeduction = orderAccountBiz.initDeduction(inProgressVO.getViolateAmount(), "违约金", DeductionTypeEnum.VIOLATE_ADVANCE, OrderAccountDeduction.ORIGIN_DEPOSIT);
            oad.getDeductions().add(violateDeduction);
        }else if(residueDays < 0){
            //如果订单 出发中 或者 已完成 或者定损中
            if(OrderStatusEnum.ORDER_WAIT.equals(baseOrder.getStatus()) ||
                    OrderStatusEnum.ORDER_FINISH.equals(baseOrder.getStatus()) ||
                    OrderStatusEnum.ORDER_FIXED_LOSS.equals(baseOrder.getStatus())) {
                Integer overDays = 0 - residueDays;
                if(overDays > 2) {
                    overDays = 2;
                }
                //超过的天数 * 200% * 单价
                inProgressVO.setViolateAmount(orderItem.getUnitPrice().multiply(new BigDecimal(2+ "")).multiply(new BigDecimal((overDays + ""))));
                OrderAccountDeduction violateDeduction = orderAccountBiz.initDeduction(inProgressVO.getViolateAmount(), "违约金", DeductionTypeEnum.VIOLATE_DELAY, OrderAccountDeduction.ORIGIN_DEPOSIT);
                oad.getDeductions().add(violateDeduction);
            }
        }

        return inProgressVO;
    }

    public InProgressVO inProgressCalculate(BaseOrder baseOrder, Integer useDays) {
        OrderItem orderItem = orderItemBiz.selectOne(new OrderItem(){{
            setType(ItemTypeEnum.VEHICLE_MODEL.getCode());
            setOrderId(baseOrder.getId());
        }});
        Integer freeDays = (null == orderItem.getCutNum())?0 :orderItem.getCutNum();
        return inProgressCalculate(baseOrder, orderItem, freeDays, useDays, null);
    }

    public InProgressVO calculateOrderComplete(BaseOrder baseOrder, OrderRentVehicleDetail orvd, OrderAccountDetail oad, OrderItem orderItem, Integer useDays) {
        InProgressVO inProgressVO = inProgressCalculate(baseOrder, orderItem, orvd.getFreeDays(), useDays, oad);
        oad.setDepositAmount(orvd.getDeposit().subtract(inProgressVO.getExtraAmount()).subtract(inProgressVO.getViolateAmount()));
        oad.setOrderAmount(inProgressVO.getRefundOrderAmount());
        oad.setOriginDepositAmount(orvd.getDeposit());
        oad.setOriginOrderAmount(baseOrder.getRealAmount());
        return inProgressVO;
    }
}