package com.xxfc.platform.order.biz;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.admin.entity.AppUserDetail;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.AppUserDTO;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
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.activity.user.UserInfoBiz;
import com.xxfc.platform.order.contant.enumerate.CrosstownTypeEnum;
import com.xxfc.platform.order.contant.enumerate.DepositRefundStatus;
import com.xxfc.platform.order.contant.enumerate.OrderStatusEnum;
import com.xxfc.platform.order.entity.*;
import com.xxfc.platform.order.mapper.OrderVehicaleCrosstownMapper;
import com.xxfc.platform.order.pojo.mq.OrderMQDTO;
import com.xxfc.platform.order.pojo.order.OrderPageVO;
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.common.RestResponse;
import com.xxfc.platform.vehicle.constant.ResCode.ResCode;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import com.xxfc.platform.vehicle.pojo.CompanyDetail;
import com.xxfc.platform.vehicle.pojo.VehicleArrivalVo;
import com.xxfc.platform.vehicle.pojo.VehicleDepartureVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
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.List;
import java.util.Map;
import java.util.TimeZone;

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

@Service
@Slf4j
public class OrderVehicleCrosstownBiz extends BaseBiz<OrderVehicaleCrosstownMapper, OrderVehicleCrosstown> {

    @Autowired
    OrderVehicleCrosstownBiz orderVehicleCrosstownBiz;

    @Autowired
    OrderUserLicenseBiz orderUserLicenseBiz;
    @Autowired
    ThirdFeign thirdFeign;
    @Autowired
    UserInfoBiz userInfoBiz;
    @Autowired
    VehicleFeign vehicleFeign;
    @Autowired
    UserFeign userFeign;
    @Autowired
    private OrderRentVehicleBiz orderRentVehicleBiz;

    @Autowired
    private OrderDepositRefundRecordBiz orderDepositRefundRecordBiz;

    @Autowired
    BaseOrderBiz baseOrderBiz;

    public OrderVehicleCrosstown get(Integer id) {
        return selectById(id);
    }

    public List<OrderVehicleCrosstownDto> selectByOrderId(OrderVehicleCrosstownDto orderVehicleCrosstownDto) {

        List<OrderVehicleCrosstownDto> list = mapper.selectByOrderId(orderVehicleCrosstownDto);
        for (OrderVehicleCrosstownDto value : list) {
            if(value != null && value.getOrperaterId() != null && value.getType() != 1) {
                UserDTO userDTO = userFeign.userinfoByUid(value.getOrperaterId()).getData();
                if(userDTO != null) {
                    CompanyDetail branchCompany = vehicleFeign.getCompanyDetail(userDTO.getCompanyId()).getData();
                    if(branchCompany != null) {
                        value.setCustomerPhone(branchCompany.getVehiceServicePhone());
                    }
                }
            }
            updateCrossRecord(value);
            List<DepositRefundRecord> depositRefundRecords = orderDepositRefundRecordBiz.selectByCrossId(value.getId());
            value.setDepositRefundRecord(depositRefundRecords == null || depositRefundRecords.size() <= 0 ? null : depositRefundRecords);
        }
        return list;
    }

    public OrderVehicleCrosstownDto getByOrderId(OrderVehicleCrosstownDto orderVehicleCrosstownDto) {
        List<OrderVehicleCrosstownDto> list = mapper.selectByOrderId(orderVehicleCrosstownDto);
        return list != null && list.size() > 0 ? list.get(0) : null;
    }

    public void updateCrossRecord(OrderVehicleCrosstownDto value) {
        if (value.getOrperaterId() != null) {
            ObjectRestResponse<AppUserDTO> objectRestResponse = userFeign.userDetailById(value.getOrperaterId());
            if (objectRestResponse.getData() != null) {
                value.setUsername(objectRestResponse.getData().getNickname());
            }
        }
        if (value.getUserLicenseId() != null) {
            List<OrderUserLicense> orderUserLicenses = orderUserLicenseBiz.selectByIds(value.getUserLicenseId()).getData();
            if (orderUserLicenses != null && orderUserLicenses.size() > 0) {
                value.setLicenseIdCard(orderUserLicenses.get(0).getLicenseIdCard());
                value.setLicenseImg(orderUserLicenses.get(0).getLicenseImg());
                value.setLicenseName(orderUserLicenses.get(0).getLicenseName());
                value.setLicensePhone(orderUserLicenses.get(0).getLicensePhone());
            }
        }
    }


