package bus.service.impl;

import bus.model.SnowflakeUtil;
import bus.model.dto.*;
import bus.model.dto.page.BCourseInfoPageDto;
import bus.model.po.*;
import bus.model.vo.BCourseInfoVo;
import bus.mapper.BCourseInfoMapper;

import bus.service.*;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.orcas.common.sso.model.ExtInfo;
import com.orcas.iso.config.common.user.CurrentUserHolder;
import com.qzwisdom.qzframework.core.tool.exception.BusinessException;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Program: bus
 * @Description: 描述
 * @Author: zy
 * @Date: 2025-03-02 19:53:49
 **/
@Service

public class BCourseInfoServiceImpl extends ServiceImpl<BCourseInfoMapper, BCourseInfoPo> implements BCourseInfoService {

    @Autowired
    private BCourseInfoMapper bCourseInfoMapper;
    @Resource
    private SnowflakeUtil snowflakeUtil;
    @Resource
    private BCourseTimeService bCourseTimeService;
    @Resource
    private BCoursePreService bCoursePreService;
    @Resource
    private BCourseStationService bCourseStationService;
    @Resource
    private BStationInfoService bStationInfoService;
    @Resource
    private BCourseBusService bCourseBusService;
    @Resource
    private BBusInfoService bBusInfoService;
    @Resource
    private BUserCourseService bUserCourseService;

	/**
     * 详情
     * @param id
     * @return
     */
    @Override
    public BCourseInfoDto getDetailById(String id){
        BCourseInfoPo po = this.bCourseInfoMapper.selectById(id);
        BCourseInfoDto bCourseInfoDto = BeanUtil.toBean(po, BCourseInfoDto.class);
        String mapPoint = po.getMapPoint();
        if(StrUtil.isNotBlank(mapPoint)) {
            List<BCoursePointDto> fileJsons = JSONUtil.toList(mapPoint, BCoursePointDto.class);
            bCourseInfoDto.setMapPointList(fileJsons);
        }
        QueryWrapper<BCourseTimePo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_id", id);
        queryWrapper.orderByAsc("sort");
        List<BCourseTimePo> list = bCourseTimeService.list(queryWrapper);
        bCourseInfoDto.setBCourseTimeList(BeanUtil.copyToList(list, BCourseTimeDto.class));

        QueryWrapper<BCoursePrePo> queryWrapper6 = new QueryWrapper<>();
        queryWrapper6.eq("course_id", id);
        queryWrapper6.orderByAsc("sort");
        List<BCoursePrePo> list6 = bCoursePreService.list(queryWrapper6);
        bCourseInfoDto.setBCoursePreList(BeanUtil.copyToList(list6, BCoursePreDto.class));

        QueryWrapper<BCourseStationPo> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("course_id", id);
        queryWrapper1.orderByAsc("sort");
        List<BCourseStationPo> list1 = bCourseStationService.list(queryWrapper1);
        if(CollectionUtil.isNotEmpty(list1)) {
            List<String> stationIds = list1.stream().map(BCourseStationPo::getStationId).collect(Collectors.toList());
            QueryWrapper<BStationInfoPo> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.in("id", stationIds);
            List<BStationInfoPo> list2 = bStationInfoService.list(queryWrapper2);
            Map<String,BStationInfoPo> collect = list2.stream().collect(Collectors.toMap(BStationInfoPo::getId, b -> b));
            List<BCourseStationDto> list5 = new ArrayList<>();
            for (BCourseStationPo bCourseStationPo : list1 ) {
                String stationId = bCourseStationPo.getStationId();
                BStationInfoPo bStationInfoPo = collect.get(stationId);
                if(bStationInfoPo != null) {
                    BCourseStationDto bCourseStationDto = new BCourseStationDto();
                    bCourseStationDto.setId(bCourseStationPo.getId());
                    bCourseStationDto.setStationId(bCourseStationPo.getStationId());
                    bCourseStationDto.setSort(bCourseStationPo.getSort());
                    bCourseStationDto.setType(bCourseStationPo.getType());
                    bCourseStationDto.setRemark(bCourseStationPo.getRemark());
                    bCourseStationDto.setName(bStationInfoPo.getName());
                    bCourseStationDto.setStationType(bStationInfoPo.getStationType());
                    bCourseStationDto.setStationStatus(bStationInfoPo.getStationStatus());
                    bCourseStationDto.setDetailAddress(bStationInfoPo.getDetailAddress());
                    bCourseStationDto.setStationCode(bStationInfoPo.getStationCode());
                    bCourseStationDto.setLatitude(bStationInfoPo.getLatitude());
                    bCourseStationDto.setLongitude(bStationInfoPo.getLongitude());
                    list5.add(bCourseStationDto);
                }
            }
            bCourseInfoDto.setBCourseStationList(list5);
        }

        QueryWrapper<BCourseBusPo> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.eq("course_id", id);
        queryWrapper3.orderByAsc("sort");
        List<BCourseBusPo> list3 = bCourseBusService.list(queryWrapper3);
        if(CollectionUtil.isNotEmpty(list3)) {
            List<String> busIds = list3.stream().map(BCourseBusPo::getBusId).collect(Collectors.toList());
            QueryWrapper<BBusInfoPo> queryWrapper4 = new QueryWrapper<>();
            queryWrapper4.in("id", busIds);
            List<BBusInfoPo> list4 = bBusInfoService.list(queryWrapper4);
            Map<String,BBusInfoPo> collect = list4.stream().collect(Collectors.toMap(BBusInfoPo::getId, b -> b));
            List<BCourseBusDto> list2 = new ArrayList<>();
            for (BCourseBusPo bCourseBusPo : list3 ) {
                String busId = bCourseBusPo.getBusId();
                BBusInfoPo bBusInfoPo = collect.get(busId);
                if(bBusInfoPo != null) {
                    BCourseBusDto bCourseBusDto = new BCourseBusDto();
                    bCourseBusDto.setId(bCourseBusPo.getId());
                    bCourseBusDto.setBusId(bCourseBusPo.getBusId());
                    bCourseBusDto.setSort(bCourseBusPo.getSort());
                    bCourseBusDto.setRemark(bCourseBusPo.getRemark());
                    bCourseBusDto.setBusNo(bBusInfoPo.getBusNo());
                    bCourseBusDto.setDriverName(bBusInfoPo.getDriverName());
                    bCourseBusDto.setDriverPhone(bBusInfoPo.getDriverPhone());

                    list2.add(bCourseBusDto);
                }
            }

            bCourseInfoDto.setBCourseBusList(list2);
        }
        return bCourseInfoDto;
    }

