package com.sckw.transport.repository;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sckw.core.model.enums.CarWaybillEnum;
import com.sckw.transport.dao.KwtWaybillOrderMapper;
import com.sckw.transport.model.KwtWaybillOrder;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @Author: 马超伟
 * @CreateTime: 2025-10-12
 * @Description:
 * @Version: 1.0
 */

@Repository
public class KwtWaybillOrderRepository extends ServiceImpl<KwtWaybillOrderMapper, KwtWaybillOrder> {

    /**
     * 查询运单号下拉列表(支持模糊查询)
     * @param wayOrderIds 运单id集合
     * @param wOrderNo 运单号(模糊匹配)
     * @return 运单号列表
     */
    public List<KwtWaybillOrder> selectWaybillOrderOptions(Set<Long> wayOrderIds, String wOrderNo,LocalDateTime startDateTime, LocalDateTime endDateTime) {
        LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                .select(KwtWaybillOrder::getId,
                        KwtWaybillOrder::getWOrderNo,
                        KwtWaybillOrder::getTruckNo,
                        KwtWaybillOrder::getDriverName,
                        KwtWaybillOrder::getDriverPhone,
                        KwtWaybillOrder::getStatus)
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .in(CollectionUtils.isNotEmpty(wayOrderIds), KwtWaybillOrder::getId, wayOrderIds)
                .like(StringUtils.isNotBlank(wOrderNo), KwtWaybillOrder::getWOrderNo, wOrderNo)
                .ge(Objects.nonNull(startDateTime),KwtWaybillOrder::getCreateTime, startDateTime)
                .le(Objects.nonNull(endDateTime),KwtWaybillOrder::getCreateTime, endDateTime)
                .orderByDesc(KwtWaybillOrder::getCreateTime);

        return list(wrapper);

    }

    public Page<KwtWaybillOrder> findPage(Set<Long> wayOrderIds,String truckNo,int pageNum, int pageSize, Date beforeDate, Date date) {
        Page<KwtWaybillOrder> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                .ge(KwtWaybillOrder::getCreateTime, beforeDate)
                .le(KwtWaybillOrder::getCreateTime, date)
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .in(CollectionUtils.isNotEmpty(wayOrderIds),KwtWaybillOrder::getId, wayOrderIds)
                .eq(StringUtils.isNotBlank(truckNo),KwtWaybillOrder::getTruckNo, truckNo)
                .orderByDesc(KwtWaybillOrder::getCreateTime);
        return page(page,wrapper);
    }

    public List<KwtWaybillOrder> findAll() {
        LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .orderByDesc(KwtWaybillOrder::getCreateTime)
                .select(KwtWaybillOrder::getId,
                        KwtWaybillOrder::getStatus,
                        KwtWaybillOrder::getTruckNo);
        return list(wrapper);
    }


