package org.jeecg.modules.subwayNetwork.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.dto.PageSearch;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.deviceAsset.entity.TrackBedManagement;
import org.jeecg.modules.subwayNetwork.dto.SubwaySectionEditDTO;
import org.jeecg.modules.subwayNetwork.dto.SubwaySectionQueryDTO;
import org.jeecg.modules.subwayNetwork.entity.LightRail;
import org.jeecg.modules.subwayNetwork.entity.SectionStationMap;
import org.jeecg.modules.subwayNetwork.entity.SubwaySection;
import org.jeecg.modules.subwayNetwork.entity.TrainStation;
import org.jeecg.modules.subwayNetwork.mapper.LightRailMapper;
import org.jeecg.modules.subwayNetwork.mapper.SectionStationMapMapper;
import org.jeecg.modules.subwayNetwork.mapper.SubwaySectionMapper;
import org.jeecg.modules.subwayNetwork.mapper.TrainStationMapper;
import org.jeecg.modules.subwayNetwork.service.ISubwaySectionService;
import org.jeecg.modules.subwayNetwork.vo.SubwaySectionVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: 线路车站-地铁区间
 * @Author: jeecg-boot
 * @Date: 2023-06-15
 * @Version: V1.0
 */
@Service
public class SubwaySectionServiceImpl extends ServiceImpl<SubwaySectionMapper, SubwaySection> implements ISubwaySectionService {
    @Resource
    private LightRailMapper lightRailMapper;

    @Resource
    private TrainStationMapper trainStationMapper;

    @Resource
    private SectionStationMapMapper sectionStationMapMapper;