    @Override
    public BCourseInfoPo getDetail(String id) {
        return bCourseInfoMapper.selectById(id);
    }

    /**
     * 保存
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
	public void save(BCourseInfoDto dto){
        BCourseInfoPo po = BeanUtil.toBean(dto, BCourseInfoPo.class);
        List<BCoursePointDto> mapPointList = dto.getMapPointList();
        if(CollectionUtil.isNotEmpty(mapPointList)) {
            String mapPoint = JSONUtil.toJsonStr(mapPointList);
            po.setMapPoint(mapPoint);
        }
        ExtInfo extInfo = CurrentUserHolder.get();
        po.setId(snowflakeUtil.snowflakeId());
        po.setCreateTime(new Date());
        po.setUpdateTime(new Date());
        po.setCreatorId(extInfo.getUserId());
        po.setUpdaterId(extInfo.getUserId());
        po.setCreatorName(extInfo.getUserName());
        po.setUpdaterName(extInfo.getUserName());
        //处理时刻
        List<BCourseTimeDto> bCourseTimeList = dto.getBCourseTimeList();
        po.setFirstBusSpace(bCourseTimeList.get(0).getBusSpace());
        List<BCourseTimePo> bCourseTimePoList = handleCourseTime(bCourseTimeList, extInfo, po.getId(), false);
        bCourseTimeService.saveBatch(bCourseTimePoList);
        //处理预约时刻
        List<BCoursePreDto> bCoursePreList = dto.getBCoursePreList();
        List<BCoursePrePo> bCoursePrePos = handleCoursePre(bCoursePreList, extInfo, po.getId(), false);
        bCoursePreService.saveBatch(bCoursePrePos);

        //处理标志点
        List<BCourseStationDto> bCourseStationList = dto.getBCourseStationList();

        String stationId = bCourseStationList.get(0).getStationId();
        BStationInfoPo byId = bStationInfoService.getById(stationId);
        po.setFirstStationName(byId.getName());
        po.setFirstStationId(stationId);

        String stationId1 = bCourseStationList.get(bCourseStationList.size()-1).getStationId();
        BStationInfoPo byId1 = bStationInfoService.getById(stationId1);
        po.setLastStationName(byId1.getName());
        po.setLastStationId(stationId1);

        List<BCourseStationPo> bCourseStationPos = handleCourseStation(bCourseStationList, extInfo, po.getId(), true);
        bCourseStationService.saveBatch(bCourseStationPos);

        //处理车辆
        List<BCourseBusDto> bCourseBusList = dto.getBCourseBusList();
//        List<String> busId = bCourseBusList.stream().map(BCourseBusDto::getBusId).collect(Collectors.toList());
//        QueryWrapper<BCourseBusPo> queryWrapper = new QueryWrapper<>();
//        queryWrapper.in("bus_id", busId);
//        List<BCourseBusPo> list = bCourseBusService.list(queryWrapper);
//        if(CollectionUtil.isNotEmpty(list)){
//            throw new BusinessException("存在车辆已被绑定");
//        }
        List<BCourseBusPo> bCourseBusPos = handleCourseBus(bCourseBusList, extInfo, po.getId(), true);
        bCourseBusService.saveBatch(bCourseBusPos);
        this.bCourseInfoMapper.insert(po);
    }

    /**
    * 列表
    * @param dto
    * @return
    */
    @Override
    public List<BCourseInfoVo> list(BCourseInfoPageDto dto){
        return this.bCourseInfoMapper.list(dto);
    }

