package com.xxfc.platform.order.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
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.OrderCostDetail;
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.VehicleModel;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import com.xxfc.platform.vehicle.pojo.BookVehicleVO;
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.ArrayList;
import java.util.HashMap;
import java.util.List;

@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 BigDecimal DEPOSIT = new BigDecimal("20000.00");

    @Autowired
    VehicleFeign vehicleFeign;

    @Autowired
    OrderCostDetailBiz orderCostDetailBiz;

    @Autowired
    OrderTemplateBiz orderTemplateBiz;

    @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());

        super.handleDetail(bo);
    }

    @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;

        //计算价格
            //计算车辆费用
        VehicleModel vehicleModel = vehicleFeign.get(detail.getModelId()).getData();
        vehicleAmount = vehicleAmount.add(vehicleModel.getPrice().multiply(BigDecimal.valueOf(detail.getDayNum())));
        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(vehicleModel.getPrice());
        rvp.setDriverPrice(DRIVER_PRICE);
        rvp.setDamageSafePrice(DAMAGE_SAFE);
        rvp.setModelName(vehicleModel.getName());
        rvp.setDayNum(detail.getDayNum());
        rvp.setVehicleNum(1);
        rvp.setDriverNum(1);

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

    private String handlechildren(RentVehicleBO detail) {
        StringBuffer childrenStr = new StringBuffer("${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}");
        }
        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) {
        //根据车型、时间、距离，门店，预定车辆
        BookVehicleVO bookVehicleVO = detail.getBookVehicleVO();
        ObjectRestResponse<String> orr = vehicleFeign.rentApplyVehicle(bookVehicleVO);
        detail.setVehicleId(orr.getData());
    }
}
