package com.xxfc.platform.order.biz;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.xxfc.platform.order.contant.enumerate.CrosstownTypeEnum;
import com.xxfc.platform.order.contant.enumerate.DepositRefundStatus;
import com.xxfc.platform.order.entity.*;
import com.xxfc.platform.order.mapper.DepositRefundRecordMapper;
import com.xxfc.platform.order.pojo.order.OrderVehicleCrosstownDto;
import com.xxfc.platform.universal.constant.DictionaryKey;
import com.xxfc.platform.universal.entity.Dictionary;
import com.xxfc.platform.universal.feign.ThirdFeign;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

import static com.xxfc.platform.universal.constant.DictionaryKey.APP_ORDER;

@Service
@Slf4j
public class OrderDepositRefundRecordBiz extends BaseBiz<DepositRefundRecordMapper, DepositRefundRecord> {

    @Autowired
    ThirdFeign thirdFeign;
    @Autowired
    BaseOrderBiz baseOrderBiz;
    @Autowired
    OrderRentVehicleBiz orderRentVehicleBiz;
    @Autowired
    UserFeign userFeign;

    @Autowired
    VehicleFeign vehicleFeign;

    @Autowired
    OrderVehicleCrosstownBiz orderVehicleCrosstownBiz;

    @Autowired
    OrderViolationBiz orderViolationBiz;
    /**
     * 添加正常记录
     */
    @Transactional
    public void saveNormalRecord(DepositRefundRecord depositRefundRecord) {
        depositRefundRecord.setStatus(DepositRefundStatus.INITIATEREFUND.getCode());
        depositRefundRecord.setIscomplete(true);
        insertSelectiveRe(depositRefundRecord);
        depositRefundRecord.setStatus(DepositRefundStatus.REFUNDARRIVAL.getCode());
        depositRefundRecord.setIscomplete(false);
        insertSelectiveRe(depositRefundRecord);
        depositRefundRecord.setStatus(DepositRefundStatus.VIOLATIONARRIVAL.getCode());
        depositRefundRecord.setRestAmount(getAmount());
        insertSelectiveRe(depositRefundRecord);
    }

    /**
     * 添加定损记录
     * @param depositRefundRecord
     */
    @Transactional
    public void saveFixLossRecord(DepositRefundRecord depositRefundRecord) {
        depositRefundRecord.setStatus(DepositRefundStatus.FIXLOSS.getCode());
        depositRefundRecord.setIscomplete(true);
        insertSelectiveRe(depositRefundRecord);
        depositRefundRecord.setIscomplete(false);
        depositRefundRecord.setStatus(DepositRefundStatus.FIXLOSSREFUND.getCode());
        insertSelectiveRe(depositRefundRecord);
        depositRefundRecord.setStatus(DepositRefundStatus.FIXLOSSREFUNDARRIVAL.getCode());
        insertSelectiveRe(depositRefundRecord);
        depositRefundRecord.setStatus(DepositRefundStatus.VIOLATIONARRIVAL.getCode());
        depositRefundRecord.setRestAmount(getAmount());
        insertSelectiveRe(depositRefundRecord);
    }

    public DepositRefundRecord findByCrossIdAndStatus(Integer crossId, Integer status) {
        Map<String, Object> map = new HashMap<>();
        map.put("crossId", crossId);
        map.put("status", status);
        return mapper.findByCrossIdAndStatus(map);
    }

    public void update(DepositRefundRecord depositRefundRecord) {
        if(depositRefundRecord.getId() != null) {
            updateSelectiveByIdRe(depositRefundRecord);
        }
    }

    public void save(DepositRefundRecord depositRefundRecord) {
        mapper.insert(depositRefundRecord);
    }


