package com.xxfc.platform.order.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import com.github.wxiaoqi.security.admin.constant.enumerate.MemberEnum;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.AppUserDTO;
import com.github.wxiaoqi.security.common.context.BaseContextHandler;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.xxfc.platform.order.biz.OrderCostDetailBiz;
import com.xxfc.platform.order.biz.OrderRentVehicleBiz;
import com.xxfc.platform.order.biz.OrderTemplateBiz;
import com.xxfc.platform.order.contant.enumerate.OrderCostEnum;
import com.xxfc.platform.order.contant.enumerate.OrderStatusEnum;
import com.xxfc.platform.order.contant.enumerate.OrderTypeEnum;
import com.xxfc.platform.order.entity.OrderTemplate;
import com.xxfc.platform.order.pojo.order.RentVehicleBO;
import com.xxfc.platform.order.pojo.price.RentVehiclePriceVO;
import com.xxfc.platform.vehicle.entity.VehicleBookRecord;
import com.xxfc.platform.vehicle.entity.VehicleModel;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import com.xxfc.platform.vehicle.pojo.RentVehicleBookDTO;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.HashMap;

import static com.github.wxiaoqi.security.admin.constant.enumerate.MemberEnum.*;

@Service
@Log4j
public class OrderRentVehicleService extends AbstractOrderHandle<OrderRentVehicleBiz, RentVehicleBO> {

    private static BigDecimal DRIVER_PRICE = new BigDecimal("600.00");
    private static BigDecimal DAMAGE_SAFE = new BigDecimal("100.00"); //车损免赔
    private static Integer DRIVER_TYPE_COMPANY = 1;
    private static Integer DRIVER_TYPE_DAMAGE_SAFE = 1;
    private static Integer DISCOUNT_STATUS_NONE = 0;
    private static Integer DISCOUNT_STATUS_MEMBER = 1;
    private static Integer DISCOUNT_STATUS_FIXED = 2;

    @Autowired
    VehicleFeign vehicleFeign;

    @Autowired
    OrderCostDetailBiz orderCostDetailBiz;

    @Autowired
    OrderTemplateBiz orderTemplateBiz;

    @Autowired
    UserFeign userFeign;

    @PostConstruct
    public void init(){
        this.orderTypeEnum = OrderTypeEnum.RentVehicle;
    }


    @Override
    public void initDetail(RentVehicleBO bo) {
        super.initDetail(bo);
        VehicleModel vehicleModel = vehicleFeign.get(bo.getModelId()).getData();
        bo.setVehicleModel(vehicleModel);
    }

    @Override
    public void handleDetail(RentVehicleBO bo) {
        //获取可用车辆
        acquireVehicle(bo);
        //设置订单状态为3
        bo.getOrder().setStatus(OrderStatusEnum.ORDER_UNPAY.getCode());
        //设置订单图片
        bo.getOrder().setPicture(bo.getVehicleModel().getPicture());
        //设置订单名称
        bo.getOrder().setName(bo.getVehicleModel().getName());

        //扣减免费天数
        if(null != bo.getFreeDays() && bo.getFreeDays() > 0) {
            int result = userFeign.memberDays(bo.getAppUserDTO().getUserid(), bo.getFreeDays(), UserFeign.MEMBER_DAYS_LOCK);
            if(result < 0) {
                throw new BaseException(ResultCode.FAILED_CODE);
            }
        }

        super.handleDetail(bo);

        //发送定时取消订单(30分钟)
        rabbitProduct.sendDelayMessage(bo.getOrder(), 1000L * 60 * 30);
    }

    @Override
    public void handleCalculate(RentVehicleBO bo) {
        RentVehiclePriceVO rvpv = calculatePrice(bo);
        BeanUtil.copyProperties(rvpv, bo.getOrder());
        BeanUtil.copyProperties(rvpv, bo);
    }

