package cn.iocoder.yudao.module.rescue.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.CoordinateUtil;
import cn.hutool.http.HttpUtil;
import cn.iocoder.yudao.module.custom.entity.CustomerMain;
import cn.iocoder.yudao.module.custom.service.CustomerMainService;
import cn.iocoder.yudao.module.partner.entity.PartnerCustomerInfo;
import cn.iocoder.yudao.module.partner.service.IPartnerCustomerInfoService;
import cn.iocoder.yudao.module.rescue.domain.*;
import cn.iocoder.yudao.module.rescue.mapper.RescueDriverInfoMapper;
import cn.iocoder.yudao.module.rescue.utils.RedissonDelayQueue;
import cn.iocoder.yudao.module.shop.entity.ShopUserCar;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.rescue.service.*;
import cn.iocoder.yudao.module.rescue.utils.RedisUtil;
import cn.iocoder.yudao.module.rescue.utils.StringUtils;
import cn.iocoder.yudao.util.WechatPayConfig;
import cn.iocoder.yudao.util.WechatPayRequest;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static cn.hutool.core.util.CoordinateUtil.wgs84ToGcj02;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;


/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author ruoyi
 * @date 2023-07-18
 */
@Service
public class RescueDriverInfoServiceImpl extends ServiceImpl<RescueDriverInfoMapper, RescueDriverInfo>  implements IRescueDriverInfoService {
    @Autowired
    private AdminUserApi userService;
    @Autowired
    private IRescueInfoService rescueInfoService;
    @Autowired
    private RedisUtil redisCache;
    @Autowired
    private IDriverInfoService driverInfoService;
    @Autowired
    private IRescueInfoDetailService detailService;
    @Autowired
    private IRescueDriverPositionService positionService;
    @Autowired
    private DictDataApi dictDataService;
    @Autowired
    private IRescueOrderInfoService rescueOrderInfoService;
    @Autowired
    private IRescueOrderDetailService orderDetailService;
    @Autowired
    private IRescueCarInfoService carInfoService;
    @Autowired
    private IRescueRefuelRecordService refuelRecordService;
    @Resource
    private WechatPayRequest wechatPayRequest;
    @Autowired
    private WechatPayConfig wechatPayConfig;
    @Resource
    private RedissonDelayQueue redissonDelayQueue;
    @Autowired
    private IPartnerCustomerInfoService customerInfoService;
    @Resource
    private CustomerMainService customerMainService;

    public static String Redis_Driver_Key = "Rescue:Driver:";
    public static String Redis_Driver_Position_Key = "DriverPosition:";
    public static Map<String, Object> driverInfoMap = new HashMap<>();

    static {
        driverInfoMap.put("longitude", "0.00");
        driverInfoMap.put("latitude", "0.00");
        driverInfoMap.put("status", "1");
        driverInfoMap.put("positionInfo", "位置不详");
    }

    /**
     * 新增【司机】
     *
     * @param rescueDriverInfo 【司机】
     * @return 结果
     */
    @Override
    public int insertRescueDriverInfo(RescueDriverInfo rescueDriverInfo) {
        return baseMapper.insert(rescueDriverInfo);
//        return baseMapper.insertRescueDriverInfo(rescueDriverInfo);
    }

    @Override
    public DriverInfo driverInfoStatistics(Long driverId) {
        DriverInfo driverInfo = driverInfoService.getById(driverId);
        AdminUserRespDTO user = userService.getUser(driverInfo.getUserId());
        driverInfo.setRealName(user.getNickname());
        driverInfo.setAvatar(user.getAvatar());
        //待确认
        long count = baseMapper.dqrList(driverId);
        driverInfo.setDqrNum(count);
        //进行中
        LambdaQueryWrapper<RescueInfo> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(RescueInfo::getDriverId, driverId).eq(RescueInfo::getRescueStatus, "3");
        long count1 = rescueInfoService.count(queryWrapper1);
        driverInfo.setJxNum(count1);
        //已完成
        LambdaQueryWrapper<RescueInfo> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(RescueInfo::getDriverId, driverId).and(item -> {
            item.eq(RescueInfo::getRescueStatus, "5").or().eq(RescueInfo::getRescueStatus, "6");
        });
        long count2 = rescueInfoService.count(queryWrapper2);
        driverInfo.setWcNum(count2);
        return driverInfo;
    }