    public List<DepositRefundRecord> selectByCrossId(Integer cross) {
        List<DepositRefundRecord> list = mapper.selectByCrossId(cross);
        for(DepositRefundRecord depositRefundRecord : list) {
            OrderVehicleCrosstown orderVehicleCrosstown = orderVehicleCrosstownBiz.selectById(depositRefundRecord.getCrosstownId());
            if(depositRefundRecord.getIscomplete() == true && depositRefundRecord.getStatus() == DepositRefundStatus.VIOLATIONARRIVAL.getCode()) {//查询违章记录
                if(orderVehicleCrosstown != null) {
                    BaseOrder baseOrder = baseOrderBiz.selectById(orderVehicleCrosstown.getOrderId());
                    if(baseOrder != null) {
                        OrderViolation orderViolation = orderViolationBiz.getOneByDetailId(baseOrder.getDetailId());
                        depositRefundRecord.setOrderViolation(orderViolation);
                    }
                }
            }
            if(depositRefundRecord.getStatus() == DepositRefundStatus.VIOLATIONARRIVAL.getCode()) {
                Map<String, Dictionary> dictionaryMap = thirdFeign.dictionaryGetAll4Map().getData();
                Integer rentDepositAutoRefundTime = new Integer(dictionaryMap.get(APP_ORDER+ "_"+ DictionaryKey.RENT_DEPOSIT_AUTO_REFUND_TIME).getDetail());
                depositRefundRecord.setRentDepositAutoRefundTime(depositRefundRecord.getCrtTime() + (rentDepositAutoRefundTime == null?0:rentDepositAutoRefundTime*60*60*1000));

            }
        }
        return list;
    }

    public void saveViolationDeposit(OrderViolation orderViolation) {
        log.info("添加违章押金记录：orderViolation = {}", orderViolation.toString());
        String logInfo = "";
        OrderRentVehicleDetail orderRentVehicleDetail = orderRentVehicleBiz.selectById(orderViolation.getDetailId());
        if(orderRentVehicleDetail != null) {
            OrderVehicleCrosstownDto orderVehicleCrosstown = new OrderVehicleCrosstownDto();
            orderVehicleCrosstown.setOrderId(orderRentVehicleDetail.getOrderId());
            orderVehicleCrosstown.setType(CrosstownTypeEnum.ARRIVE.getCode());
            OrderVehicleCrosstownDto orderVehicleCrosstownDto = orderVehicleCrosstownBiz.getByOrderId(orderVehicleCrosstown);
            if(orderVehicleCrosstownDto != null) {
                insertDeposit(orderVehicleCrosstownDto, orderViolation, logInfo);
            } else {
                orderVehicleCrosstown.setType(CrosstownTypeEnum.FIXED_LOSS.getCode());
                OrderVehicleCrosstownDto depositCross = orderVehicleCrosstownBiz.getByOrderId(orderVehicleCrosstown);
                insertDeposit(depositCross, orderViolation, logInfo);
                logInfo = "还车记录不存在";
            }
        } else {
            logInfo = "订单详情不存在";
        }
        log.info("添加违章押金记录失败：" + logInfo);
    }

    public BigDecimal getAmount() {
        //设置保留金
        Map<String, Dictionary> dictionaryMap = thirdFeign.dictionaryGetAll4Map().getData();
        BigDecimal illegalReserve = new BigDecimal(dictionaryMap.get(APP_ORDER + "_" + DictionaryKey.ILLEGAL_RESERVE).getDetail());
        return illegalReserve;
    }

    public void insertDeposit(OrderVehicleCrosstownDto orderVehicleCrosstownDto, OrderViolation orderViolation,  String logInfo) {
        DepositRefundRecord depositRefundRecord = findByCrossIdAndStatus(orderVehicleCrosstownDto.getId(), DepositRefundStatus.VIOLATIONARRIVAL.getCode());
        if(depositRefundRecord != null) {
            DepositRefundRecord newValue = new DepositRefundRecord();
            BeanUtil.copyProperties(depositRefundRecord, newValue, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            newValue.setAmount(orderViolation.getPrice());
            newValue.setRestAmount(depositRefundRecord.getTotalAmount().subtract(orderViolation.getPrice()));//减去违章金之后的押金
            newValue.setIscomplete(false);
            newValue.setId(null);
            mapper.insert(newValue);
            depositRefundRecord.setIsshow(false);
            updateSelectiveByIdRe(depositRefundRecord);
        } else {
            logInfo = "押金记录不存在";
        }
    }

    public void completeRecordStatus(Integer crosstownId, DepositRefundStatus depositRefundStatus) {
        DepositRefundRecord depositRefundRecord = findByCrossIdAndStatus(crosstownId, depositRefundStatus.getCode());
        depositRefundRecord.setIscomplete(Boolean.TRUE);
        updateSelectiveById(depositRefundRecord);
    }

}