    @Override
    public RentVehiclePriceVO calculatePrice(RentVehicleBO detail) {
        BigDecimal orderAmount = BigDecimal.ZERO;
        BigDecimal goodsAmount = BigDecimal.ZERO;
        BigDecimal vehicleAmount = BigDecimal.ZERO;
        BigDecimal driverAmount = BigDecimal.ZERO;
        BigDecimal damageSafeAmount = BigDecimal.ZERO;
        BigDecimal modelAmount = BigDecimal.ZERO;
        Integer vehicleDayNum = 0;
        Integer freeDayNum = 0;
        //当前用户
        AppUserDTO dto = detail.getAppUserDTO();

        //如果用户存在，并且为会员，并且车辆有优惠价
        if(null != dto && detail.getRentFreeDay() > 0 && dto.getRentFreeDays() > 0) {
            if(detail.getDayNum() > dto.getRentFreeDays()) {
                freeDayNum = dto.getRentFreeDays();
            }else {
                freeDayNum = detail.getDayNum();
            }
            vehicleDayNum = detail.getDayNum() - freeDayNum;
        }else {
            vehicleDayNum = detail.getDayNum();
        }

        //计算价格
            //计算车辆费用
        VehicleModel vehicleModel = vehicleFeign.get(detail.getModelId()).getData();

        //如果用户存在，并且为会员，并且车辆有优惠价
        if(null != dto && !NONE.equals(detail.getAppUserDTO()) && !DISCOUNT_STATUS_NONE.equals(vehicleModel.getRentDiscountStatus())) {
            String[] prices = vehicleModel.getRentDiscountPrice().split(",");
            switch (MemberEnum.getByCode(detail.getAppUserDTO().getIsMember())) {
                case NORMAL:
                    modelAmount = handleDiscount(vehicleModel, prices, NORMAL);
                    break;
                case GOLD:
                    modelAmount = handleDiscount(vehicleModel, prices, GOLD);
                    break;
                case DIAMOND:
                    modelAmount = handleDiscount(vehicleModel, prices, DIAMOND);
                    break;
            }
        }else {
            modelAmount = vehicleModel.getPrice();
        }
        vehicleAmount = vehicleAmount.add(modelAmount.multiply(BigDecimal.valueOf(vehicleDayNum)));
        if(DRIVER_TYPE_COMPANY.equals(detail.getDriverType())) {
            //计算司机费用
            driverAmount = driverAmount.add(DRIVER_PRICE.multiply(BigDecimal.valueOf(detail.getDayNum())));
        }

        if(DRIVER_TYPE_DAMAGE_SAFE.equals(detail.getDamageSafe())) {
            //免赔费用
            damageSafeAmount = damageSafeAmount.add(DAMAGE_SAFE.multiply(BigDecimal.valueOf(detail.getDayNum())));
        }

            //商品价格
        goodsAmount = goodsAmount.add(vehicleAmount).add(driverAmount);
            //总价格（包含押金）
        orderAmount = orderAmount.add(goodsAmount).add(vehicleModel.getDeposit());

        //生成订单明细
        RentVehiclePriceVO rvp = new RentVehiclePriceVO();
        rvp.setOrderAmount(orderAmount);
        rvp.setGoodsAmount(goodsAmount);
        rvp.setDriverAmount(driverAmount);
        rvp.setVehicleAmount(vehicleAmount);
        rvp.setDamageSafeAmount(damageSafeAmount);
        rvp.setRealAmount(orderAmount);
        rvp.setDeposit(vehicleModel.getDeposit());
        rvp.setModelAmount(modelAmount);
        rvp.setDriverPrice(DRIVER_PRICE);
        rvp.setDamageSafePrice(DAMAGE_SAFE);
        rvp.setModelName(vehicleModel.getName());
        rvp.setDayNum(detail.getDayNum());
        rvp.setVehicleDayNum(vehicleDayNum);
        rvp.setVehicleNum(1);
        rvp.setDriverNum(1);

        //设置收费明细
        costDetail(rvp, handlechildren(detail, vehicleDayNum));
        return rvp;
    }

    /**
     * 获取会员比例或者会员价
     * @param vehicleModel
     * @param prices
     * @param memberEnum
     * @return
     */
    private BigDecimal handleDiscount(VehicleModel vehicleModel, String[] prices, MemberEnum memberEnum) {
        BigDecimal modelAmount;//会员比例
        if(DISCOUNT_STATUS_MEMBER.equals(vehicleModel.getRentDiscountStatus())) {
            modelAmount = new BigDecimal(String.valueOf((memberEnum.getPercent()/100))).multiply(vehicleModel.getPrice());
        }else {
            //会员固定价列表
            modelAmount = new BigDecimal(prices[(memberEnum.getCode() - 1)]);
        }
        return modelAmount;
    }

    private String handlechildren(RentVehicleBO detail, Integer vehicleDayNum) {
        StringBuffer childrenStr = new StringBuffer("");
        if(vehicleDayNum > 0) {
            childrenStr.append(",${tem_0101}");
        }
        if(DRIVER_TYPE_COMPANY.equals(detail.getDriverType())) {
            childrenStr.append(",${tem_0102}");
        }
        childrenStr.append(",${tem_0103}");
        if(DRIVER_TYPE_DAMAGE_SAFE.equals(detail.getDamageSafe())) {
            childrenStr.append(",${tem_0104}");
        }
        if(childrenStr.length() > 0){
            childrenStr.deleteCharAt(1);
        }
        return childrenStr.toString();
    }

    /**
     * 计算费用明细
     * @param vo
     * @return
     */
    private void costDetail(RentVehiclePriceVO vo, String children) {
        OrderTemplate template = orderTemplateBiz.selectById(OrderCostEnum.RentVehicle.getCode());
        template.setTemplate(orderTemplateBiz.result(template.getTemplate(), new HashMap(){{
            put("children", children);
        }}));
        String result = orderTemplateBiz.result(template, Dict.parse(vo));
        vo.setCostDetail(result);
    }

    private void acquireVehicle(RentVehicleBO detail) {
        //根据车型、时间、距离，门店，预定车辆
        RentVehicleBookDTO rentVehicleBookDTO = BeanUtil.toBean(detail.getBookVehicleVO(), RentVehicleBookDTO.class);
        rentVehicleBookDTO.setUserName(BaseContextHandler.getName());
        ObjectRestResponse<VehicleBookRecord> orr = vehicleFeign.rentApplyVehicle(rentVehicleBookDTO);
        detail.setVehicleId(orr.getData().getVehicleId());
        detail.setBookRecordId(orr.getData().getId());
    }
}
