package com.xxfc.platform.order.rest;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.rest.UserRestInterface;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreClientToken;
import com.github.wxiaoqi.security.common.constant.CommonConstants;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.rest.BaseController;
import com.github.wxiaoqi.security.common.util.Query;
import com.github.wxiaoqi.security.common.vo.PageParam;
import com.xxfc.platform.order.biz.BaseOrderBiz;
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.biz.inner.OrderCalculateBiz;
import com.xxfc.platform.order.biz.inner.OrderCancelBiz;
import com.xxfc.platform.order.contant.enumerate.ItemTypeEnum;
import com.xxfc.platform.order.contant.enumerate.OrderStatusEnum;
import com.xxfc.platform.order.contant.enumerate.OrderTypeEnum;
import com.xxfc.platform.order.entity.OrderItem;
import com.xxfc.platform.order.entity.OrderRefund;
import com.xxfc.platform.order.entity.OrderRentVehicleDetail;
import com.xxfc.platform.order.pojo.account.OrderAccountDetail;
import com.xxfc.platform.order.pojo.calculate.InProgressVO;
import com.xxfc.platform.order.pojo.order.OrderPageVO;
import com.xxfc.platform.order.pojo.order.VehicleItemDTO;
import com.xxfc.platform.universal.constant.DictionaryKey;
import lombok.Data;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.math.RoundingMode;

import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_FALSE;
import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_TRUE;
import static com.xxfc.platform.universal.constant.DictionaryKey.*;

@Controller
@RequestMapping("orderRefund")
public class OrderRefundController extends BaseController<OrderRefundBiz,OrderRefund> implements UserRestInterface {

    @Autowired
    BaseOrderBiz baseOrderBiz;

    @Autowired
    OrderAccountBiz orderAccountBiz;

    @Autowired
    OrderItemBiz orderItemBiz;

    @Autowired
    OrderCalculateBiz orderCalculateBiz;

    @Autowired
    UserFeign userFeign;

    @Override
    public UserFeign getUserFeign() {
        return userFeign;
    }