    //司机上线
    @Override
    public void topLine(Long driverId) {
        DriverInfo driverInfo = driverInfoService.getById(driverId);
        String redisKey = Redis_Driver_Key + driverInfo.getTenantId() + ":" + driverId;
        String status = "1";
        if (!redisCache.hasKey(redisKey)) {
            redisCache.setCacheMap(redisKey, driverInfoMap);
            //初始化
            //获取当前司机是否存在未结束的救援订单
            LambdaQueryWrapper<RescueInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RescueInfo::getDriverId, driverId).eq(RescueInfo::getRescueStatus, "3");
            long count = rescueInfoService.count(queryWrapper);
            if (count > 0) {
                redisCache.setCacheMapValue(redisKey, "status", "3");
                status = "3";
            }

        }

        LambdaUpdateWrapper<DriverInfo> wrapper = new LambdaUpdateWrapper();
        wrapper.eq(DriverInfo::getId, driverId).set(DriverInfo::getDriverStatus, status);
        driverInfoService.update(wrapper);
    }

    //下线
    @Override
    public void downLine(Long driverId) {
        DriverInfo driverInfo = driverInfoService.getById(driverId);
        String redisKey2 = Redis_Driver_Key + driverInfo.getTenantId() + ":" + driverId;
        if (redisCache.hasKey(redisKey2)) {
            Map<String, Object> cacheMap = redisCache.getCacheMap(redisKey2);
            driverInfo.setDriverStatus("4");
            driverInfo.setDriverLatitude(cacheMap.get("latitude").toString());
            driverInfo.setDriverLongitude(cacheMap.get("longitude").toString());
            driverInfo.setDriverPositionInfo(cacheMap.get("positionInfo").toString());
            driverInfo.setDriverStatus(cacheMap.get("status").toString());
        }
        driverInfoService.updateById(driverInfo);

    }

    @Override
    public String getStatus(Long driverId) {
        DriverInfo driverInfo = driverInfoService.getById(driverId);
        String driverStatus = driverInfo.getDriverStatus();
        if (driverStatus.equals("2")) {
            return "0";
        }
        return "1";
    }

    /**
     * {
     * *     longitude:124.11,
     * *     latitude:125.33,
     * *     positionInfo:"山东省济南市市中区八一立交桥"
     * * }
     *
     * @param driverId
     * @param positionInfo
     */
    @Override
    public void updatePosition(Long driverId, JSONObject positionInfo) {
        DriverInfo driverInfo = driverInfoService.getById(driverId);

        //经度
        Double longitudeTmp = positionInfo.getDouble("longitude");
        //纬度
        Double latitudeTmp = positionInfo.getDouble("latitude");
        //高度
        String height = positionInfo.getString("height");
        CoordinateUtil.Coordinate coordinate = wgs84ToGcj02(longitudeTmp, latitudeTmp);
        String longitude = String.valueOf(coordinate.getLng());
        String latitude = String.valueOf(coordinate.getLat());
        String[] split1 = longitude.split("\\.");
        if (split1[1].length() > 6) {
            longitude = split1[0] + "." + split1[1].substring(0, 6);
        }
        String[] split2 = latitude.split("\\.");
        if (split2[1].length() > 6) {
            latitude = split2[0] + "." + split2[1].substring(0, 6);
        }
        //详细位置
        String positionStr = "";
        try {
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("key", "b8131e88d6f74b26322c8c5ed0c4d71c");
            paramMap.put("location", longitude + "," + latitude);
            String s = HttpUtil.get("https://restapi.amap.com/v3/geocode/regeo?parameters", paramMap);
            JSONObject jsonObject = JSONObject.parseObject(s);
            positionStr = jsonObject.getJSONObject("regeocode").getString("formatted_address");
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        //先处理第一个结构 每个区域下司机的位置
        //省：市：区
        String redisKey = Redis_Driver_Position_Key + driverInfo.getTenantId();
        JSONObject data = new JSONObject();
        data.put("driverId", driverId);
        data.put("longitude", longitude);
        data.put("latitude", latitude);
        data.put("positionInfo", positionStr);
        //先得清空目前的
        redisCache.deleteCacheMapValue(redisKey, driverId.toString());
        redisCache.setCacheMapValue(redisKey, driverId.toString(), data);
        //在处理第二个数据结构
        String redisKey2 = Redis_Driver_Key + driverInfo.getTenantId() + ":" + driverId;
        if (redisCache.hasKey(redisKey2)) {
            redisCache.setCacheMapValue(redisKey2, "longitude", longitude);
            redisCache.setCacheMapValue(redisKey2, "latitude", latitude);
            redisCache.setCacheMapValue(redisKey2, "status", driverInfo.getDriverStatus());
            redisCache.setCacheMapValue(redisKey2, "positionInfo", positionStr);
        } else {
            Map<String, Object> driverInfoMap = new HashMap<>();
            driverInfoMap.put("longitude", longitude);
            driverInfoMap.put("latitude", latitude);
            driverInfoMap.put("status", driverInfo.getDriverStatus());
            driverInfoMap.put("positionInfo", positionStr);
            //初始化
            redisCache.setCacheMap(redisKey2, driverInfoMap);
        }
        Object temp = redisCache.getCacheMapValue(redisKey2, "rescueIds");
        if (ObjectUtils.isNotEmpty(temp)) {
            String[] rescueIds = temp.toString().split(",");
            for (String tmp : rescueIds) {
                //进行经纬度记录
                Long rescueId = Long.parseLong(tmp);
                RescueDriverPosition driverPosition = new RescueDriverPosition();
                driverPosition.setDriverId(driverId);
                driverPosition.setRescueInfoId(rescueId);
                driverPosition.setLongitude(longitude);
                driverPosition.setLatitude(latitude);
                driverPosition.setPositionInfo(positionStr);
                driverPosition.setHeight(height);
                positionService.save(driverPosition);
            }

        }


    }


    @Override
    public List<RescueInfo> driverRescueList(Long driverId) {
        List<RescueInfo> rescueInfos = baseMapper.driverRescueList(driverId);
        for (RescueInfo rescueInfo : rescueInfos) {
            String dljy_type = dictDataService.getDictDataLabel("dljy_type", rescueInfo.getRescueType());
            rescueInfo.setRescueTypeStr(dljy_type);
            String car_type = dictDataService.getDictDataLabel("rescue_car_type", rescueInfo.getCarType());
            rescueInfo.setCarTypeStr(car_type);
        }
        return rescueInfos;
    }

    @Override
    public List<RescueInfo> driverRescuePage(RescueInfo rescueInfo) {
        List<RescueInfo> rescueInfos = baseMapper.driverRescuePage(rescueInfo);
        for (RescueInfo it : rescueInfos) {
            String dljy_type = dictDataService.getDictDataLabel("dljy_type", it.getRescueType());
            it.setRescueTypeStr(dljy_type);
            String car_type = dictDataService.getDictDataLabel("rescue_car_type", it.getCarType());
            it.setCarTypeStr(car_type);
        }
        return rescueInfos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void driverAccept(Long rescueDriverId, String choose, String rejectReason) throws Exception {
        RescueDriverInfo rescueDriverInfo = this.getById(rescueDriverId);
        RescueInfo rescueInfo = rescueInfoService.selectRescueInfoById(rescueDriverInfo.getRescueId());
        AdminUserRespDTO user = userService.getUser(rescueInfo.getUserId());
        if (choose.equals("1")) {
            Lock lock = new ReentrantLock();
            lock.lock();
            try {
                if (!ObjectUtils.isEmpty(rescueInfo.getDriverId())) {
                    throw exception0(500, "订单已被抢走");
                }
                DriverInfo driverInfo = driverInfoService.getById(rescueDriverInfo.getDriverId());

                AdminUserRespDTO driverUser = userService.getUser(driverInfo.getUserId());
                Long deptId = driverInfo.getDeptId();
                //接受
                rescueDriverInfo.setDriverAccept("1");
                this.updateById(rescueDriverInfo);
                LambdaQueryWrapper<RescueCarInfo> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(RescueCarInfo::getPossessorId, driverInfo.getId());
                RescueCarInfo carInfo = carInfoService.getOne(queryWrapper1);
                if (ObjectUtils.isNotEmpty(carInfo)) {
                    rescueInfo.setDriverId(rescueDriverInfo.getDriverId());
                    rescueInfo.setDriverName(driverUser.getNickname());
                    rescueInfo.setDriverPhoneNum(driverInfo.getPhonenumber());
                    rescueInfo.setDriverCarNum(carInfo.getRescueCarNum());
                } else {
                    throw exception0(500,"请联系管理员维护车辆信息开始接单");
                }
                //状态修改为救援中
                rescueInfo.setRescueStatus("3");
                rescueInfoService.updateRescueInfo(rescueInfo);
                //处理别的司机的订单信息
                LambdaQueryWrapper<RescueDriverInfo> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(RescueDriverInfo::getRescueId, rescueDriverInfo.getRescueId()).ge(RescueDriverInfo::getDriverId, rescueDriverId);
                this.remove(queryWrapper);
                detailService.save(new RescueInfoDetail(rescueInfo.getId(), "0", "司机正在赶来路上", "司机正在赶来路上"));
                //再更新司机当前的订单状态
                //所在机构
                String redisKey = Redis_Driver_Key + deptId + ":" + driverInfo.getId();
                //订单开始
                RescueOrderInfo rescueOrderInfo = new RescueOrderInfo();
                rescueOrderInfo.setRescueInfoId(rescueInfo.getId());
                rescueOrderInfo.setOrderNo("appJy" + "-" + System.currentTimeMillis() + "-" + getRandomString6());
                rescueOrderInfo.setIsOnline("1");
                rescueOrderInfo.setOrderStatus("0");
                rescueOrderInfo.setOrderTime(new Date());
                rescueOrderInfo.setOrderType("jy");
                rescueOrderInfo.setPhonenumber(user.getMobile());
                rescueOrderInfo.setUserId(user.getId());
                rescueOrderInfo.setRealName(user.getNickname());
                if (rescueInfo.getFeeType().equals("2")) {
                    //签单
                    rescueOrderInfo.setPayType("qd");
                }
                rescueOrderInfoService.insertRescueOrderInfo(rescueOrderInfo);
                //增加司机接单次数
                Long rescueNum = Optional.ofNullable(driverInfo.getRescueNum()).orElse(0L);
                driverInfo.setRescueNum(++rescueNum);
                driverInfo.setDriverStatus("3");
                driverInfoService.updateById(driverInfo);
                if (redisCache.hasKey(redisKey)) {
                    String rescueIds = "";
                    Object tmp = redisCache.getCacheMapValue(redisKey, "rescueIds");
                    if (ObjectUtils.isNotEmpty(tmp)) {
                        rescueIds = tmp.toString() + "," + rescueInfo.getId();
                    } else {
                        rescueIds = rescueInfo.getId().toString();
                    }
                    redisCache.setCacheMapValue(redisKey, "rescueIds", rescueIds);
                    redisCache.setCacheMapValue(redisKey, "status", "3");
                } else {
                    JSONObject map = new JSONObject();
                    map.put("rescueIds", rescueInfo.getId());
                    redisCache.setCacheMap(redisKey, map);
                }

                // 删除定时任务
                redissonDelayQueue.removeAllTasks(rescueInfo.getId());
            } catch (Exception e) {
                log.error(e.getMessage());
                throw new Exception("出现异常");
            } finally {
                lock.unlock();
            }

        } else {
            //拒绝
            rescueDriverInfo.setDriverAccept("0");
            rescueDriverInfo.setDriverRejectReason(rejectReason);
            this.updateById(rescueDriverInfo);
//            //重新指派  暂时注释掉使用定时器进行处理
//            rescueInfoService.appointDriver(rescueInfo.getDeptId(),rescueInfo.getId(),rescueInfo.getRescueLongitude(),rescueInfo.getRescueLatitude());

        }

    }

    @Override
    public JSONObject rescueDetail(Long rescueId) {
        JSONObject res = new JSONObject();
        RescueInfo rescueInfo = rescueInfoService.getById(rescueId);
        String dljy_type = dictDataService.getDictDataLabel("dljy_type", rescueInfo.getRescueType());
        rescueInfo.setRescueTypeStr(dljy_type);
        String car_type = dictDataService.getDictDataLabel("rescue_car_type", rescueInfo.getCarType());
        rescueInfo.setCarTypeStr(car_type);
        String rescue_status = dictDataService.getDictDataLabel("jy_status", rescueInfo.getRescueStatus());
        rescueInfo.setRescueStatus(rescue_status);
        String feeStr = dictDataService.getDictDataLabel("fee_type", rescueInfo.getFeeType());
        rescueInfo.setFeeTypeStr(feeStr);
        if (StringUtils.isNotEmpty(rescueInfo.getRescueSceneImage())) {
            rescueInfo.setRescueSceneImageList(rescueInfo.getRescueSceneImage().split(","));
        }
        LambdaQueryWrapper<RescueInfoDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RescueInfoDetail::getRescueInfoId, rescueId).orderByAsc(TenantBaseDO::getCreateTime);
        List<RescueInfoDetail> list = detailService.list(queryWrapper);
        LambdaQueryWrapper<RescueOrderInfo> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(RescueOrderInfo::getRescueInfoId, rescueId);
        RescueOrderInfo orderInfo = rescueOrderInfoService.getOne(queryWrapper2);
        //为了避免微信通知不到的情况在此进行主动查询的功能
        if (null!=orderInfo && StringUtils.isNotEmpty(orderInfo.getOrderStatus()) && orderInfo.getOrderStatus().equals("1")) {
            try {
                //待支付的情况下进行主动查询
                String resStr = wechatPayRequest.wechatHttpGet("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + orderInfo.getOrderNo() + "?mchid=" + wechatPayConfig.getMchId());
                JSONObject payRes = JSONObject.parseObject(resStr);
                if (payRes.getString("trade_state").equals("SUCCESS")) {
                    //代表实际支付成功了
                    DriverInfo driverInfo = driverInfoService.getById(rescueInfo.getDriverId());
                    orderInfo.setPayTime(new Date());
                    orderInfo.setPayMoney(orderInfo.getSetMoney());
                    orderInfo.setValidationTime(new Date());
                    orderInfo.setValidationUserId(driverInfo.getUserId());
                    orderInfo.setValidationRealName(userService.getUser(driverInfo.getUserId()).getNickname());
                    orderInfo.setOrderStatus("2");
                    rescueOrderInfoService.updateById(orderInfo);
                    //追加订单明细记录
                    RescueOrderDetail detail = new RescueOrderDetail();
                    detail.setRescueOrderId(orderInfo.getId());
                    detail.setRecordMoney(orderInfo.getSetMoney());
                    detail.setRecordTime(new Date());
                    detail.setRecordType("1");
                    detail.setRescueDetailInfo("支付成功");
                    orderDetailService.save(detail);
                    //追加救援工单记录
                    Double s = Double.valueOf(orderInfo.getSetMoney()) / 100d;
                    detailService.save(new RescueInfoDetail(rescueInfo.getId(), "0", "用户支付完成", "用户支付费用：" + s));

                }
            } catch (Exception ignored) {

            }


        }
        if (ObjectUtils.isNotEmpty(orderInfo)) {
            rescueInfo.setSetMoney(orderInfo.getSetMoney());
            rescueInfo.setOrderStatus(orderInfo.getOrderStatus());
        }

        res.put("rescueInfo", rescueInfo);
        res.put("detailList", list);
        return res;
    }

    @Override
    public void uploadDetailByDriver(RescueInfoDetail rescueInfoDetail) throws Exception {
        //到达地点打卡
        String recordType = dictDataService.getDictDataLabel("rescue_driver_record_type", rescueInfoDetail.getType());
        rescueInfoDetail.setTitle(recordType);
        LambdaQueryWrapper<RescueInfoDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RescueInfoDetail::getRescueInfoId, rescueInfoDetail.getRescueInfoId()).eq(RescueInfoDetail::getType, rescueInfoDetail.getType());
        List<RescueInfoDetail> list = detailService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            throw new Exception("不可重复上传");
        }
        RescueInfo rescueInfo = rescueInfoService.getById(rescueInfoDetail.getRescueInfoId());

        try {
            RescueDriverPosition driverPosition = new RescueDriverPosition();
            driverPosition.setDriverId(rescueInfo.getDriverId());
            driverPosition.setRescueInfoId(rescueInfo.getId());
            //经度
            Double longitudeTmp = Double.parseDouble(rescueInfoDetail.getLng());
            //纬度
            Double latitudeTmp = Double.parseDouble(rescueInfoDetail.getLat());
            CoordinateUtil.Coordinate coordinate = wgs84ToGcj02(longitudeTmp, latitudeTmp);
            String longitude = String.valueOf(coordinate.getLng());
            String latitude = String.valueOf(coordinate.getLat());
            String[] split1 = longitude.split("\\.");
            if (split1[1].length() > 6) {
                longitude = split1[0] + "." + split1[1].substring(0, 6);
            }
            String[] split2 = latitude.split("\\.");
            if (split2[1].length() > 6) {
                latitude = split2[0] + "." + split2[1].substring(0, 6);
            }
            //详细位置
            String positionStr = "";

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("key", "b8131e88d6f74b26322c8c5ed0c4d71c");
            paramMap.put("location", longitude + "," + latitude);
            String s = HttpUtil.get("https://restapi.amap.com/v3/geocode/regeo?parameters", paramMap);
            JSONObject jsonObject = JSONObject.parseObject(s);
            positionStr = jsonObject.getJSONObject("regeocode").getString("formatted_address");
            driverPosition.setLongitude(longitude);
            driverPosition.setLatitude(latitude);
            driverPosition.setPositionInfo(positionStr);
            positionService.save(driverPosition);
            rescueInfoDetail.setPositionId(driverPosition.getId());
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        detailService.save(rescueInfoDetail);

    }

    @Override
    public void setOrderMoney(Long rescueId, Double setMoney) throws Exception {
        Double temp = setMoney * 100;
        long setMoneyRes = temp.longValue();
        LambdaQueryWrapper<RescueOrderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RescueOrderInfo::getRescueInfoId, rescueId);
        RescueOrderInfo one = rescueOrderInfoService.getOne(queryWrapper);
        if (Integer.parseInt(one.getOrderStatus()) > 1) {
            throw new Exception("订单已完结不可更改");
        }
        one.setSetMoney(setMoneyRes);
        one.setOrderStatus("1");
        rescueOrderInfoService.updateById(one);
        RescueInfoDetail rescueInfoDetail = new RescueInfoDetail();
        rescueInfoDetail.setRescueInfoId(rescueId);
        rescueInfoDetail.setTitle("费用核算");
        rescueInfoDetail.setRemark("司机核算救援费用为" + setMoney + "元");
        detailService.save(rescueInfoDetail);
        RescueOrderDetail rescueOrderDetail = new RescueOrderDetail();
        rescueOrderDetail.setRecordTime(new Date());
        rescueOrderDetail.setRecordMoney(setMoneyRes);
        rescueOrderDetail.setRecordType("1");
        rescueOrderDetail.setRescueOrderId(one.getId());
        rescueOrderDetail.setRescueDetailInfo("司机核定金额等待支付");
        orderDetailService.save(rescueOrderDetail);
    }

    @Override
    public void endRescue(Long rescueId) throws Exception {
        RescueInfo rescueInfo = rescueInfoService.getById(rescueId);
        //如果放空里数存在则不计入校验
        if (rescueInfo.getFeeType().equals("1") && (ObjectUtils.isEmpty(rescueInfo.getEmptyNum()) || rescueInfo.getEmptyNum() == 0d)) {
            LambdaQueryWrapper<RescueOrderInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RescueOrderInfo::getRescueInfoId, rescueId);
            RescueOrderInfo rescueOrderInfo = rescueOrderInfoService.getOne(queryWrapper);
            if (ObjectUtils.isEmpty(rescueOrderInfo.getPayTime())) {
                throw new Exception("尚未收费不可结束");
            }
        }
        boolean flag = true;
        //未上传图片不可完成
        LambdaQueryWrapper<RescueInfoDetail> detailLambdaQueryWrapper = new LambdaQueryWrapper<>();
        detailLambdaQueryWrapper.eq(RescueInfoDetail::getRescueInfoId, rescueId);
        List<RescueInfoDetail> details = detailService.list(detailLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(details)) {
            for (RescueInfoDetail detail : details) {
                if (StringUtils.isNotEmpty(detail.getImages())) {
                    flag = false;
                    break;
                }
            }
        }
        if (flag) {
            throw new Exception("尚未上传救援图片不可完成");
        }
        LambdaQueryWrapper<RescueDriverPosition> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(RescueDriverPosition::getRescueInfoId, rescueId).orderByDesc(TenantBaseDO::getCreateTime).last("limit 1");
        RescueDriverPosition position = positionService.getOne(queryWrapper2);
        RescueInfoDetail rescueInfoDetail = new RescueInfoDetail();
        rescueInfoDetail.setRescueInfoId(rescueId);
        rescueInfoDetail.setTitle("救援完成");
        rescueInfoDetail.setRemark("司机确定救援完成，并结束");
        if (ObjectUtils.isNotEmpty(position)) {
            rescueInfoDetail.setPositionId(position.getId());
        }
        detailService.save(rescueInfoDetail);
        rescueInfo.setRescueStatus("5");
        rescueInfoService.updateById(rescueInfo);
        //处理司机状态
        //查询司机是否还存在未结束的救援订单
        //处理redis
        DriverInfo driverInfo = driverInfoService.getById(rescueInfo.getDriverId());
        AdminUserRespDTO user = userService.getUser(driverInfo.getUserId());
        try{
            // 收集客户信息
            PartnerCustomerInfo customerInfo = new PartnerCustomerInfo();
            customerInfo.setCustomerName(rescueInfo.getConnectionName());
            customerInfo.setCustomerPhone(rescueInfo.getConnectionPhone());
            customerInfo.setUserId(rescueInfo.getUserId());

            // 收集客户车辆信息
            List<ShopUserCar> userCarList = new ArrayList<>();
            ShopUserCar userCar = new ShopUserCar();
            userCar.setCarNo(rescueInfo.getLicenseNum());
            userCar.setCarModel(rescueInfo.getCarType());
            userCar.setCarBrand(rescueInfo.getCarBrand());
            userCar.setUserId(user.getId());
            userCarList.add(userCar);

            customerInfo.setUserCarList(userCarList);

            // 设置客户来源
            CustomerMain customerMain = new CustomerMain();
            customerMain.setDataFrom("02");
            customerMainService.saveOrUpdate(customerMain);

            // 调用插入客户信息的方法
            customerInfoService.insertPartnerCustomerInfo(customerInfo);
        }catch (Exception ignored){

        }



        //所在顶级机构
        String redisKey = Redis_Driver_Key + driverInfo.getTenantId() + ":" + rescueInfo.getDriverId();
        Object temp = redisCache.getCacheMapValue(redisKey, "rescueIds");
        if (ObjectUtils.isNotEmpty(temp)) {
            String s = temp.toString();
            if (StringUtils.isNotEmpty(s)) {
                String resStr = "";
                 String[] rescueIds = temp.toString().split(",");
                for (String tmp : rescueIds) {
                    if (!tmp.equals(rescueId.toString())) {
                        resStr = resStr + "," + tmp;
                    }
                }
                redisCache.setCacheMapValue(redisKey, "rescueIds", resStr.substring(1));
            }
        }
        LambdaQueryWrapper<RescueInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RescueInfo::getDriverId, rescueInfo.getDriverId()).eq(RescueInfo::getRescueStatus, "3").last("limit 1");
        RescueInfo one = rescueInfoService.getOne(queryWrapper);
        if (ObjectUtils.isEmpty(one)) {
            if (driverInfo.getDriverStatus().equals("3")) {
                //更新状态
                driverInfo.setDriverStatus("1");
                driverInfoService.updateById(driverInfo);
                if (redisCache.hasKey(redisKey)) {
                    redisCache.setCacheMapValue(redisKey, "status", "1");
                }
            }
        }
    }

    @Override
    public void addRefuelRecord(RescueRefuelRecord rescueRefuelRecord) throws Exception {
        refuelRecordService.save(rescueRefuelRecord);

    }

    @Override
    public IPage<RescueRefuelRecord> listRefuelRecord(RescueRefuelRecord rescueRefuelRecord, Page<RescueRefuelRecord> page) {
        LambdaQueryWrapper<RescueRefuelRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RescueRefuelRecord::getDriverId, rescueRefuelRecord.getDriverId()).orderByDesc(RescueRefuelRecord::getRecordTime);
        IPage<RescueRefuelRecord> result = page;
        List<RescueRefuelRecord> list = refuelRecordService.list(page, queryWrapper);
        result.setRecords(list);
        result.setTotal(list.size());
        return result;
    }

    /**
     * 6位随机数
     *
     * @return
     */
    public static String getRandomString6() {
        String str = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuilder buff = new StringBuilder();
        for (int i = 0; i < 6; ++i) {
            int number = random.nextInt(str.length());
            buff.append(str.charAt(number));
        }
        return buff.toString();
    }

    @Override
    public IPage<RescueInfo> driverRescueList2(Long id, Page<RescueInfo> page){
        IPage<RescueInfo> rescueInfos = baseMapper.driverRescueList2(id, page);
        for (RescueInfo rescueInfo : rescueInfos.getRecords()) {
            String dljy_type = dictDataService.getDictDataLabel("dljy_type", rescueInfo.getRescueType());
            rescueInfo.setRescueTypeStr(dljy_type);
            String car_type = dictDataService.getDictDataLabel("rescue_car_type", rescueInfo.getCarType());
            rescueInfo.setCarTypeStr(car_type);
        }
        return rescueInfos;
    }

    @Override
    public IPage<RescueInfo> driverRescuePage2(RescueInfo rescueInfo, Page<RescueInfo> page){
        IPage<RescueInfo> rescueInfos = baseMapper.driverRescuePage2(rescueInfo, page);
        for (RescueInfo it : rescueInfos.getRecords()) {
            String dljy_type = dictDataService.getDictDataLabel("dljy_type", it.getRescueType());
            it.setRescueTypeStr(dljy_type);
            String car_type = dictDataService.getDictDataLabel("rescue_car_type", it.getCarType());
            it.setCarTypeStr(car_type);
        }
        return rescueInfos;
    }
}