    public ObjectRestResponse selectByOrderNo(String no) {
        ObjectRestResponse<OrderPageVO> objectRestResponse = baseOrderBiz.getOrderDetail(no);
        if (objectRestResponse.getData() == null) {
            return ObjectRestResponse.createFailedResult(2379, "订单不存在");
        }
        OrderPageVO orderPageVO = objectRestResponse.getData();
        Map<String, Object> map = new HashedMap<>();
        if (orderPageVO.getStatus() == OrderStatusEnum.ORDER_FINISH.getCode()) {//订单已完成
            map.put("no", orderPageVO.getNo());
            map.put("type", CrosstownTypeEnum.ARRIVE.getCode());
        } else if (orderPageVO.getStatus() == OrderStatusEnum.ORDER_FIXED_LOSS.getCode()) {//订单定损中
            map.put("no", orderPageVO.getNo());
            map.put("type", CrosstownTypeEnum.FIXED_LOSS.getCode());
        } else if (orderPageVO.getStatus() == OrderStatusEnum.ORDER_WAIT.getCode()) {//订单出行中
            map.put("no", orderPageVO.getNo());
            map.put("type", CrosstownTypeEnum.DEPARTURE.getCode());
        } else {
            return ObjectRestResponse.succ();
        }
        OrderVehicleCrosstownDto orderVehicleCrosstownDto = mapper.selectByOrderNo(map);
        updateCrossRecord(orderVehicleCrosstownDto);
        List<DepositRefundRecord> list = orderDepositRefundRecordBiz.selectByCrossId(orderVehicleCrosstownDto.getId());
        orderVehicleCrosstownDto.setDepositRefundRecord(list == null || list.size() <= 0 ? null : list);
        return ObjectRestResponse.succ(orderVehicleCrosstownDto);
    }


    @Transactional(rollbackFor = Exception.class)
    public ObjectRestResponse<OrderVehicleCrosstownDto> add(OrderVehicleCrosstownDto orderVehicleCrosstownDto) {
        log.info("添加的参数：orderVehicaleCrosstown = {}", orderVehicleCrosstownDto);
        UserDTO userDTO = userInfoBiz.getAdminUserInfo();
        if (userDTO == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.RSTOKEN_EXPIRED_CODE, "token is null or invalid");
        }
        if (orderVehicleCrosstownDto == null || orderVehicleCrosstownDto.getOrderId() == null) {
            return ObjectRestResponse.paramIsEmpty();
        }
        orderVehicleCrosstownDto.setOrperaterId(userDTO.getId());
        BaseOrder baseOrder = baseOrderBiz.selectById(orderVehicleCrosstownDto.getOrderId());
        if (baseOrder == null) {
            return ObjectRestResponse.createFailedResult(ResCode.ORDER_IS_NOT_EXIST.getCode(), ResCode.ORDER_IS_NOT_EXIST.getDesc());
        }