    @RequestMapping(value = "/price/calculate/{no}", method = RequestMethod.GET)
    @ResponseBody
    @IgnoreClientToken
    public ObjectRestResponse<BigDecimal> getPriceCalculate(@PathVariable(value = "no") String no) {
        checkAppUser();
        //根据no 查订单
        OrderPageVO orderPageVO = baseOrderBiz.pageByParm(new Query(new PageParam(){{
            setLimit(1);
            setPage(1);
        }}){{put("no", no); }}.getSuper()).get(0);

        OrderTypeEnum orderTypeEnum = OrderTypeEnum.get(orderPageVO.getType());

        BigDecimal totalRefundAmount = BigDecimal.ZERO;
        BigDecimal totalDeductAmount = BigDecimal.ZERO;
        StringBuilder refundDescBuilder = new StringBuilder("");
        String refundDesc = "";
        InProgressVO inProgressVO = new InProgressVO();

        switch (orderTypeEnum) {
            case RENT_VEHICLE:
                DateTime nowTime = DateTime.parse(DateTime.now().toString(CommonConstants.YMR_SLASH_FORMATTER_JODA), CommonConstants.YMR_SLASH_FORMATTER_JODA);
                DateTime startTime = DateTime.parse(new DateTime(orderPageVO.getOrderRentVehicleDetail().getStartTime()).toString(CommonConstants.YMR_SLASH_FORMATTER_JODA), CommonConstants.YMR_SLASH_FORMATTER_JODA);
                DateTime endTime = DateTime.parse(new DateTime(orderPageVO.getOrderRentVehicleDetail().getEndTime()).toString(CommonConstants.YMR_SLASH_FORMATTER_JODA), CommonConstants.YMR_SLASH_FORMATTER_JODA);

                Long timeLag = orderPageVO.getOrderRentVehicleDetail().getStartTime() - System.currentTimeMillis();

                VehicleItemDTO vehicleItemDTO = BeanUtil.toBean(orderItemBiz.selectOne(new OrderItem(){{
                    setType(ItemTypeEnum.VEHICLE_MODEL.getCode());
                    setOrderId(orderPageVO.getId());
                }}), VehicleItemDTO.class);

                if(timeLag < 0 ) {
                    OrderAccountDetail oad = new OrderAccountDetail();
                    Integer freeDays = (null == vehicleItemDTO.getCutNum())?0 :vehicleItemDTO.getCutNum();
                    inProgressVO = orderCalculateBiz.inProgressCalculate(orderPageVO, vehicleItemDTO, freeDays, baseOrderBiz.getDaysBetweenDateTime(startTime, nowTime), new OrderAccountDetail(), Boolean.FALSE);
                            //.inProgressCalculate(orderPageVO, baseOrderBiz.getDaysBetweenDateTime(startTime, nowTime));
                    totalDeductAmount = oad.realTotalDeduct();
                    totalRefundAmount = oad.getOrderAmount().add(oad.getDepositAmount());
                    refundDesc = inProgressVO.getViolateDesc();
                }else {

                    String key = RENT_REFUND;

                    BigDecimal deductionAmount = orderAccountBiz.calculateDeduction(vehicleItemDTO.getBuyAmount()
                            , orderPageVO.getOrderRentVehicleDetail().getStartTime() - System.currentTimeMillis()
                            , DictionaryKey.APP_ORDER+ "_"+ key
                            , refundDescBuilder);

                    totalDeductAmount = deductionAmount;
                    totalRefundAmount = orderPageVO.getRealAmount().subtract(deductionAmount);
                    refundDesc = refundDescBuilder.toString();
                }

                break;
            case TOUR:
                //判断是省内还是省外
                String key = TOUR_IN_REFUND;
                if(SYS_TRUE.equals(orderPageVO.getOrderTourDetail().getIsOutside())) {
                    key = TOUR_REFUND;
                }

                OrderItem adultItem = orderItemBiz.selectOne(new OrderItem(){{
                    setType(ItemTypeEnum.TOUR_ADULT.getCode());
                    setOrderId(orderPageVO.getId());
                }});

                OrderItem childItem = orderItemBiz.selectOne(new OrderItem(){{
                    setType(ItemTypeEnum.TOUR_CHILD.getCode());
                    setOrderId(orderPageVO.getId());
                }});

                BigDecimal adultItemAmount = (null == adultItem)? BigDecimal.ZERO: adultItem.getRealAmount();
                BigDecimal childItemAmount = (null == childItem)? BigDecimal.ZERO: childItem.getRealAmount();

                BigDecimal deductionAmount = orderAccountBiz.calculateDeduction(adultItemAmount.add(childItemAmount)
                        , orderPageVO.getOrderTourDetail().getStartTime() - System.currentTimeMillis()
                        , DictionaryKey.APP_ORDER+ "_"+ key
                        , refundDescBuilder);

                totalDeductAmount = deductionAmount;
                totalRefundAmount = orderPageVO.getRealAmount().subtract(deductionAmount);
                refundDesc = refundDescBuilder.toString();
                break;
            default:
                break;
        }

        OrderRefundPriceVO orpv = new OrderRefundPriceVO();
        orpv.setRealAmount(orderPageVO.getRealAmount());
        orpv.setRefundAmount(totalRefundAmount);
        if(orderPageVO.getStatus().equals(OrderStatusEnum.ORDER_UNPAY.getCode())
                || orderPageVO.getStatus().equals(OrderStatusEnum.ORDER_CRT.getCode())
                || totalDeductAmount.compareTo(BigDecimal.ZERO) <= 0) {
            orpv.setRefundDesc("是否确定取消订单");
        }else {
            orpv.setRefundDesc(StrUtil.format("本次取消操作需要扣除{}元违约金，实际退款金额为{}元，您确定要取消订单吗？", totalDeductAmount, totalRefundAmount));
        }
        return ObjectRestResponse.succ(orpv);
    }

    @Data
    public class OrderRefundPriceVO {
        BigDecimal refundAmount;
        BigDecimal realAmount;
        BigDecimal cutAmount;
        String refundDesc;

        public void setRefundAmount(BigDecimal refundAmount) {
            this.refundAmount = refundAmount;
            this.cutAmount = realAmount.subtract(refundAmount);
        }
    }
}