    public KwtWaybillOrder findOneByDriverId(Long driverId) {
        //获取任务中的状态
        List<Integer> tasking = CarWaybillEnum.getTasking();
        return getOne(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDriverId, driverId)
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .in(KwtWaybillOrder::getStatus, tasking)
                .orderByDesc(KwtWaybillOrder::getId)
                .last("limit 1"));
    }

    public KwtWaybillOrder findOneByTruckNo(String truckNo, Set<Long> wayOrderIds ) {
        return getOne(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag,0)
                .eq(KwtWaybillOrder::getTruckNo,truckNo)
                .in(KwtWaybillOrder::getId, wayOrderIds)
                .orderByDesc(KwtWaybillOrder::getId)
                .last("limit 1"));
    }

    public List<KwtWaybillOrder> queryByCreateTime(LocalDateTime startMonth,Long entId) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .ge(KwtWaybillOrder::getCreateTime, startMonth)
                .eq(Objects.nonNull(entId),KwtWaybillOrder::getEntId, entId)
                .eq(KwtWaybillOrder::getDelFlag, 0));
    }

    public List<KwtWaybillOrder> findByEntId(Long entId) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(Objects.nonNull(entId),KwtWaybillOrder::getEntId, entId)
                .eq(KwtWaybillOrder::getDelFlag, 0));
    }

    public KwtWaybillOrder findOneByTruckId(String truckId) {
        return getOne(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getTruckId,truckId)
                .eq(KwtWaybillOrder::getDelFlag,0)
                .orderByDesc(KwtWaybillOrder::getId)
                .last("limit 1"));
    }

    public KwtWaybillOrder findOneByWOrderNo(String wOrderNo) {
        return getOne(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getWOrderNo,wOrderNo)
                .eq(KwtWaybillOrder::getDelFlag,0)
                .orderByDesc(KwtWaybillOrder::getId)
                .last("limit 1"));
    }

    public List<KwtWaybillOrder> queryWaybillOrderByEntId(Long entId) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag,0)
                .eq(Objects.nonNull(entId),KwtWaybillOrder::getEntId,entId)
                .orderByDesc(KwtWaybillOrder::getId));
    }

    public IPage<KwtWaybillOrder> queryPageByBillOrderIds(Set<Long> billOrderIds, int pageNum, int pageSize) {
        return page(new Page<>(pageNum, pageSize),
                Wrappers.<KwtWaybillOrder>lambdaQuery()
                        .eq(KwtWaybillOrder::getDelFlag,0)
                        .in(KwtWaybillOrder::getId, billOrderIds)
                        .orderByDesc(KwtWaybillOrder::getCreateTime)
                        .orderByDesc(KwtWaybillOrder::getId));
    }

    public List<KwtWaybillOrder> queryByCondition(KwtWaybillOrder order) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag,0)
                .like(StringUtils.isNotBlank(order.getWOrderNo()),KwtWaybillOrder::getWOrderNo, order.getWOrderNo())
                .like(StringUtils.isNotBlank(order.getTruckNo()),KwtWaybillOrder::getTruckNo, order.getTruckNo())
                .like(StringUtils.isNotBlank(order.getDriverName()),KwtWaybillOrder::getDriverName, order.getDriverName())
                .like(StringUtils.isNotBlank(order.getDriverPhone()),KwtWaybillOrder::getDriverPhone, order.getDriverPhone())
        );
    }

    public List<KwtWaybillOrder> queryByBillOrderIds(Set<Long> wayBillOrderIds) {

        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag,0)
                .in(KwtWaybillOrder::getId, wayBillOrderIds)
                .orderByDesc(KwtWaybillOrder::getUpdateTime)
                .orderByDesc(KwtWaybillOrder::getId)
        );
    }

    public List<KwtWaybillOrder> queryByBillOrderIds(Set<Long> billOrderIds, Long entId) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag,0)
                .eq(KwtWaybillOrder::getEntId,entId)
                .in(KwtWaybillOrder::getId, billOrderIds)
                .orderByDesc(KwtWaybillOrder::getUpdateTime)
        );
    }

    public KwtWaybillOrder queryByBillOrderId(Long orderId) {
        return getOne(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag,0)
                .eq(KwtWaybillOrder::getId,orderId)
                .last("limit 1")
        );
    }

    public List<KwtWaybillOrder> findWbOrderByTruckNoAndStatus(String truckNo,List<Integer> status) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag,0)
                .eq(KwtWaybillOrder::getTruckNo,truckNo)
                .in(KwtWaybillOrder::getStatus,status)
                .orderByDesc(KwtWaybillOrder::getId));
    }

    public List<KwtWaybillOrder> findList( Integer status, Set<Long> billOrderIds,Set<Long> logOrderIds) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag,0)
                .eq(Objects.nonNull( status),KwtWaybillOrder::getStatus,status)
                .in(CollectionUtils.isNotEmpty(billOrderIds),KwtWaybillOrder::getId,billOrderIds)
                .in(CollectionUtils.isNotEmpty(logOrderIds),KwtWaybillOrder::getLOrderId,logOrderIds)
                .orderByDesc(KwtWaybillOrder::getId));
    }


    public List<KwtWaybillOrder> queryWaybillOrderByLogOrderIds(List<Long> logOrderIds, Long entId, String truckNo) {
        return list(
                Wrappers.<KwtWaybillOrder>lambdaQuery()
                        .in(KwtWaybillOrder::getLOrderId, logOrderIds)
                        .eq(KwtWaybillOrder::getEntId, entId)
                        .eq(KwtWaybillOrder::getTruckNo, truckNo)
                        .eq(KwtWaybillOrder::getDelFlag, 0));
    }

    /**
     * 查询车辆列表（用于下拉选择）
     * @param truckNo 车牌号关键字（模糊匹配）
     * @return 车辆列表（按车牌号分组去重，最多返回100条）
     */
    public List<KwtWaybillOrder> selectTruckListForSelect(String truckNo,Set<Long> wayOrderIds,String waybillNo) {
        LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                .select(KwtWaybillOrder::getTruckId,
                        KwtWaybillOrder::getTruckNo,
                        KwtWaybillOrder::getDriverId,
                        KwtWaybillOrder::getDriverName,
                        KwtWaybillOrder::getDriverPhone,
                        KwtWaybillOrder::getStatus)
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .in(KwtWaybillOrder::getId,wayOrderIds)
                .like(StringUtils.isNotBlank(truckNo), KwtWaybillOrder::getTruckNo, truckNo)
                .like(StringUtils.isNotBlank(waybillNo), KwtWaybillOrder::getWOrderNo, waybillNo)
                .groupBy(KwtWaybillOrder::getTruckNo)
                .orderByDesc(KwtWaybillOrder::getUpdateTime);
        return list(wrapper);
    }


    public List<KwtWaybillOrder> queryByEntIdAndDriverId(Long entId, Long driverId) {
        Date thirtyDaysAgo = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -30));
        return list(
                Wrappers.<KwtWaybillOrder>lambdaQuery()
                        .eq(KwtWaybillOrder::getEntId, entId)
                        .eq(KwtWaybillOrder::getDriverId, driverId)
                        .eq(KwtWaybillOrder::getDelFlag, 0)
                        .ge(KwtWaybillOrder::getUpdateTime, thirtyDaysAgo));
    }

    /**
     * 查询所有已完成运单的基础统计数据。
     * <p>
     * 该方法仅返回顶部统计所需字段，避免查询无关列，减少内存占用。
     * </p>
     *
     * @param status 已完成状态编码
     * @return 已完成运单列表
     */
    public List<KwtWaybillOrder> queryCompletedWaybillOrders(Integer status) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .select(KwtWaybillOrder::getId, KwtWaybillOrder::getLOrderId, KwtWaybillOrder::getUpdateTime)
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .eq(KwtWaybillOrder::getStatus, status)
                .orderByDesc(KwtWaybillOrder::getUpdateTime));
    }

    /**
     * 根据物流订单ID查询已完成运单基础统计数据。
     * <p>
     * 仅返回顶部统计需要的字段，避免加载无关列。
     * </p>
     *
     * @param status 已完成状态编码
     * @param logisticsOrderIds 物流订单ID集合
     * @return 已完成运单列表
     */
    public List<KwtWaybillOrder> queryCompletedWaybillOrdersByLogisticsOrderIds(Integer status, List<Long> logisticsOrderIds) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .select(KwtWaybillOrder::getId, KwtWaybillOrder::getLOrderId, KwtWaybillOrder::getUpdateTime)
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .eq(KwtWaybillOrder::getStatus, status)
                .in(CollectionUtils.isNotEmpty(logisticsOrderIds), KwtWaybillOrder::getLOrderId, logisticsOrderIds)
                .orderByDesc(KwtWaybillOrder::getUpdateTime));
    }

    /**
     * 分页查询地图车辆列表（进行中任务）
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param taskingStatus 任务状态列表
     * @param wayOrderIds 运单ID集合
     * @param pageNum 页码
     * @param pageSize 每页数量
     * @return 分页结果
     */
    public IPage<KwtWaybillOrder> queryMapVehicleListPage(Date startDate, Date endDate,
                                                           List<Integer> taskingStatus, Set<Long> wayOrderIds,String truckNo, int pageNum, int pageSize) {
        return page(new Page<>(pageNum, pageSize),
                Wrappers.<KwtWaybillOrder>lambdaQuery()
                        .eq(KwtWaybillOrder::getDelFlag, 0)
                        .in(KwtWaybillOrder::getStatus, taskingStatus)
                        .in(CollectionUtils.isNotEmpty(wayOrderIds), KwtWaybillOrder::getId, wayOrderIds)
                        .ge(Objects.nonNull(startDate), KwtWaybillOrder::getCreateTime, startDate)
                        .le(Objects.nonNull(endDate), KwtWaybillOrder::getCreateTime, endDate)
                        .like(StringUtils.isNotBlank(truckNo), KwtWaybillOrder::getTruckNo, truckNo)
                        .orderByDesc(KwtWaybillOrder::getUpdateTime));
    }
    
    /**
     * 根据运单号模糊查询运单ID和运单号列表
     * @param wOrderNo 运单号关键字（模糊匹配）
     * @return 运单列表（最多返回50条）
     */
    public List<KwtWaybillOrder> queryWaybillOrderListByWOrderNo(String wOrderNo) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .select(KwtWaybillOrder::getId, KwtWaybillOrder::getWOrderNo)
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .like(StringUtils.isNotBlank(wOrderNo), KwtWaybillOrder::getWOrderNo, wOrderNo)
                .orderByDesc(KwtWaybillOrder::getCreateTime)
                .last("LIMIT 50"));
    }

    /**
     * 查询运单车辆ID和车牌号列表（去重）
     * @return 车辆列表（按车牌号分组去重）
     */
    public List<KwtWaybillOrder> queryTruckList(Long entId ) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .select(KwtWaybillOrder::getTruckId, KwtWaybillOrder::getTruckNo)
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .eq(KwtWaybillOrder::getEntId, entId)
                .orderByDesc(KwtWaybillOrder::getTruckId));
    }

    public KwtWaybillOrder queryByWayOrderNo(String wOrderNo) {
        return getOne(
                Wrappers.<KwtWaybillOrder>lambdaQuery()
                        .eq(KwtWaybillOrder::getWOrderNo, wOrderNo)
                        .eq(KwtWaybillOrder::getDelFlag, 0)
                        .last("limit 1"));
    }

    public KwtWaybillOrder findOneByTruckNo(Long logOrderId, String truckNo, Long entId ) {
        return getOne(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getLOrderId,logOrderId)
                .eq(KwtWaybillOrder::getTruckNo,truckNo)
                .eq(KwtWaybillOrder::getEntId, entId)
                .eq(KwtWaybillOrder::getDelFlag,0)
                .eq(KwtWaybillOrder::getStatus, 1)
                .last("limit 1"));
    }

    public List<KwtWaybillOrder> queryByEntId(Long entId, Long driverId) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                        .eq(KwtWaybillOrder::getEntId, entId)
                        .eq(KwtWaybillOrder::getDriverId, driverId)
                        .eq(KwtWaybillOrder::getDelFlag, 0)
                        .orderByAsc(KwtWaybillOrder::getUpdateTime));
    }

    public List<KwtWaybillOrder> findOneByLogOrderIdAndStatus(Long logOrderId, List<Integer> status, Long waybillId) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getLOrderId,logOrderId)
                .in(KwtWaybillOrder::getStatus, status)
                .eq(KwtWaybillOrder::getDelFlag,0)
                .ne(KwtWaybillOrder::getId, waybillId)
                .orderByAsc(KwtWaybillOrder::getCreateTime));
    }

    public List<KwtWaybillOrder> queryByBillOrderIdsAndTime(Set<Long> wayOrderIds, Date startDate, Date endDate) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .in(KwtWaybillOrder::getId, wayOrderIds)
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .ge(KwtWaybillOrder::getCreateTime, startDate)
                .le(KwtWaybillOrder::getCreateTime, endDate)
        );
    }

    public Page<KwtWaybillOrder> findPageByStatus(int pageNum, int pageSize) {
        Page<KwtWaybillOrder> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .eq(KwtWaybillOrder::getStatus, 5)
                .orderByDesc(KwtWaybillOrder::getCreateTime);
        return page(page,wrapper);
    }

    public List<KwtWaybillOrder> findWbOrderByTruckNo(String truckNo) {
        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .eq(KwtWaybillOrder::getTruckNo, truckNo)
                .eq(KwtWaybillOrder::getOpened, 0)
                .orderByDesc(KwtWaybillOrder::getId));
    }

}
