package com.bonus.material.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONObject;
import com.ah.sbd.SmsTool;
import com.ah.sbd.utils.param.BatchSmsByContentParam;
import com.ah.sbd.utils.param.SmsParam;
import com.alibaba.fastjson2.JSONArray;
import com.bonus.common.biz.constant.BmConfigItems;
import com.bonus.common.biz.constant.MaterialConstants;
import com.bonus.common.biz.enums.MaStatusEnum;
import com.bonus.common.biz.enums.MessageTypeEnum;
import com.bonus.common.biz.enums.OrderStatusEnum;
import com.bonus.common.biz.enums.TmTaskTypeEnum;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.utils.SpringUtils;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.utils.encryption.Sm4Utils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.redis.service.RedisService;
import com.bonus.common.security.service.SmsService;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.basic.domain.BmMessage;
import com.bonus.material.basic.mapper.BmMessageMapper;
import com.bonus.material.common.config.RemoteConfig;
import com.bonus.material.comprehensive.entity.RentDetailDto;
import com.bonus.material.device.domain.DevInfo;
import com.bonus.material.device.domain.vo.DevInfoVo;
import com.bonus.material.device.mapper.DevInfoMapper;
import com.bonus.material.largeScreen.entity.OrderData;
import com.bonus.material.lease.domain.LeaseRepair;
import com.bonus.material.lease.domain.LeaseRepairRecord;
import com.bonus.material.lease.mapper.LeaseRepairRecordMapper;
import com.bonus.material.order.domain.OrderDetailDto;
import com.bonus.material.order.domain.OrderInfoDto;
import com.bonus.material.order.domain.ProDto;
import com.bonus.material.order.mapper.OrderMapper;
import com.bonus.material.order.service.OrderService;
import com.bonus.material.task.domain.TmTask;
import com.bonus.material.task.mapper.TmTaskMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

import static com.bonus.common.biz.constant.MaterialConstants.ADMIN_ID;
import static com.bonus.common.biz.constant.MaterialConstants.PROVINCE_COMPANY_DEPT_ID;

/**
 * @Author：liang.chao
 * @Date：2024/11/26 - 10:34
 */