	/**
     * 修改
     * @param dto
     * @return
     */
    @Override
    public void update(BCourseInfoDto dto){
        BCourseInfoPo po = BeanUtil.toBean(dto, BCourseInfoPo.class);
        List<BCoursePointDto> mapPointList = dto.getMapPointList();
        if(CollectionUtil.isNotEmpty(mapPointList)) {
            String mapPoint = JSONUtil.toJsonStr(mapPointList);
            po.setMapPoint(mapPoint);
        }
        ExtInfo extInfo = CurrentUserHolder.get();
        po.setUpdateTime(new Date());
        po.setUpdaterId(extInfo.getUserId());
        po.setUpdaterName(extInfo.getUserName());
        //处理时刻
        bCourseTimeService.deleteByCourseId(po.getId());
        List<BCourseTimeDto> bCourseTimeList = dto.getBCourseTimeList();
        po.setFirstBusSpace(bCourseTimeList.get(0).getBusSpace());
        List<BCourseTimePo> bCourseTimePoList = handleCourseTime(bCourseTimeList, extInfo, po.getId(), false);
        bCourseTimeService.saveBatch(bCourseTimePoList);

        //处理预约时刻
        bCoursePreService.deleteByCourseId(po.getId());
        List<BCoursePreDto> bCoursePreList = dto.getBCoursePreList();
        List<BCoursePrePo> bCoursePrePos = handleCoursePre(bCoursePreList, extInfo, po.getId(), false);
        bCoursePreService.saveBatch(bCoursePrePos);
        //处理标志点
        bCourseStationService.deleteByCourseId(po.getId());
        List<BCourseStationDto> bCourseStationList = dto.getBCourseStationList();
        String stationName= bCourseStationList.get(0).getName();
        po.setFirstStationName(stationName);
        String stationName1 = bCourseStationList.get(bCourseStationList.size()-1).getName();
        po.setLastStationName(stationName1);

        List<BCourseStationPo> bCourseStationPos = handleCourseStation(bCourseStationList, extInfo, po.getId(),false);
        bCourseStationService.saveBatch(bCourseStationPos);
        //处理车辆
        bCourseBusService.deleteByCourseId(po.getId());
        List<BCourseBusDto> bCourseBusList = dto.getBCourseBusList();
//        List<String> busId = bCourseBusList.stream().map(BCourseBusDto::getBusId).collect(Collectors.toList());
//        QueryWrapper<BCourseBusPo> queryWrapper = new QueryWrapper<>();
//        queryWrapper.in("bus_id", busId);
//        queryWrapper.ne("id",dto.getId());
//        List<BCourseBusPo> list = bCourseBusService.list(queryWrapper);
//        if(CollectionUtil.isNotEmpty(list)){
//            throw new BusinessException("存在车辆已被绑定");
//        }

        List<BCourseBusPo> bCourseBusPos = handleCourseBus(bCourseBusList, extInfo, po.getId(), false);
        bCourseBusService.saveBatch(bCourseBusPos);
        this.bCourseInfoMapper.updateById(po);
    }