    @Override
    public void edit(SubwaySectionEditDTO dto) {
        // 1.查询[起,始]站信息
        TrainStation startTrainStation = trainStationMapper.selectById(dto.getStartTrainStationId());
        TrainStation endTrainStation = trainStationMapper.selectById(dto.getEndTrainStationId());

        // 1.1 起点里程 一定要大于始点里程
        if (startTrainStation.getCenterMileage().compareTo(endTrainStation.getCenterMileage()) > 0) {
            throw JeecgBootException.error("选中站点开始里程要小于结束里程");
        }

        List<SubwaySection> listRecord = this.lambdaQuery()
                .eq(SubwaySection::getLightRailId, dto.getLightRailId())
                .eq(SubwaySection::getLineAliasId, dto.getLineAliasId())
                .list();
        for (SubwaySection record : listRecord) {
            // 如果是更新，排除自己
            if (record.getId().equals(dto.getId())) {
                continue;
            }
            BigDecimal currentStartMileage = record.getSectionStartingMileage();
            BigDecimal currentEndMileage = record.getSectionEndMileage();

            BigDecimal startMileage = startTrainStation.getCenterMileage();
            BigDecimal endMileage = endTrainStation.getCenterMileage();


            // 判断区间是否重叠
            if (currentStartMileage.compareTo(startMileage) >= 0 && currentEndMileage.compareTo(endMileage) <= 0) {
                throw JeecgBootException.error("和区间 " + record.getSectionName() + "有里程交集;" +
                        "你选中的站点里程范围【" + startTrainStation.getCenterMileage() + "~" + endTrainStation.getCenterMileage() + "】;" +
                        "冲突区间名称:" + record.getSectionName() + ",里程范围【" + record.getSectionStartingMileage() + "~" + record.getSectionEndMileage() + "】");
            }

            // 判断开始里程是否是否冲突
            if (currentStartMileage.compareTo(startMileage) < 0 && currentEndMileage.compareTo(startMileage) > 0) {
                throw JeecgBootException.error("和区间 " + record.getSectionName() + "有里程交集;" +
                        "你选中的站点里程范围【" + startTrainStation.getCenterMileage() + "~" + endTrainStation.getCenterMileage() + "】;" +
                        "冲突区间名称:" + record.getSectionName() + ",里程范围【" + record.getSectionStartingMileage() + "~" + record.getSectionEndMileage() + "】");
            }

            // 判断结束里程是否是否冲突
            if (currentStartMileage.compareTo(endMileage) < 0 && currentEndMileage.compareTo(endMileage) > 0) {
                throw JeecgBootException.error("和区间 " + record.getSectionName() + "有里程交集;" +
                        "你选中的站点里程范围【" + startTrainStation.getCenterMileage() + "~" + endTrainStation.getCenterMileage() + "】;" +
                        "冲突区间名称:" + record.getSectionName() + ",里程范围【" + record.getSectionStartingMileage() + "~" + record.getSectionEndMileage() + "】");
            }
        }


        // 2.设置区间信息
        SubwaySection subwaySection = BeanUtil.copyProperties(dto, SubwaySection.class);
        LightRail rail = lightRailMapper.selectById(dto.getLightRailId()); // 线路id
        subwaySection.setLightRailName(rail.getRailLineName());// 线路昵称
        subwaySection.setSectionStartingMileage(startTrainStation.getCenterMileage()); // 区间起始里程
        subwaySection.setSectionEndMileage(endTrainStation.getCenterMileage());// 区间结束里程
        //维护区间的更新人和更新时间
        subwaySection.setUpdateTime(new Date());
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String realname = user.getRealname();
        subwaySection.setUpdateBy(realname);
        if (ObjectUtil.isEmpty(dto.getId())) {
            this.save(subwaySection);
        } else {
            this.updateById(subwaySection);
        }


        // 3.设置区间-车站关联信息
        // 3.1 先删除关联信息
        LambdaQueryWrapper<SectionStationMap> ssmQueryWrapper = new LambdaQueryWrapper<>();
        ssmQueryWrapper.eq(SectionStationMap::getSectionId, subwaySection.getId());
        sectionStationMapMapper.delete(ssmQueryWrapper);

        // 3.2 查询这个单行区间的车站
        QueryWrapper<TrainStation> tsQueryWrapper = new QueryWrapper<>();


        // 可能会存在先选开始里程大的那个,再选开始里程小的那个
        int startSeq = startTrainStation.getSeq();
        int endSeq = endTrainStation.getSeq();
        if (startTrainStation.getStartingMileage().compareTo(endTrainStation.getStartingMileage()) > 0) {
            startSeq = endTrainStation.getSeq();
            endSeq = startTrainStation.getSeq();
        }
        tsQueryWrapper.lambda()
                .ge(TrainStation::getSeq, startSeq)
                .le(TrainStation::getSeq, endSeq)
                .eq(TrainStation::getLineAliasId, dto.getLineAliasId())
                .eq(TrainStation::getLightRailId, subwaySection.getLightRailId());
        List<TrainStation> trainStations = trainStationMapper.selectList(tsQueryWrapper);
        LightRail lightRail = lightRailMapper.selectById(subwaySection.getLightRailId());

        // 3.3 保存关联关系
        for (TrainStation trainStation : trainStations) {
            SectionStationMap sectionStationMap = new SectionStationMap();
            sectionStationMap.setLightRailId(lightRail.getId());// 车站id
            sectionStationMap.setLightRailName(lightRail.getRailLineName()); // 车站名称
            sectionStationMap.setSectionId(subwaySection.getId());// 区间id
            sectionStationMap.setSectionName(subwaySection.getSectionName()); // 区间名称
            sectionStationMap.setStationId(trainStation.getId()); // 车站id
            sectionStationMap.setStationName(trainStation.getStationName()); // 车站名称
            sectionStationMap.setLightRailId(dto.getLightRailId());
            sectionStationMap.setStationLineAliasId(dto.getLineAliasId());//线别id
            sectionStationMap.setStationStartingMileage(trainStation.getStartingMileage());// 车站起始里程
            sectionStationMap.setStationCenterMileage(trainStation.getCenterMileage());// 车站中心里程
            sectionStationMap.setStationEndMileage(trainStation.getEndMileage());// 车站结束里程
            sectionStationMapMapper.insert(sectionStationMap);
        }
    }

    @Override
    public IPage<SubwaySectionVO> queryPageList(PageSearch<SubwaySectionQueryDTO> dto) {
        // 分页查询
        IPage<SubwaySectionVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());
        page = this.baseMapper.queryPageList(page, dto.getQuery());
        return page;
    }

}