@Service
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private TmTaskMapper tmTaskMapper;

    @Resource
    private BmMessageMapper bmMessageMapper;

    @Resource
    private DevInfoMapper devInfoMapper;

    @Resource
    private LeaseRepairRecordMapper leaseRepairRecordMapper;

    @Resource
    private RemoteConfig remoteConfig;

    @Resource
    private RedisService redisService;

    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    @Transactional
    public Integer submitOrderInfo(ProDto proDto) {
        int j = 0;
        proDto.getOrderInfoDto().removeIf(Objects::isNull);
        for (OrderInfoDto orderInfoDto : proDto.getOrderInfoDto()) {
            // 首先判断库存是否足够
            List<OrderDetailDto> orderDetailDtos = orderInfoDto.getDetailsList();
            if (orderDetailDtos == null) {
                continue;
            }
            //生成订单信息
            String code = "D" + System.currentTimeMillis();
            orderInfoDto.setCode(code);
            DevInfo maInfo;
            for (OrderDetailDto orderDetailDto : orderDetailDtos) {
                // 先判断要租赁的设备状态是否正常
                if (orderDetailDto.getDevType().equals("0")) {
                    maInfo = devInfoMapper.getMaStatusByMaId(Long.valueOf(orderDetailDto.getMaId()));
                } else {
                    maInfo = devInfoMapper.getMaStatusByToolId(Long.valueOf(orderDetailDto.getMaId()), orderDetailDto.getNum());
                }

                if (maInfo == null || maInfo.getMaStatus() == null) {
                    throw new RuntimeException("设备信息异常");
                }
                if (!maInfo.getMaStatus().equals(MaStatusEnum.ON_HIRE.getCode())) {
                    throw new RuntimeException("设备非在库状态，无法下单!");
                }
                String devPersonPhone = maInfo.getPersonPhone();
                orderMapper.updateMaStatus(orderDetailDto);
            }

            Long userid = SecurityUtils.getLoginUser().getUserid();
            orderInfoDto.setBuyerId(userid.intValue());
            orderInfoDto.setBuyerCompany(Optional.ofNullable(SecurityUtils.getLoginUser().getSysUser().getCompanyId()).orElse(SecurityUtils.getLoginUser().getSysUser().getDeptId()).intValue());
            orderInfoDto.setCreater(userid);
            orderInfoDto.setUseUnit(proDto.getUseUnit());
            orderInfoDto.setProCode(proDto.getProCode());
            orderInfoDto.setProName(proDto.getProName());
            orderInfoDto.setProType(proDto.getProType());
            orderInfoDto.setVoltageLevel(proDto.getVoltageLevel());
            orderInfoDto.setProProvince(proDto.getProProvince());
            orderInfoDto.setProCity(proDto.getProCity());
            orderInfoDto.setProCounty(proDto.getProCounty());
            Integer i = orderMapper.insertOrderInfo(orderInfoDto);
            j += i;
            if (i > 0) {
                for (OrderDetailDto orderDetailDto : orderDetailDtos) {
                    orderDetailDto.setOrderId(orderInfoDto.getOrderId());
                    orderMapper.insertOrderDetail(orderDetailDto);
                }
            }
//            TmTask tmTask = new TmTask();
//            tmTask.setTaskType(TmTaskTypeEnum.TM_TASK_ORDER.getTaskTypeId());
//            tmTask.setTaskStatus(OrderStatusEnum.TO_ORDER_PLACED.getStatus());
//            tmTask.setCode(code);
//            tmTask.setCreateBy(SecurityUtils.getLoginUser().getUsername());
//            tmTask.setCreateTime(DateUtils.getNowDate());
//            tmTask.setBuyerCompanyId(Optional.ofNullable(SecurityUtils.getLoginUser().getSysUser().getCompanyId()).orElse(SecurityUtils.getLoginUser().getSysUser().getDeptId()));
//            if (!CollectionUtils.isEmpty(orderDetailDtos)) {
//                DevInfoVo devInfoVo = devInfoMapper.selectDevInfoByMaId(Long.valueOf(orderDetailDtos.get(0).getMaId()));
//                tmTask.setSellerCompanyId(Long.valueOf(devInfoVo.getCompanyId()));
//            }
//            tmTask.setNoticeCompanyId(tmTask.getSellerCompanyId());
//            tmTaskMapper.insertSelective(tmTask);
        }
        return j;
    }

    @Override
    public List<OrderInfoDto> getOrderDetails(OrderInfoDto orderInfoDto) throws Exception {
        if (orderInfoDto.isFlag()) {
            orderInfoDto.setSellerCompany(Optional.ofNullable(SecurityUtils.getLoginUser().getSysUser().getCompanyId()).orElse(SecurityUtils.getLoginUser().getSysUser().getDeptId()).intValue());
        } else {
            orderInfoDto.setBuyerCompany(Optional.ofNullable(SecurityUtils.getLoginUser().getSysUser().getCompanyId()).orElse(SecurityUtils.getLoginUser().getSysUser().getDeptId()).intValue());
        }

        List<OrderInfoDto> orderInfoDtos = orderMapper.getOrderDetails(orderInfoDto);
        for (OrderInfoDto dto : orderInfoDtos) {
            dto.setPhoneNumber(Sm4Utils.decrypt(dto.getPhoneNumber()));
            List<OrderDetailDto> list = new ArrayList<>();
            String ids = dto.getIds();
            for (String id : ids.split(",")) {
                OrderDetailDto orderDetailDto = orderMapper.selectOrderDetailsById(id);
                list.add(orderDetailDto);
            }
            BigDecimal totalRentalPrice = BigDecimal.ZERO;
            BigDecimal totalReliefPrice = BigDecimal.ZERO;
            for (OrderDetailDto detailDto : list) {
                detailDto.setOriginDays(detailDto.getDays());
                if (String.valueOf(OrderStatusEnum.ORDER_FINISHED.getStatus()).equals(detailDto.getOrderStatus())) {
                    detailDto.setDays(detailDto.getDateDays() == null ? detailDto.getDays() : String.valueOf(detailDto.getDateDays()));
                    if (detailDto.getChangeCost() != null) {
                        totalRentalPrice = totalRentalPrice.add(detailDto.getChangeCost());
                    } else {
                        if (detailDto.getDateDays() != null && detailDto.getDateDays() > 0 && detailDto.getDayLeasePrice() != null) {
                            BigDecimal newTotalPrice = detailDto.getDayLeasePrice().multiply(new BigDecimal(detailDto.getDateDays()))
                                    .setScale(2, RoundingMode.HALF_UP);
                            totalRentalPrice = totalRentalPrice.add(newTotalPrice);
                            detailDto.setCosts(newTotalPrice);
                        }
                    }
                    if (detailDto.getReliefChangeCost() != null) {
                        totalReliefPrice.add(detailDto.getReliefChangeCost());
                    } else if (detailDto.getReliefCost() != null) {
                        totalReliefPrice.add(detailDto.getReliefCost());
                    }
                }
            }
            dto.setTotalRentalPrice(totalRentalPrice);
            dto.setDetailsList(list);
            Optional<OrderDetailDto> minOrderStatus = list.stream().min(Comparator.comparingInt(p -> Integer.parseInt(p.getOrderStatus())));
            minOrderStatus.ifPresent(orderDetailDto -> dto.setOrderStatus(orderDetailDto.getOrderStatus()));
            //根据订单id去lease_repair_record表中查询是否已填写退租检修信息
            int count = leaseRepairRecordMapper.selectLeaseContent(String.valueOf(dto.getOrderId()));
            if (count > 0) {
                dto.setIsLeaseContent(1);
            } else {
                dto.setIsLeaseContent(0);
            }
            dto.setPartBacked(list.stream().anyMatch(o -> OrderStatusEnum.ORDER_UNDER_LEASE.getStatus().toString().equals(o.getOrderStatus())));
            LeaseRepair leaseRepair = new LeaseRepair();
            leaseRepair.setOrderId(String.valueOf(dto.getOrderId()));
        }
        return orderInfoDtos;
    }

    @Override
    public OrderInfoDto getOrderDetailsById(OrderDetailDto dto) {
        OrderInfoDto orderInfoDto = orderMapper.getOrderDetailsById(dto);
        List<OrderDetailDto> list = orderMapper.selectOrderDetailsByOrderId(dto.getOrderId().toString());
        Optional<OrderDetailDto> minOrderStatus = list.stream().min(Comparator.comparingInt(p -> Integer.parseInt(p.getOrderStatus())));
        minOrderStatus.ifPresent(orderDetailDto -> orderInfoDto.setOrderStatus(orderDetailDto.getOrderStatus()));
        orderInfoDto.setPhoneNumber(Sm4Utils.decrypt(orderInfoDto.getPhoneNumber()));
        orderInfoDto.setStartTime(list.get(0).getRentBeginTime());
        orderInfoDto.setEndTime(list.get(0).getRentEndTime());
        orderInfoDto.setPreOutboundUser(list.get(0).getPreOutboundUser());
        orderInfoDto.setPreOutboundTime(list.get(0).getPreOutboundTime());
        orderInfoDto.setReceivingUser(list.get(0).getReceivingUser());
        orderInfoDto.setReceivingTime(list.get(0).getReceivingTime());
        for (OrderDetailDto orderDetailDto : list) {
//            orderDetailDto.setTotalCost(orderDetailDto.getCosts());
            // 出库时间设置为租赁开始时间
            if (StringUtils.isNotBlank(orderDetailDto.getPreOutboundTime())) {
                // 租赁天数为租期结束时间减去出库时间,计算天数差
                String dateStr1 = orderDetailDto.getPreOutboundTime();
                Date dateStr2 = orderDetailDto.getRentEndTime();
                long daysDifference = calculateDaysDifference(dateStr1, dateStr2);
                // 计算累计租金
//                BigDecimal totalCost = orderDetailDto.getDayLeasePrice().multiply(new BigDecimal(daysDifference));
                orderDetailDto.setDays(String.valueOf(daysDifference));
//                orderDetailDto.setTotalCost(totalCost);
            }
        }
        orderInfoDto.setDetailsList(list);
        return orderInfoDto;
    }

    /**
     * 计算两个日期之间的天数差
     */
    public static long calculateDaysDifference(String preOutboundTimeStr, Date rentEndTime) {
        try {
            // 定义日期格式
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            // 将字符串转换为 Date 类型
            Date preOutboundDate = sdf.parse(preOutboundTimeStr);

            // 将 java.util.Date 转换为 java.time.LocalDate
            LocalDate preOutboundLocalDate = convertToLocalDate(preOutboundDate);
            LocalDate rentEndLocalDate = convertToLocalDate(rentEndTime);

            // 计算天数差
            long days = ChronoUnit.DAYS.between(preOutboundLocalDate, rentEndLocalDate);
            if (days == 0) {
                days = 1;
            } else {
                days = days + 1;
            }
            return days;
        } catch (ParseException e) {
            throw new RuntimeException("日期转换错误", e);
        }
    }

    /**
     * 将 java.util.Date 转换为 java.time.LocalDate
     */
    public static LocalDate convertToLocalDate(Date date) {
        return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
    }

    @Override
    public List<OrderInfoDto> getOrderStatusCount(OrderDetailDto dto) throws Exception {
        // true:出租方  false:承租方
        if (dto.isFlag()) {
            dto.setSellerCompany(Optional.ofNullable(SecurityUtils.getLoginUser().getSysUser().getCompanyId()).orElse(SecurityUtils.getLoginUser().getSysUser().getDeptId()).intValue());
        } else {
            dto.setBuyerCompany(Optional.ofNullable(SecurityUtils.getLoginUser().getSysUser().getCompanyId()).orElse(SecurityUtils.getLoginUser().getSysUser().getDeptId()).intValue());
        }
        List<OrderInfoDto> orderInfoDto = orderMapper.getOrderStatusCount(dto);
        OrderInfoDto infoDto = getOrderInfoDto(orderInfoDto);
        orderInfoDto.add(0, infoDto);
        return orderInfoDto;
    }

    private static OrderInfoDto getOrderInfoDto(List<OrderInfoDto> orderInfoDto) {
        int total = 0;
        OrderInfoDto infoDto = new OrderInfoDto();
        if (!CollectionUtils.isEmpty(orderInfoDto)) {
            for (OrderInfoDto info : orderInfoDto) {
                if (info.getOrderStatus().equals(OrderStatusEnum.ORDER_AWAITING_RECEIPT.getStatus().toString())) {
                    infoDto.setLeaseOrderCount(info.getOrderCount());
                } else if (info.getOrderStatus().equals(OrderStatusEnum.ORDER_FINISHED.getStatus().toString())) {
                    infoDto.setCompleteOrderCount(info.getOrderCount());
                }
                total += info.getOrderCount();
            }
            infoDto.setOrderCount(total);
        }
        return infoDto;
    }

    @Override
    public Integer updateOrderStatus(OrderDetailDto orderInfoDto) {
        List<OrderDetailDto> dtos = orderMapper.getOrderDetailsByOrderId(orderInfoDto.getOrderId());
        // 针对于接单操作，生成6位数取件码，合并出库和收货操作
        if (orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_RECEIVE.getStatus().toString())) {
            // 生成6位数取件码
            String code = generateSixDigitNumber();
            // 存储redis中
            redisService.setCacheObject(MaterialConstants.DICT_TYPE_ORDER_PICKUP_CODE + orderInfoDto.getOrderId(), code);
        }
        // 针对于收货操作，校验6位数取件码是否正确
        if (orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_AWAITING_RECEIPT.getStatus().toString())) {
            if (StringUtils.isBlank(orderInfoDto.getPickupCode())) {
                throw new ServiceException("取件码不能为空");
            }
            // 查看存储redis中的取件码，和前端传的取件码做对比
            String captcha = redisService.getCacheObject(MaterialConstants.DICT_TYPE_ORDER_PICKUP_CODE + orderInfoDto.getOrderId()).toString();
            if (!captcha.equals(orderInfoDto.getPickupCode())) {
                throw new ServiceException("取件码错误，请检查后重新输入");
            }
            // 删除redis中的取件码
            redisService.deleteObject(MaterialConstants.DICT_TYPE_ORDER_PICKUP_CODE + orderInfoDto.getOrderId());
        }
        // 退租
        if (orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_UNDER_LEASE.getStatus().toString())) {
            if (!dtos.isEmpty() && CollectionUtil.isNotEmpty(dtos)) {
                if (CollectionUtil.isNotEmpty(orderInfoDto.getMaIds())) {
                    for (OrderDetailDto dto : dtos) {
                        if (orderInfoDto.getMaIds().contains(dto.getMaId())) {
                            dto.setMaStatus("1");
                            orderMapper.updateDeviceStatus(dto);
                        }
                    }
                } else {
                    for (OrderDetailDto dto : dtos) {
                        dto.setMaStatus("1");
                        orderMapper.updateDeviceStatus(dto);
                    }
                }
            }
        }
        // 取消
        if (orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_CANCEL.getStatus().toString())) {
            if (!dtos.isEmpty() && CollectionUtil.isNotEmpty(dtos)) {
                for (OrderDetailDto dto : dtos) {
                    dto.setMaStatus(MaStatusEnum.LISTING.getCode().toString());
                    orderMapper.updateDeviceStatus(dto);
                }
            }
        }
        // 订单完成，修改装备为下架状态
        if (orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_FINISHED.getStatus().toString())) {
            if (!dtos.isEmpty() && CollectionUtil.isNotEmpty(dtos)) {
                if (CollectionUtil.isNotEmpty(orderInfoDto.getMaIds())) {
                    for (OrderDetailDto dto : dtos) {
                        if (orderInfoDto.getMaIds().contains(dto.getMaId())) {
                            dto.setMaStatus(MaStatusEnum.ON_HIRE.getCode().toString());
                            orderMapper.updateDeviceStatus(dto);
                        }
                    }
                } else {
                    for (OrderDetailDto dto : dtos) {
                        dto.setMaStatus(MaStatusEnum.ON_HIRE.getCode().toString());
                        orderMapper.updateDeviceStatus(dto);
                    }
                }
            }
        }
        String userName = SecurityUtils.getLoginUser().getUsername();
        Integer i = orderMapper.updateOrderStatus(orderInfoDto.getOrderId(), orderInfoDto.getMaIds(), orderInfoDto.getOrderStatus(), userName, orderInfoDto.getOrderRemark());
        if (!CollectionUtils.isEmpty(dtos)) {
            OptionalInt minOrderStatus = dtos.stream().mapToInt(o -> Integer.parseInt(o.getOrderStatus())).min();
            TmTask tmTask = new TmTask();
            tmTask.setTaskType(TmTaskTypeEnum.TM_TASK_ORDER.getTaskTypeId());
            tmTask.setTaskStatus(minOrderStatus.getAsInt());
            tmTask.setCode(dtos.get(0).getOrderCode());
            if (orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_PENDING_SHIPMENT.getStatus().toString()) ||
                    orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_TERMINATED.getStatus().toString())) {
                tmTask.setNoticeCompanyId(tmTask.getBuyerCompanyId());

            } else if (orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_RECEIVE.getStatus().toString()) ||
                    orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_AWAITING_RECEIPT.getStatus().toString()) ||
                    orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_UNDER_LEASE.getStatus().toString()) ||
                    orderInfoDto.getOrderStatus().equals(OrderStatusEnum.ORDER_REPAIRED.getStatus().toString())) {
                tmTask.setNoticeCompanyId(tmTask.getSellerCompanyId());
            }
            tmTaskMapper.updateTaskStatus(tmTask);
        }
        try {
            if (!dtos.isEmpty() && CollectionUtil.isNotEmpty(dtos)) {
                for (OrderDetailDto dto : dtos) {
                    BmMessage bmMessage = new BmMessage();
                    bmMessage.setCreateTime(DateUtils.getNowDate());
                    Map<String, String> maMachineMap = remoteConfig.getDictValue(MaterialConstants.DICT_TYPE_ORDER_STATUS);
                    bmMessage.setMessageContent("您好，您的订单状态已变更为" + maMachineMap.get(orderInfoDto.getOrderStatus()) + "，请及时查看");
                    bmMessage.setMessageType(String.valueOf(MessageTypeEnum.ORDER_MESSAGE.getType()));
                    bmMessage.setUuid(String.valueOf(UUID.randomUUID()));
                    bmMessage.setFromCompany(0L);
                    bmMessage.setFromUser(0L);
                    bmMessage.setFromCompanyName("系统");
                    bmMessage.setIsRead(0);
                    // 已下单、已收货、已退租、已完成 通知出租方
                    if (OrderStatusEnum.TO_ORDER_PLACED.getStatus().toString().equals(orderInfoDto.getOrderStatus()) || OrderStatusEnum.ORDER_AWAITING_RECEIPT.getStatus().toString().equals(orderInfoDto.getOrderStatus())
                            || OrderStatusEnum.ORDER_UNDER_LEASE.getStatus().toString().equals(orderInfoDto.getOrderStatus()) || OrderStatusEnum.ORDER_FINISHED.getStatus().toString().equals(orderInfoDto.getOrderStatus())
                            || OrderStatusEnum.ORDER_CANCEL.getStatus().toString().equals(orderInfoDto.getOrderStatus())) {
                        bmMessage.setToCompany(Long.valueOf(dto.getSellerCompany()));
                    } else if (OrderStatusEnum.ORDER_RECEIVE.getStatus().toString().equals(orderInfoDto.getOrderStatus()) || OrderStatusEnum.ORDER_PENDING_SHIPMENT.getStatus().toString().equals(orderInfoDto.getOrderStatus())
                            || OrderStatusEnum.ORDER_REPAIRED.getStatus().toString().equals(orderInfoDto.getOrderStatus()) || OrderStatusEnum.ORDER_TERMINATED.getStatus().toString().equals(orderInfoDto.getOrderStatus())) {
                        // 已接单、已出库、已检修、已结算 通知承租方
                        bmMessage.setToCompany(Long.valueOf(dto.getBuyerCompany()));
                    }
                    String msgKey = MaterialConstants.CACHE_MATERIAL_MALL_MESSAGE + bmMessage.getFromCompany() + ":" + bmMessage.getToCompany();
                    JSONArray arrayCache = SpringUtils.getBean(RedisService.class).getCacheObject(msgKey);
                    if (arrayCache == null) {
                        arrayCache = new JSONArray();
                    }
                    List<BmMessage> list = arrayCache.toList(BmMessage.class);
                    list.add(bmMessage);
                    (SpringUtils.getBean(RedisService.class)).setCacheObject(msgKey, list, MaterialConstants.CACHE_MATERIAL_MALL_MESSAGE_HOURS, TimeUnit.HOURS);
                    bmMessageMapper.insertBmMessage(bmMessage);
                }
            }
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
        return i;
    }

    /**
     * 发送消息到短信
     *
     * @param phoneNumbers 电话号码列表，可能包含无效或重复的号码
     * @param msg          要发送的短信消息内容
     * @return 发送短信的结果，具体形式依赖于SmsUtils.smsToken的实现
     * 此方法首先检查电话号码列表是否为空，如果为空，则直接返回空字符串。
     * 接下来，它会移除列表中所有为空的电话号码，
     * 然后对列表中超过11位的电话号码进行解密处理，
     * 确保只有有效的电话号码被用来发送短信。
     */
    private String sendMsgToSms(List<String> phoneNumbers, String msg) {
        // 检查电话号码列表和消息内容是否有效
        if (CollectionUtils.isEmpty(phoneNumbers) || StringUtils.isBlank(msg)) {
            return "";
        }

        // 过滤掉无效的电话号码
        phoneNumbers.removeIf(StringUtils::isEmpty);

        // 对超过11位的电话号码进行解密处理
        phoneNumbers.replaceAll(phoneNumber ->
                phoneNumber.length() > 11 ? Sm4Utils.decrypt(phoneNumber) : phoneNumber
        );

        // 根据电话号码数量发送短信
        if (phoneNumbers.isEmpty()) {
            return "";
        } else if (phoneNumbers.size() == 1) {
            JSONObject sendResult = SmsTool.sendSms(new SmsParam(phoneNumbers.get(0), msg), BmConfigItems.ANHUI_COMPANY_SMS_KEY);
            return sendResult.toString();
        } else {
            JSONObject sendResult = SmsTool.sendSms(new BatchSmsByContentParam(phoneNumbers, msg), BmConfigItems.ANHUI_COMPANY_SMS_KEY);
            return sendResult.toString();
        }
    }


    /**
     * 生成六位随机数取件码
     */
    public static String generateSixDigitNumber() {
        // 生成一个六位数的随机数，范围是 100000 到 999999
        return String.valueOf(ThreadLocalRandom.current().nextInt(100000, 1000000));
    }

    @Override
    public Integer inputCostRelief(OrderInfoDto orderInfoDto) {
        int result = 0;
        try {
            List<OrderDetailDto> list = orderInfoDto.getDetailsList();
            if (!CollectionUtils.isEmpty(list)) {
                for (OrderDetailDto dto : list) {
                    if (Objects.nonNull(dto.getReliefStartTime()) && Objects.nonNull(dto.getReliefEndTime())) {
                        Date reliefStartTime = sdf.parse(dto.getReliefStartTime());
                        Date reliefEndTime = sdf.parse(dto.getReliefEndTime());
                        long days = DateUtils.daysBetween(reliefStartTime, reliefEndTime) + 1;
                        dto.setReliefDays((int) days);
                        result += orderMapper.updateOrder4Relief(dto);
                    }
                }
            }
            return result;
        } catch (Exception e) {
            return 0;
        }
    }

    @Override
    public Integer changeReliefPrice(OrderInfoDto orderInfoDto) {
        List<OrderDetailDto> list = orderInfoDto.getDetailsList();
        if (!CollectionUtils.isEmpty(list)) {
            for (OrderDetailDto dto : list) {
                if (Objects.nonNull(dto.getReliefChangeCost())) {
                    orderMapper.changeReliefPrice(dto);
                }
            }
        }
        return 0;
    }

    @Override
    public OrderInfoDto getAgreementByOrderId(String orderId) {
        return orderMapper.getAgreementByOrderId(orderId);
    }

    @Override
    public List<RentDetailDto> getRentDetails(DevInfoVo devInfo) {
        return orderMapper.getRentDetails(devInfo);
    }

    @Override
    public List<OrderInfoDto> getOrderInfos(OrderInfoDto devInfo) {
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
        if (userId != null && deptId != null
                && !userId.equals(ADMIN_ID)
                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
            if ("1".equals(devInfo.getPageType())) {
                devInfo.setBuyerCompany(deptId.intValue());
            } else {
                devInfo.setSellerCompany(deptId.intValue());
            }
        }
        List<OrderInfoDto> orderInfoDtos = orderMapper.getOrderDetails(devInfo);

        String deviceName = devInfo.getDeviceName();
        List<OrderInfoDto> resultList = new ArrayList<>();

        for (OrderInfoDto dto : orderInfoDtos) {
            dto.setPhoneNumber(Sm4Utils.decrypt(dto.getPhoneNumber()));
            List<OrderDetailDto> list = new ArrayList<>();
            String ids = dto.getIds();
            for (String id : ids.split(",")) {
                OrderDetailDto orderDetailDto = orderMapper.selectOrderDetailsById(id);

                if (StringUtils.isNotBlank(deviceName)) {
                    String detailDeviceName = orderDetailDto.getDeviceName();
                    if (detailDeviceName != null && detailDeviceName.contains(deviceName)) {
                        list.add(orderDetailDto);
                    }
                } else {
                    list.add(orderDetailDto);
                }

            }
            list.removeIf(Objects::isNull);
            dto.setDetailsList(list);
            if (!list.isEmpty()) {
                Optional<OrderDetailDto> minOrderStatus = list.stream().min(Comparator.comparingInt(p -> Integer.parseInt(p.getOrderStatus())));
                minOrderStatus.ifPresent(orderDetailDto -> dto.setOrderStatus(orderDetailDto.getOrderStatus()));
                //根据订单id去lease_repair_record表中查询是否已填写退租检修信息
                int count = leaseRepairRecordMapper.selectLeaseContent(String.valueOf(dto.getOrderId()));
                if (count > 0) {
                    dto.setIsLeaseContent(1);
                } else {
                    dto.setIsLeaseContent(0);
                }
                dto.setPartBacked(list.stream().anyMatch(o -> OrderStatusEnum.ORDER_UNDER_LEASE.getStatus().toString().equals(o.getOrderStatus())));
                LeaseRepair leaseRepair = new LeaseRepair();
                leaseRepair.setOrderId(String.valueOf(dto.getOrderId()));
                // 将符合条件的订单加入结果集
                resultList.add(dto);
            }
        }
        return resultList;
    }

    @Override
    public OrderData getOrderData() {
        return orderMapper.getOrderData();
    }

    @Override
    public OrderData getCompanysCost() {
        return orderMapper.getCompanysCost();
    }

    /**
     * 获取单个订单取件码
     */
    @Override
    public int getOrderCode(OrderDetailDto dto) {
        if (dto == null || dto.getOrderId() == null) {
            throw new RuntimeException("参数不能为空");
        }
        Object cacheObject = redisService.getCacheObject(MaterialConstants.DICT_TYPE_ORDER_PICKUP_CODE + dto.getOrderId());
        if (cacheObject == null) {
            throw new RuntimeException("未查询到取件码");
        }
        return Integer.parseInt(cacheObject.toString());
    }

    /**
     * 订单确认
     */
    @Override
    public AjaxResult orderConfirm(String orderId) {
        try {
            Integer i = orderMapper.orderConfirm(orderId);
            return i > 0 ? AjaxResult.success("操作成功") : AjaxResult.error("操作失败");
        } catch (Exception e) {
            return AjaxResult.error("操作成功");
        }
    }

    /**
     * 订单驳回
     */
    @Override
    public AjaxResult orderReject(String orderId) {
        try {
            int dbCount = orderMapper.orderReject(orderId);
            return dbCount > 0 ? AjaxResult.success("操作成功") : AjaxResult.error("操作失败");
        } catch (Exception e) {
            return AjaxResult.error("操作成功");
        }
    }

    /**
     * @param keyWord
     * @return
     */
    @Override
    public AjaxResult getCategoryList(String keyWord) {
        return AjaxResult.success(orderMapper.getCategoryList(keyWord));
    }
}