    private List<BCourseTimePo> handleCourseTime(List<BCourseTimeDto> timeList,
                                                 ExtInfo extInfo,
                                                 String courseId,
                                                 Boolean isCreate) {
        List<BCourseTimePo> bCourseTimePoList = new ArrayList<>();
        for (int i = 0; i < timeList.size(); i++) {
            BCourseTimeDto bCourseTimeDto = timeList.get(i);
            BCourseTimePo bCourseTimePo = BeanUtil.toBean(bCourseTimeDto, BCourseTimePo.class);
            bCourseTimePo.setId(snowflakeUtil.snowflakeId());
            bCourseTimePo.setCourseId(courseId);
            if(isCreate){
                bCourseTimePo.setCreateTime(new Date());
                bCourseTimePo.setCreatorId(extInfo.getUserId());
                bCourseTimePo.setCreatorName(extInfo.getUserName());
            }
            bCourseTimePo.setUpdateTime(new Date());
            bCourseTimePo.setUpdaterId(extInfo.getUserId());
            bCourseTimePo.setUpdaterName(extInfo.getUserName());
            if (i == 0) {
                bCourseTimePo.setType("0");
            }else {
                bCourseTimePo.setType("1");
            }
            bCourseTimePoList.add(bCourseTimePo);
        }
        return bCourseTimePoList;
    }

    private List<BCoursePrePo> handleCoursePre(List<BCoursePreDto> timeList,
                                                 ExtInfo extInfo,
                                                 String courseId,
                                                 Boolean isCreate) {
        List<BCoursePrePo> bCoursePrePoList = new ArrayList<>();
        for (int i = 0; i < timeList.size(); i++) {
            BCoursePreDto bCoursePreDto = timeList.get(i);
            BCoursePrePo bCoursePrePo = BeanUtil.toBean(bCoursePreDto, BCoursePrePo.class);
            bCoursePrePo.setId(snowflakeUtil.snowflakeId());
            bCoursePrePo.setCourseId(courseId);
            if(isCreate){
                bCoursePrePo.setCreateTime(new Date());
                bCoursePrePo.setCreatorId(extInfo.getUserId());
                bCoursePrePo.setCreatorName(extInfo.getUserName());
            }
            bCoursePrePo.setUpdateTime(new Date());
            bCoursePrePo.setUpdaterId(extInfo.getUserId());
            bCoursePrePo.setUpdaterName(extInfo.getUserName());

            bCoursePrePoList.add(bCoursePrePo);
        }
        return bCoursePrePoList;
    }
    /**
     * 处理站点信息
     */

    private List<BCourseStationPo> handleCourseStation(List<BCourseStationDto> stationList,
                                                       ExtInfo extInfo,
                                                       String courseId,
                                                       Boolean isCreate) {
        List<BCourseStationPo> poList = new ArrayList<>();
        for (int i = 0; i < stationList.size(); i++) {
            BCourseStationDto bCourseStationDto = stationList.get(i);
            BCourseStationPo bCourseStationPo = BeanUtil.toBean(bCourseStationDto, BCourseStationPo.class);
            bCourseStationPo.setId(snowflakeUtil.snowflakeId());
            bCourseStationPo.setCourseId(courseId);
            if(isCreate){
                bCourseStationPo.setCreateTime(new Date());
                bCourseStationPo.setCreatorId(extInfo.getUserId());
                bCourseStationPo.setCreatorName(extInfo.getUserName());
            }
            bCourseStationPo.setUpdateTime(new Date());
            bCourseStationPo.setUpdaterId(extInfo.getUserId());
            bCourseStationPo.setUpdaterName(extInfo.getUserName());
            if (i == 0) {
                bCourseStationPo.setType("0");
            }else if(i == stationList.size()-1) {
                bCourseStationPo.setType("2");
            }else{
                bCourseStationPo.setType("1");
            }
            poList.add(bCourseStationPo);
        }
        return poList;
    }

