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

import cn.hutool.core.util.StrUtil;
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.contant.enumerate.DeductionTypeEnum;
import com.xxfc.platform.order.contant.enumerate.ItemTypeEnum;
import com.xxfc.platform.order.contant.enumerate.OrderStatusEnum;
import com.xxfc.platform.order.entity.BaseOrder;
import com.xxfc.platform.order.entity.OrderItem;
import com.xxfc.platform.order.entity.OrderRentVehicleDetail;
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
    OrderItemBiz orderItemBiz;

    @Autowired
    OrderAccountBiz orderAccountBiz;

    public InProgressVO inProgressCalculate(BaseOrder baseOrder, OrderItem orderItem, Integer freeDays, Integer useDays, OrderAccountDetail oad, Boolean isCancel) {
        BigDecimal refundAmount = BigDecimal.ZERO;
        BigDecimal consumeAmount = BigDecimal.ZERO;
        //商品真实价格
        BigDecimal goodsRealAmount = baseOrder.getGoodsAmount().subtract(baseOrder.getCouponAmount());
        //其他消费金额 = 商品真实价格 - 主要商品真实价格 = （商品价格 - 优惠价格）- 主要商品真实价格
        BigDecimal otherItemRealAmount = goodsRealAmount.subtract(orderItem.getRealAmount());

        InProgressVO inProgressVO = new InProgressVO();
        inProgressVO.setUsedDays(useDays);
        inProgressVO.setUsedAmount(orderItem.getUnitPrice().multiply(new BigDecimal(useDays+ "")));

        //计算：剩余免费天数
        Integer backFreeDays = freeDays - useDays;
        //待返还的免费天数
        List<String> backCouponNos = Lists.newArrayList();
        //剩余天数
        Integer residueDays = orderItem.getTotalNum() - useDays;
        //过了出发时间取消订单 ，优先使用免费天数
        if(backFreeDays <= 0) {
            //设置免费天数
            inProgressVO.setUsedfreeDays(freeDays);
            inProgressVO.setUsedFreeDaysAmount(orderItem.getUnitPrice().multiply(new BigDecimal(freeDays+ "")));

            //消费天数
            Integer consumeDays = useDays - freeDays;
            //如果使用天数 大于 总天数
            if(useDays > orderItem.getTotalNum()) {
                    //消费天数
                consumeDays = orderItem.getTotalNum() - freeDays;
            }

            //需要扣除订单费用
            //判断是否达到优惠券条件 不符合则返还优惠券
            //计算使用天数的费用
            consumeAmount = orderItem.getUnitPrice().multiply(new BigDecimal(consumeDays+""));
            if(StrUtil.isNotBlank(baseOrder.getCouponTickerNos())) {
                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);
                }
            }

            //设置消费金额
            consumeAmount = consumeAmount.add(otherItemRealAmount);
            inProgressVO.setConsumeAmount(consumeAmount);

            refundAmount = handleConsumeAmount(oad, refundAmount, consumeAmount, goodsRealAmount, inProgressVO);
        }else {
            //设置免费天数
            inProgressVO.setUsedfreeDays(useDays);
            inProgressVO.setUsedFreeDaysAmount(orderItem.getUnitPrice().multiply(new BigDecimal(useDays+ "")));

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

            //返回优惠券
            if(StrUtil.isNotBlank(baseOrder.getCouponTickerNos())) {
                //返回所有优惠券
                inProgressVO.setBackCoupons(StrUtil.split(baseOrder.getCouponTickerNos(), ','));
            }

            //设置消费金额 由于返回了优惠券，所以添加优惠券之前减免的金额
            consumeAmount = consumeAmount.add(otherItemRealAmount).add(baseOrder.getCouponAmount());
            inProgressVO.setConsumeAmount(consumeAmount);

            refundAmount = handleConsumeAmount(oad, refundAmount, consumeAmount, goodsRealAmount, inProgressVO);

        }

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

        //计算违约金
            //residueDays * 身份价格
        if(residueDays > 0) {
            String violateDesc = StrUtil.format("{}元/天 x{}天", orderItem.getUnitPrice().toString(), residueDays);
            if(residueDays > 2) {
                residueDays = 2;
                violateDesc += StrUtil.format("（封顶{}元）", orderItem.getUnitPrice().multiply(new BigDecimal((residueDays + ""))));
            }
            inProgressVO.setViolateAmount(orderItem.getUnitPrice().multiply(new BigDecimal((residueDays + ""))));
            inProgressVO.setViolateDesc(" 提前还车违约金："+ violateDesc);
            OrderAccountDeduction violateDeduction = orderAccountBiz.initDeduction(inProgressVO.getViolateAmount(), violateDesc, DeductionTypeEnum.VIOLATE_ADVANCE, OrderAccountDeduction.ORIGIN_DEPOSIT);
            oad.getDeductions().add(violateDeduction);
        }else if(residueDays < 0 && !isCancel){
            //如果订单 出发中 或者 已完成 或者定损中
            if(OrderStatusEnum.ORDER_WAIT.getCode().equals(baseOrder.getStatus()) ||
                    OrderStatusEnum.ORDER_FINISH.getCode().equals(baseOrder.getStatus()) ||
                    OrderStatusEnum.ORDER_FIXED_LOSS.getCode().equals(baseOrder.getStatus())) {
                Integer overDays = 0 - residueDays;
                String violateDesc = StrUtil.format("({}元/天 x200%) x{}天", orderItem.getUnitPrice().toString(), overDays);
//                if(overDays > 2) {
//                    overDays = 2;
//                    violateDesc += StrUtil.format("（封顶{}元）", orderItem.getUnitPrice().multiply(new BigDecimal((residueDays + ""))));
//                }
                //超过的天数 * 200% * 单价
                inProgressVO.setViolateAmount(orderItem.getUnitPrice().multiply(new BigDecimal(2+ "")).multiply(new BigDecimal((overDays + ""))));
                inProgressVO.setViolateDesc(" 延期还车违约金："+ violateDesc);
                OrderAccountDeduction violateDeduction = orderAccountBiz.initDeduction(inProgressVO.getViolateAmount(), violateDesc, DeductionTypeEnum.VIOLATE_DELAY, OrderAccountDeduction.ORIGIN_DEPOSIT);
                oad.getDeductions().add(violateDeduction);
            }
        }

        return inProgressVO;
    }

    private BigDecimal handleConsumeAmount(OrderAccountDetail oad, BigDecimal refundAmount, BigDecimal consumeAmount, BigDecimal goodsRealAmount, InProgressVO inProgressVO) {
        if (consumeAmount.compareTo(BigDecimal.ZERO) > 0) {
            //消费金额 大于0 增加额外费用
            OrderAccountDeduction consumeDeduction = orderAccountBiz.initDeduction(consumeAmount, "消费金额", DeductionTypeEnum.CONSUME, OrderAccountDeduction.ORIGIN_ORDER_DEPOSIT);
            oad.getDeductions().add(consumeDeduction);
        }

        //消费金额 小于商品真实的金额 返回钱
        if (consumeAmount.compareTo(goodsRealAmount) <= 0) {
            //设置返回钱
            refundAmount = refundAmount.add(goodsRealAmount.subtract(consumeAmount));
        } else {
            //设置额外扣减（押金里面扣）
            inProgressVO.setExtraAmount(consumeAmount.subtract(goodsRealAmount));
        }
        return refundAmount;
    }

    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, new OrderAccountDetail(), Boolean.FALSE);
    }

    public InProgressVO calculateOrderComplete(BaseOrder baseOrder, OrderRentVehicleDetail orvd, OrderAccountDetail oad, OrderItem orderItem, Integer useDays, Boolean isCancel) {
        InProgressVO inProgressVO = inProgressCalculate(baseOrder, orderItem, orvd.getFreeDays(), useDays, oad, isCancel);

        //定金 - （额外消费金额 + 违约金）
        oad.setDepositAmount(orvd.getDeposit().subtract(inProgressVO.getExtraAmount().add(inProgressVO.getViolateAmount())));
        oad.setOrderAmount(inProgressVO.getRefundOrderAmount());
        oad.setOriginDepositAmount(orvd.getDeposit());
        oad.setOriginOrderAmount(baseOrder.getGoodsAmount().subtract(baseOrder.getCouponAmount()));
        return inProgressVO;
    }
}