        OrderRentVehicleDetail orderRentVehicleDetail = orderRentVehicleBiz.selectById(baseOrder.getDetailId());
       if(orderVehicleCrosstownDto.getType() == CrosstownTypeEnum.DEPARTURE.getCode()) {
           boolean flag = getTodayTime(orderRentVehicleDetail.getEndTime());
           if (!flag) {
               return ObjectRestResponse.createFailedResult(3502, "今日不是交车日期");
           }
           if(userDTO.getCompanyId() != orderRentVehicleDetail.getStartCompanyId()) {
               return ObjectRestResponse.createFailedResult(3501, "无交车权限");
           }
       } else {
           if(userDTO.getCompanyId() != orderRentVehicleDetail.getEndCompanyId()) {
               return ObjectRestResponse.createFailedResult(3503, "无收车权限");
           }
       }
        if(baseOrder.getStatus() != -1) {
            Vehicle vehicle = null;
            RestResponse<Vehicle> restResponse = vehicleFeign.findById(orderRentVehicleDetail.getVehicleId());
            log.info("获取车辆信息返回消息：{}", restResponse.getMessage());
            if (restResponse.getData() != null) {
                vehicle = restResponse.getData();
            }
            if (vehicle == null) {
                return ObjectRestResponse.createFailedResult(ResCode.VEHICLE_DEPARTURE_VEHICLE_UNEXIST.getCode(), ResCode.VEHICLE_DEPARTURE_VEHICLE_UNEXIST.getDesc());
            }
                if( vehicle.getMileageLastUpdate() != null) {
                    //判断车辆公里数
                    if (orderVehicleCrosstownDto.getMileage() == null || orderVehicleCrosstownDto.getMileage() <= vehicle.getMileageLastUpdate()) {
                        return ObjectRestResponse.createFailedResult(ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getCode(), ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getDesc());
                    }
                }

        }
        AppUserDTO appUserDTO = userFeign.userDetailById(baseOrder.getUserId()).getData();
        //调用车辆管理的出车还车
        //出车
        if (orderVehicleCrosstownDto.getType() == CrosstownTypeEnum.DEPARTURE.getCode()) { //交车

            VehicleDepartureVo vehicleDepartureVo = new VehicleDepartureVo();
            vehicleDepartureVo.setVehicleId(orderRentVehicleDetail.getVehicleId());
            vehicleDepartureVo.setDepartureBranchCompanyId(orderRentVehicleDetail.getStartCompanyId());
            vehicleDepartureVo.setExpectArrivalBranchCompanyId(orderRentVehicleDetail.getEndCompanyId());
            vehicleDepartureVo.setMileage(orderVehicleCrosstownDto.getMileage());
           if(appUserDTO != null) {
               vehicleDepartureVo.setUser(appUserDTO.getNickname());
               vehicleDepartureVo.setUserTel(appUserDTO.getUsername());
           } else {
               vehicleDepartureVo.setUser("APP用戶");
               vehicleDepartureVo.setUserTel("13656235623");
           }
            vehicleDepartureVo.setUse("用户租车");
            vehicleDepartureVo.setBookRecordId(orderRentVehicleDetail.getBookRecordId());
            vehicleDepartureVo.setCheckMan(orderVehicleCrosstownDto.getLicenseName());
            vehicleDepartureVo.setCheckManTel(orderVehicleCrosstownDto.getLicensePhone());
            try {
                RestResponse restResponse = vehicleFeign.departureBySmall(vehicleDepartureVo);
                log.info("返回信息： " + restResponse);
            } catch (Exception e) {
                e.printStackTrace();
                return ObjectRestResponse.createFailedResult(1001, e.getMessage());
            }
        } else if (orderVehicleCrosstownDto.getType() == CrosstownTypeEnum.ARRIVE.getCode() || orderVehicleCrosstownDto.getType() == CrosstownTypeEnum.FIXED_LOSS.getCode()) { //还车
            VehicleArrivalVo vehicleArrivalVo = new VehicleArrivalVo();
            vehicleArrivalVo.setVehicleId(orderRentVehicleDetail.getVehicleId());
            vehicleArrivalVo.setArrivalBranchCompanyId(userDTO.getCompanyId());
            vehicleArrivalVo.setMileage(orderVehicleCrosstownDto.getMileage());
            vehicleArrivalVo.setRecycleMan(userDTO.getName());
            vehicleArrivalVo.setBookRecordId(orderRentVehicleDetail.getBookRecordId());
            if(appUserDTO != null) {
                vehicleArrivalVo.setRecycleManTel(appUserDTO.getUsername());
            } else {
                vehicleArrivalVo.setRecycleManTel("13565235623");
            }
            try {
                vehicleFeign.arrivalBySmall(vehicleArrivalVo);
            } catch (Exception e) {
                e.printStackTrace();
                return ObjectRestResponse.createFailedResult(500, e.getMessage());
            }
        }
        Double cost = 0.0;
        if (StringUtils.isNotBlank(orderVehicleCrosstownDto.getDedDetail())) {
            JSONArray jsonArray = JSONArray.parseArray(orderVehicleCrosstownDto.getDedDetail());
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = JSONObject.parseObject(jsonArray.get(i).toString());
                if(jsonObject!= null) {
                    cost += Double.parseDouble(jsonObject.getString("cost"));
                }
            }
        }
        BigDecimal amount =  new BigDecimal(cost.toString()).divide(new BigDecimal("1"), 2, BigDecimal.ROUND_UP);
        orderVehicleCrosstownDto.setDeductionCost(amount);
       //扣除费用
        orderVehicleCrosstownDto.setRestDeposit(orderRentVehicleDetail.getDeposit().subtract(amount));
        if(orderVehicleCrosstownDto.getRestDeposit().compareTo(getAmount()) == -1) { //剩余金额小于保证金
            return ObjectRestResponse.createFailedResult(500,"押金不足，不能交车，请联系客服！");
        }
        //出车成功后修改订单状态
        List<OrderVehicleCrosstownDto> oldValue = orderVehicleCrosstownBiz.selectByOrderId(orderVehicleCrosstownDto);
        if (oldValue.size() == 1) {
            BeanUtil.copyProperties(orderVehicleCrosstownDto, oldValue.get(0), CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            getOrderLicense(orderVehicleCrosstownDto);
            handleOrderStatus(baseOrder, orderRentVehicleDetail, oldValue.get(0));
            updateSelectiveByIdRe(oldValue.get(0));
            RestResponse<Vehicle> response = vehicleFeign.findById(orderRentVehicleDetail.getVehicleId());
            if (response.getData() != null) {
                orderVehicleCrosstownDto.setVehicleNumberPlat(response.getData().getNumberPlate());
            }
            return ObjectRestResponse.succ(oldValue.get(0));
        } else if (oldValue.size() <= 0) {
            getOrderLicense(orderVehicleCrosstownDto);
            orderVehicleCrosstownBiz.insertSelective(orderVehicleCrosstownDto);
            OrderVehicleCrosstown orderVehicleCrosstown = orderVehicleCrosstownBiz.selectOne(orderVehicleCrosstownDto);
            handleOrderStatus(baseOrder, orderRentVehicleDetail, orderVehicleCrosstown);
            RestResponse<Vehicle> response = vehicleFeign.findById(orderRentVehicleDetail.getVehicleId());
            if (response.getData() != null) {
                orderVehicleCrosstownDto.setVehicleNumberPlat(response.getData().getNumberPlate());
            }
            return ObjectRestResponse.succ(orderVehicleCrosstownDto);
        }
        return ObjectRestResponse.createDefaultFail();
    }

    private void handleOrderStatus(BaseOrder baseOrder, OrderRentVehicleDetail orderRentVehicleDetail, OrderVehicleCrosstown orderVehicleCrosstown) {
        //交车完成 设置订单状态为出行中
        BigDecimal totalAmount = new BigDecimal(0);
        ObjectRestResponse<OrderPageVO> objectRestResponse = baseOrderBiz.getOrderDetail(baseOrder.getNo());
        if (objectRestResponse.getData() != null && objectRestResponse.getData().getOrderRentVehicleDetail() != null) {
            //总押金-保留金
            totalAmount = objectRestResponse.getData().getOrderRentVehicleDetail().getDeposit();
        }

        if (baseOrder.getStatus() == OrderStatusEnum.ORDER_TOSTART.getCode()) {//交车
            baseOrder.setStatus(OrderStatusEnum.ORDER_WAIT.getCode());
            baseOrder = baseOrderBiz.updateSelectiveByIdReT(baseOrder);
        } else if (baseOrder.getStatus() == OrderStatusEnum.ORDER_WAIT.getCode()) { //还车
            if (orderVehicleCrosstown.getType() == CrosstownTypeEnum.ARRIVE.getCode()) {//不定损直接还车
                //添加非定损记录
                DepositRefundRecord depositRefundRecord = new DepositRefundRecord();
                depositRefundRecord.setAmount(orderVehicleCrosstown.getDeductionCost());
                depositRefundRecord.setRestAmount(totalAmount.subtract(getAmount()).subtract(orderVehicleCrosstown.getDeductionCost()));
                depositRefundRecord.setTotalAmount(totalAmount.subtract(getAmount()));
                depositRefundRecord.setCrosstownId(orderVehicleCrosstown.getId());
                orderDepositRefundRecordBiz.saveNormalRecord(depositRefundRecord);
               //修改订单状态为已完成
                baseOrder.setStatus(OrderStatusEnum.ORDER_FINISH.getCode());
                baseOrder = baseOrderBiz.updateSelectiveByIdReT(baseOrder);
                //修改订单详情是否押金全部退还
                orderRentVehicleDetail.setFixedLossStatus(0);
                orderRentVehicleBiz.updateSelectiveByIdRe(orderRentVehicleDetail);
                baseOrderBiz.sendOrderMq(orderRentVehicleDetail, null, null, baseOrder, OrderMQDTO.ORDER_FINISH);
            } else if (orderVehicleCrosstown.getType() == CrosstownTypeEnum.FIXED_LOSS.getCode()) { //定损还车，添加定损记录
                //添加定损记录
                DepositRefundRecord depositRefundRecord = new DepositRefundRecord();
                depositRefundRecord.setAmount(orderVehicleCrosstown.getDeductionCost());
                depositRefundRecord.setRestAmount(totalAmount.subtract(getAmount()).subtract(orderVehicleCrosstown.getDeductionCost()));
                depositRefundRecord.setTotalAmount(totalAmount.subtract(getAmount()));
                depositRefundRecord.setCrosstownId(orderVehicleCrosstown.getId());
                orderDepositRefundRecordBiz.saveFixLossRecord(depositRefundRecord);
                //修改訂單狀態為定損
                baseOrder.setStatus(OrderStatusEnum.ORDER_FIXED_LOSS.getCode());
                baseOrderBiz.updateSelectiveByIdReT(baseOrder);
                orderRentVehicleDetail.setFixedLossStatus(1);
                orderRentVehicleBiz.updateSelectiveByIdRe(orderRentVehicleDetail);
            }
        } else if (baseOrder.getStatus() == OrderStatusEnum.ORDER_FIXED_LOSS.getCode()) {//定损后还车
            DepositRefundRecord depositRefundRecord = orderDepositRefundRecordBiz.findByCrossIdAndStatus(orderVehicleCrosstown.getId(), DepositRefundStatus.FIXLOSSREFUND.getCode());
            if (depositRefundRecord != null) {
                DepositRefundRecord newValue = new DepositRefundRecord();
                BeanUtil.copyProperties(depositRefundRecord, newValue, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
                depositRefundRecord.setIsshow(false);
                orderDepositRefundRecordBiz.updateSelectiveByIdRe(depositRefundRecord);
                newValue.setIscomplete(true); //发起退款显示
                newValue.setAmount(orderVehicleCrosstown.getDeductionCost());
                newValue.setRestAmount(totalAmount.subtract(getAmount()).subtract(orderVehicleCrosstown.getDeductionCost()));
                newValue.setTotalAmount(totalAmount.subtract(getAmount()));
                newValue.setCrosstownId(orderVehicleCrosstown.getId());
                newValue.setId(null);
                orderDepositRefundRecordBiz.save(newValue);
                DepositRefundRecord nextValue = orderDepositRefundRecordBiz.findByCrossIdAndStatus(orderVehicleCrosstown.getId(), DepositRefundStatus.FIXLOSSREFUNDARRIVAL.getCode());
                if(nextValue != null) {
                    nextValue.setRestAmount(newValue.getRestAmount());
                    orderDepositRefundRecordBiz.update(nextValue);
                }
            } else {
                throw new BaseException("定损记录不存在！请联系客服");
            }
            baseOrder.setStatus(OrderStatusEnum.ORDER_FINISH.getCode());
            baseOrder = baseOrderBiz.updateSelectiveByIdReT(baseOrder);
            baseOrderBiz.sendOrderMq(orderRentVehicleDetail, null, null, baseOrder, OrderMQDTO.ORDER_FINISH);
        }
    }

    public void getOrderLicense(OrderVehicleCrosstownDto orderVehicleCrosstownDto) {
        if (StringUtils.isNotBlank(orderVehicleCrosstownDto.getLicenseIdCard())) {
            OrderUserLicense orderUserLicense = new OrderUserLicense();
            orderUserLicense.setLicenseIdCard(orderVehicleCrosstownDto.getLicenseIdCard());
            orderUserLicense.setLicenseImg(orderVehicleCrosstownDto.getLicenseImg());
            orderUserLicense.setLicenseName(orderVehicleCrosstownDto.getLicenseName());
            orderUserLicense.setLicensePhone(orderVehicleCrosstownDto.getLicensePhone());
            if (orderUserLicense != null) {
                Integer id = orderUserLicenseBiz.add(orderUserLicense).getData().getId();
                orderVehicleCrosstownDto.setUserLicenseId(id + "");
            }
        }
    }

    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 boolean getTodayTime(Long time) {
        long current = System.currentTimeMillis();
        if (current <= (time / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset() ) + 24 * 60 * 60 * 1000 -1) {
            return true;
        }
        return false;
    }
}