    private List<BCourseBusPo> handleCourseBus(List<BCourseBusDto> busList,
                                               ExtInfo extInfo,
                                               String courseId,
                                               Boolean isCreate) {
        List<BCourseBusPo> poList = BeanUtil.copyToList(busList, BCourseBusPo.class);
        poList.forEach(bCourseBusPo -> {
            bCourseBusPo.setCourseId(courseId);
            bCourseBusPo.setId(snowflakeUtil.snowflakeId());
            bCourseBusPo.setCourseId(courseId);
            if(isCreate){
                bCourseBusPo.setCreateTime(new Date());
                bCourseBusPo.setCreatorId(extInfo.getUserId());
                bCourseBusPo.setCreatorName(extInfo.getUserName());
            }
            bCourseBusPo.setUpdateTime(new Date());
            bCourseBusPo.setUpdaterId(extInfo.getUserId());
            bCourseBusPo.setUpdaterName(extInfo.getUserName());
        });

        return poList;

    }



    /**
     * 删除
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id){
        QueryWrapper<BCourseTimePo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_id", id);
        bCourseTimeService.remove(queryWrapper);
        QueryWrapper<BCourseStationPo> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("course_id", id);
        bCourseStationService.remove(queryWrapper1);
        QueryWrapper<BCourseBusPo> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("course_id", id);
        bCourseBusService.remove(queryWrapper2);
		bCourseInfoMapper.deleteById(id);
    }

    /**
     * 根据经纬度和半径(米)获取附近的路线
     * @return 附近的路线列表
     */
    @Override
    public List<WBusTrackInfoDto> getNearbyRoutes(NearbyRoutesDto nearbyRoutesDto) {
        Integer radius = nearbyRoutesDto.getRadius();
        String latitude = nearbyRoutesDto.getLatitude();
        String longitude = nearbyRoutesDto.getLongitude();
        // 参数验证
        if (latitude == null || longitude == null || radius == null ) {
            return Collections.emptyList();
        }

        // 1. 查询附近站点
        List<BStationInfoDto> nearbyStations = bCourseInfoMapper.findNearbyStations(nearbyRoutesDto);
        if (CollectionUtil.isEmpty(nearbyStations)) {
            return Collections.emptyList();
        }

        // 2. 查询经过这些站点的路线
        List<String> stationIds = nearbyStations.stream()
                .map(BStationInfoDto::getId)
                .collect(Collectors.toList());

        // 3. 查询包含这些站点的路线信息
        List<BCourseInfoVo> bUserCoursePos = bCourseInfoMapper.findRoutesByStationId(stationIds);
        if (CollectionUtil.isEmpty(bUserCoursePos)) {
            return Collections.emptyList();
        }

        // 获取路线ID列表（去重）
        List<String> courseIdList = bUserCoursePos.stream()
                .map(BCourseInfoVo::getId)
                .distinct()
                .collect(Collectors.toList());

        // 获取每个路线的详细信息
        List<WBusTrackInfoDto> result = new ArrayList<>();
        for(String courseId : courseIdList) {
            BCourseInfoDto courseInfo = getDetailById(courseId);
            if(courseInfo != null) {
                // 构建路线追踪信息
                WBusTrackInfoDto trackInfo = new WBusTrackInfoDto();
                trackInfo.setCourseId(courseInfo.getId());
                trackInfo.setCourseName(courseInfo.getCourseName());
                trackInfo.setFirstStationName(courseInfo.getFirstStationName());
                trackInfo.setLastStationName(courseInfo.getLastStationName());
                trackInfo.setFirstBusSpace(courseInfo.getFirstBusSpace());
                trackInfo.setTicketAmount(courseInfo.getTicketAmount());
                trackInfo.setMapPicUrl(courseInfo.getMapPicUrl());
                // 处理路线站点信息
                List<BCoursePointDto> stationInfoList = courseInfo.getMapPointList();
                trackInfo.setClist(stationInfoList);

                // 车辆经纬度
                List<BCourseBusDto> bCourseBusList = courseInfo.getBCourseBusList();
                if (CollectionUtil.isNotEmpty(bCourseBusList)) {
                    List<BCoursePointDto> bStationInfoList = new ArrayList<>();
                    for(BCourseBusDto bCourseBus : bCourseBusList) {
                        if (bCourseBus.getLocalLatitude() != null && bCourseBus.getLocalLongitude() != null) {
                            BCoursePointDto bCoursePointDto = new BCoursePointDto();
                            bCoursePointDto.setLongitude(bCourseBus.getLocalLongitude());
                            bCoursePointDto.setLatitude(bCourseBus.getLocalLatitude());
                            bStationInfoList.add(bCoursePointDto);
                        }
                    }
                    trackInfo.setBlist(bStationInfoList);
                }
                result.add(trackInfo);
            }
        }
        return result;
    }

    /**
     * 查找最近的站点
     */
    private BStationInfoDto findNearestStation(
            List<BStationInfoDto> stations,
            Double latitude,
            Double longitude) {
        return stations.stream()
                .min(Comparator.comparingDouble(station ->
                        calculateDistance(
                                latitude,
                                longitude,
                                 station.getLatitude().doubleValue(),
                                station.getLongitude().doubleValue()
                        )
                ))
                .orElse(null);
    }

    /**
     * 计算两点之间的距离(米)
     */
    private double calculateDistance(
            Double lat1,
            Double lng1,
            Double lat2,
            Double lng2) {
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);
        double a = radLat1 - radLat2;
        double b = Math.toRadians(lng1) - Math.toRadians(lng2);

        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
                Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
        s = s * 6378137; // 地球半径
        return s;
    }

    @Override
    public List<BCourseTrackTreeDto> getTreeList() {
        List<BCourseInfoPo> list = this.bCourseInfoMapper.selectList((Wrapper)((QueryWrapper)(new QueryWrapper()).eq("is_delete", 0)).orderByDesc("status"));
        Map<String, List<BCourseInfoPo>> busGroups = (Map)list.stream().collect(Collectors.groupingBy(BCourseInfoPo::getStatus, Collectors.toList()));
        List<BCourseTrackTreeDto> treeList = new ArrayList();
        busGroups.forEach((status, buses) -> {
            BCourseTrackTreeDto statusNode = new BCourseTrackTreeDto();
            statusNode.setStatus(status);
            List<BTrackNameDto> children = (List)buses.stream().map((bus) -> {
                BTrackNameDto busNode = new BTrackNameDto();
                busNode.setId(bus.getId());
                busNode.setName(bus.getCourseName());
                busNode.setCode(bus.getCourseCode());
                return busNode;
            }).collect(Collectors.toList());
            statusNode.setList(children);
            treeList.add(statusNode);
        });
        return treeList;
    }

    @Override
    public BTrackStationDto getPoint(String courseId) {
        BTrackStationDto dto = new BTrackStationDto();
        BCourseInfoPo byId = (BCourseInfoPo)this.getById(courseId);
        List<BCourseStationPo> listByCourse = this.bCourseStationService.getListByCourse(courseId);
        if (CollectionUtil.isNotEmpty(listByCourse)) {
            List<String> stationIds = (List)listByCourse.stream().map(BCourseStationPo::getStationId).collect(Collectors.toList());
            List<BStationPointDto> list = new ArrayList();
            this.bStationInfoService.listByIds(stationIds).forEach((bStationInfoPo) -> {
                BStationPointDto bCoursePointDto = new BStationPointDto();
                bCoursePointDto.setLatitude(bCoursePointDto.getLatitude());
                bCoursePointDto.setLongitude(bCoursePointDto.getLongitude());
                bCoursePointDto.setId(bStationInfoPo.getId());
                bCoursePointDto.setName(bStationInfoPo.getName());
                list.add(bCoursePointDto);
            });
            dto.setSlist(list);
        }

        String mapPoint = byId.getMapPoint();
        if (StrUtil.isNotBlank(mapPoint)) {
            List<BCoursePointDto> fileJsons = JSONUtil.toList(mapPoint, BCoursePointDto.class);
            dto.setClist(fileJsons);
        }

        dto.setId(courseId);
        return dto;
    }

    @Override
    public List<BStationPointDto> getAllPoint() {
        QueryWrapper<BStationInfoPo> queryWrapper = new QueryWrapper();
        queryWrapper.eq("is_delete", 0);
        List<BStationInfoPo> list = this.bStationInfoService.list(queryWrapper);
        List<BStationPointDto> bStationPointDtos = BeanUtil.copyToList(list, BStationPointDto.class);
        return bStationPointDtos;
    }

    @Override
    public List<BTrackCourseDto> getAllCourse() {
        List<BTrackCourseDto> list = new ArrayList();
        QueryWrapper<BCourseInfoPo> queryWrapper1 = new QueryWrapper();
        queryWrapper1.eq("is_delete", 0);
        List<BCourseInfoPo> list1 = this.list(queryWrapper1);
        Iterator var4 = list1.iterator();

        while(var4.hasNext()) {
            BCourseInfoPo po = (BCourseInfoPo)var4.next();
            String mapPoint = po.getMapPoint();
            if (StrUtil.isNotBlank(mapPoint)) {
                BTrackCourseDto dto = new BTrackCourseDto();
                List<BCoursePointDto> fileJsons = JSONUtil.toList(mapPoint, BCoursePointDto.class);
                dto.setClist(fileJsons);
                dto.setId(po.getId());
                list.add(dto);
            }
        }

        return list;
    }

    /**
     * 根据站点类型获取路线信息
     *
     * @param stationType 站点类型
     * @return 站点及其关联路线信息列表
     */
    @Override
    public List<WStationNameDto> getAllCourseByType(String stationType) {
        // 1. 查询指定类型的所有站点
        QueryWrapper<BStationInfoPo> stationWrapper = new QueryWrapper<>();
        stationWrapper.eq("station_type", stationType)
                     .eq("is_delete", 0);
        List<BStationInfoPo> stations = bStationInfoService.list(stationWrapper);
        
        if (CollectionUtil.isEmpty(stations)) {
            return Collections.emptyList();
        }

        // 2. 获取站点ID集合
        List<String> stationIds = stations.stream()
                .map(BStationInfoPo::getId)
                .collect(Collectors.toList());
        // 3. 查询包含这些站点的路线信息
        List<BCourseInfoVo> courses = bCourseInfoMapper.findRoutesByStations(stationIds);
        // 4. 构建站点与路线的映射关系
        Map<String, List<BCourseInfoVo>> courseMap = courses.stream()
                .collect(Collectors.groupingBy(course -> course.getStationId()));

        List<WStationNameDto>  newList = new ArrayList<>();

        for (BStationInfoPo station : stations) {
            List<BCourseInfoVo> course = courseMap.get(station.getId());
            if (course != null) {
                WStationNameDto dto =  new WStationNameDto();
                dto.setId(station.getId());
                dto.setStationName(station.getName());
                List<WCourseInfoByTypeDto> list1 = new ArrayList<>();
                for (BCourseInfoVo bCourseInfoVo : course) {
                    WCourseInfoByTypeDto wCourseInfoByTypeDto = BeanUtil.toBean(bCourseInfoVo, WCourseInfoByTypeDto.class);
                    String mapPoint = bCourseInfoVo.getMapPoint();
                    if (StrUtil.isNotBlank(mapPoint)) {
                        List<BCoursePointDto> fileJsons = JSONUtil.toList(mapPoint, BCoursePointDto.class);
                        wCourseInfoByTypeDto.setMapPointList(fileJsons);
                    }
                    list1.add(wCourseInfoByTypeDto);
                }
                dto.setList(list1);
                newList.add(dto);
            }
        }

      return newList;
    }

    /**
     * 根据站点类型获取路线信息
     *
     * @return
     */
    @Override
    public List<WCourseInfoByTypeDto> getMapAllCourse() {
        // 1. 查询指定类型的所有站点
        QueryWrapper<BStationInfoPo> stationWrapper = new QueryWrapper<>();
        stationWrapper.eq("is_delete", 0);
        List<BStationInfoPo> stations = bStationInfoService.list(stationWrapper);

        if (CollectionUtil.isEmpty(stations)) {
            return Collections.emptyList();
        }

        // 2. 获取站点ID集合
        List<String> stationIds = stations.stream()
                .map(BStationInfoPo::getId)
                .collect(Collectors.toList());

        // 3. 查询包含这些站点的线路
        List<BCourseInfoVo> courses = bCourseInfoMapper.findRoutesByStations(stationIds);

        // 4. 去重处理（基于线路ID）
        Map<String, BCourseInfoVo> uniqueCourses = courses.stream()
                .collect(Collectors.toMap(
                        BCourseInfoVo::getId,
                        course -> course,
                        (existing, replacement) -> existing));

        // 5. 转换DTO
        return uniqueCourses.values().stream().map(course -> {
            WCourseInfoByTypeDto dto =BeanUtil.toBean(course, WCourseInfoByTypeDto.class);
            String mapPoint = course.getMapPoint();
            if (StrUtil.isNotBlank(mapPoint)) {
                dto.setMapPointList(JSONUtil.toList(mapPoint, BCoursePointDto.class));
            }
            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 获取路线详细信息，包括路线基本信息、站点、时间表等
     * @param courseId 路线ID
     * @return 路线详细信息
     */
    @Override
    public WCourseDetailDto getCourseDetail(String courseId) {
        WCourseDetailDto detailDto = new WCourseDetailDto();
        
        // 获取路线基本信息
        BCourseInfoPo courseInfo = this.getById(courseId);
        if (courseInfo == null) {
            return null;
        }
        QueryWrapper<BUserCoursePo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_id",courseId);
        List<BUserCoursePo> list = bUserCourseService.list(queryWrapper);
        if(CollectionUtil.isNotEmpty(list)){
            detailDto.setIsCollect("1");
        }
        // 设置基本信息
        detailDto.setCourseId(courseId);
        detailDto.setCourseName(courseInfo.getCourseName());
        detailDto.setTicketAmount(courseInfo.getTicketAmount());
        detailDto.setFirstStationName(courseInfo.getFirstStationName());
        detailDto.setLastStationName(courseInfo.getLastStationName());
        detailDto.setMapPicUrl(courseInfo.getMapPicUrl());
        // 获取路线点位信息
        String mapPoint = courseInfo.getMapPoint();
        if (StrUtil.isNotBlank(mapPoint)) {
            List<BCoursePointDto> routePoints = JSONUtil.toList(mapPoint, BCoursePointDto.class);
            detailDto.setRoutePoints(routePoints);
        }
        
        // 获取站点信息
        QueryWrapper<BCourseStationPo> stationWrapper = new QueryWrapper<>();
        stationWrapper.eq("course_id", courseId);
        stationWrapper.orderByAsc("sort");
        List<BCourseStationPo> stations = bCourseStationService.list(stationWrapper);
        
        if (CollectionUtil.isNotEmpty(stations)) {
            List<String> stationIds = stations.stream()
                .map(BCourseStationPo::getStationId)
                .collect(Collectors.toList());
                
            // 获取站点详细信息
            Map<String, BStationInfoPo> stationMap = bStationInfoService.listByIds(stationIds)
                .stream()
                .collect(Collectors.toMap(BStationInfoPo::getId, station -> station));
                
            List<WCourseStationDto> stationList = new ArrayList<>();
            for (BCourseStationPo station : stations) {
                BStationInfoPo stationInfo = stationMap.get(station.getStationId());
                if (stationInfo != null) {
                    WCourseStationDto stationDto = new WCourseStationDto();
                    stationDto.setStationId(stationInfo.getId());
                    stationDto.setStationName(stationInfo.getName());
                    stationDto.setStationType(stationInfo.getStationType());
                    stationDto.setLatitude(stationInfo.getLatitude());
                    stationDto.setLongitude(stationInfo.getLongitude());
                    stationDto.setSort(station.getSort());
                    stationDto.setType(station.getType()); // 0:起点 1:途经点 2:终点
                    stationList.add(stationDto);
                }
            }
            detailDto.setStations(stationList);
        }
        
        // 获取时间表信息
        QueryWrapper<BCourseTimePo> timeWrapper = new QueryWrapper<>();
        timeWrapper.eq("course_id", courseId);
        timeWrapper.orderByAsc("sort");
        List<BCourseTimePo> times = bCourseTimeService.list(timeWrapper);
        
        if (CollectionUtil.isNotEmpty(times)) {
            List<WCourseTimeDto> timeList = times.stream()
                .map(time -> {
                    WCourseTimeDto timeDto = new WCourseTimeDto();
                    timeDto.setBusSpace(time.getBusSpace());
                    timeDto.setType(time.getType()); // 0:首班车 1:其他班次
                    return timeDto;
                })
                .collect(Collectors.toList());
            detailDto.setTimes(timeList);
        }
        QueryWrapper<BCourseBusPo> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.eq("course_id", courseId);
        queryWrapper3.orderByAsc("sort");
        List<BCourseBusPo> list3 = bCourseBusService.list(queryWrapper3);
        if(CollectionUtil.isNotEmpty(list3)) {
            List<String> busIds = list3.stream().map(BCourseBusPo::getBusId).collect(Collectors.toList());
            QueryWrapper<BBusInfoPo> queryWrapper4 = new QueryWrapper<>();
            queryWrapper4.in("id", busIds);
            List<BBusInfoPo> list4 = bBusInfoService.list(queryWrapper4);
            List<WBusInfoDto> wBusInfoDtos = BeanUtil.copyToList(list4, WBusInfoDto.class);
            detailDto.setBuses(wBusInfoDtos);
        }
        return detailDto;
    }
}
