package org.jeecg.modules.subwayNetwork.controller;

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

import cn.hutool.core.util.ObjectUtil;
import org.jeecg.common.api.dto.PageSearch;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.checkData.entity.MovementRecordsMaster;
import org.jeecg.modules.checkData.entity.RecordsMasterCheck;
import org.jeecg.modules.checkData.mapper.MovementRecordsMasterMapper;
import org.jeecg.modules.checkData.service.IMovementRecordsMasterService;
import org.jeecg.modules.checkData.service.IRecordsMasterCheckService;
import org.jeecg.modules.deviceAsset.entity.*;
import org.jeecg.modules.deviceAsset.service.*;
import org.jeecg.modules.dynamicStaticAnalysis.service.IAnalysisBatchService;
import org.jeecg.modules.maintenanceWork.service.IWorkBatchService;
import org.jeecg.modules.subwayNetwork.dto.SubwaySectionEditDTO;
import org.jeecg.modules.subwayNetwork.dto.SubwaySectionQueryDTO;
import org.jeecg.modules.subwayNetwork.entity.SectionStationMap;
import org.jeecg.modules.subwayNetwork.entity.SubwaySection;
import org.jeecg.modules.subwayNetwork.service.ISectionStationMapService;
import org.jeecg.modules.subwayNetwork.service.ISubwaySectionService;

import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.subwayNetwork.vo.SubwaySectionVO;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;

/**
 * @Description: 线路车站-地铁区间
 * @Author: jeecg-boot
 * @Date: 2023-06-15
 * @Version: V1.0
 */
@Api(tags = "线路车站-地铁区间")
@RestController
@RequestMapping("/subwayNetwork/subwaySection")
@Slf4j
public class SubwaySectionController extends JeecgController<SubwaySection, ISubwaySectionService> {
    @Resource
    private ISectionStationMapService sectionStationMapService;
    @Resource
    private IRailManagementService railManagementService;
    @Resource
    private ISwitchManagementService switchManagementService;
    @Resource
    private ICurveManagementService curveManagementService;
    @Resource
    private IVerticalCurveManagementService verticalCurveManagementService;
    @Resource
    private ITrackBedManagementService trackBedManagementService;
    @Resource
    private IFastenerManagementService fastenerManagementService;
    @Resource
    private ISignBoardManagementService signBoardManagementService;
    @Resource
    private ISleeperManagementService sleeperManagementService;
    @Resource
    private IMovementRecordsMasterService movementRecordsMasterService;

    @Resource
    private IRecordsMasterCheckService recordsMasterCheckService;

    @AutoLog(value = "线路车站-地铁区间-分页列表查询")
    @ApiOperation(value = "线路车站-地铁区间-分页列表查询", notes = "线路车站-地铁区间-分页列表查询")
    @PostMapping(value = "/list")
    public Result<IPage<SubwaySectionVO>> queryPageList(@RequestBody PageSearch<SubwaySectionQueryDTO> dto) {
        IPage<SubwaySectionVO> pageList = this.service.queryPageList(dto);
        return Result.OK(pageList);
    }


    @AutoLog(value = "线路车站-地铁区间-编辑")
    @ApiOperation(value = "线路车站-地铁区间-编辑", notes = "线路车站-地铁区间-编辑")
    @PostMapping(value = "/edit")
    public Result<String> edit(@RequestBody SubwaySectionEditDTO dto) {

        this.service.edit(dto);

        return Result.OK("编辑成功!");
    }


    @AutoLog(value = "线路车站-地铁区间-通过id删除")
    @ApiOperation(value = "线路车站-地铁区间-通过id删除", notes = "线路车站-地铁区间-通过id删除")
    @GetMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {

        verifyDeleteParams(id);

        sectionStationMapService.lambdaUpdate()
                .eq(SectionStationMap::getSectionId, id)
                .remove();
        this.service.removeById(id);

        return Result.OK("删除成功!");
    }

    private void verifyDeleteParams(String id) {
        Long railCount = railManagementService.lambdaQuery()
                .eq(RailManagement::getSectionId, id)
                .count();

        Long switchCount = 0L;
        List<SectionStationMap> sectionStationMapList = sectionStationMapService.lambdaQuery()
                .eq(SectionStationMap::getSectionId, id)
                .list();
        if (ObjectUtil.isNotEmpty(sectionStationMapList)) {
            List<String> sectionStationMapIds = sectionStationMapList.stream()
                    .map(SectionStationMap::getId)
                    .collect(Collectors.toList());
            switchCount = switchManagementService.lambdaQuery()
                    .in(SwitchManagement::getSectionStationMapId, sectionStationMapIds)
                    .count();
        }

        Long curveCount = curveManagementService.lambdaQuery()
                .eq(CurveManagement::getSectionId, id)
                .count();

        Long verticalCurveCount = verticalCurveManagementService.lambdaQuery()
                .eq(VerticalCurveManagement::getSectionId, id)
                .count();

        Long trackBedCount = trackBedManagementService.lambdaQuery()
                .eq(TrackBedManagement::getSectionId, id)
                .count();

        Long fastenerCount = fastenerManagementService.lambdaQuery()
                .eq(FastenerManagement::getSectionId, id)
                .count();
        Long sleeperCount = sleeperManagementService.lambdaQuery()
                .eq(SleeperManagement::getSectionId, id)
                .count();
        Long signBoardCount = signBoardManagementService.lambdaQuery()
                .eq(SignBoardManagement::getSectionId, id)
                .count();
        Long movementRecordsCount = movementRecordsMasterService.lambdaQuery()
                .eq(MovementRecordsMaster::getSubwaySectionId, id)
                .count();
        Long recordsMasterCount = recordsMasterCheckService.lambdaQuery()
                .eq(RecordsMasterCheck::getSubwaySectionId, id)
                .count();

        boolean isDel = false;
        StringBuilder errorMsg = new StringBuilder("该区间下还有");
        if (railCount != 0) {
            isDel = true;
            errorMsg.append("钢轨单元:" + railCount + "个");
        }
        if (switchCount != 0) {
            isDel = true;
            errorMsg.append("道岔单元:" + switchCount + "个");
        }
        if (curveCount != 0) {
            isDel = true;
            errorMsg.append("曲线单元:" + curveCount + "个");
        }
        if (verticalCurveCount != 0) {
            isDel = true;
            errorMsg.append("竖曲线单元:" + verticalCurveCount + "个");
        }
        if (trackBedCount != 0) {
            isDel = true;
            errorMsg.append("道床:" + trackBedCount + "个");
        }
        if (fastenerCount != 0) {
            isDel = true;
            errorMsg.append("扣件:" + fastenerCount + "个");
        }
        if (sleeperCount != 0) {
            isDel = true;
            errorMsg.append("轨枕:" + sleeperCount + "个");
        }
        if (signBoardCount != 0) {
            isDel = true;
            errorMsg.append("轨行区标示牌:" + signBoardCount + "个");
        }
        if (movementRecordsCount != 0) {
            isDel = true;
            errorMsg.append("动静态几何数据关联:" + movementRecordsCount + "条");
        }
        if (recordsMasterCount != 0) {
            isDel = true;
            errorMsg.append("设备检查记录数据关联:" + recordsMasterCount + "条");
        }
        if (isDel) {
            throw JeecgBootException.error(errorMsg.toString());
        }
    }

    @AutoLog(value = "线路车站-地铁区间-批量删除")
    @ApiOperation(value = "线路车站-地铁区间-批量删除", notes = "线路车站-地铁区间-批量删除")
    @GetMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        String message = "";
        Integer totalNum = 0;
        Integer successNum = 0;
        Integer failNum = 0;
        String failMessage = " ";


        List<SubwaySection> listRecords = this.service.lambdaQuery()
                .in(SubwaySection::getId, Arrays.asList(ids.split(",")))
                .list();
        for (SubwaySection record : listRecords) {
            totalNum++;
            String id = record.getId();
            Long railCount = railManagementService.lambdaQuery()
                    .eq(RailManagement::getSectionId, id)
                    .count();
            Long switchCount = 0L;
            List<SectionStationMap> sectionStationMapList = sectionStationMapService.lambdaQuery()
                    .eq(SectionStationMap::getSectionId, id)
                    .list();
            if (ObjectUtil.isNotEmpty(sectionStationMapList)) {
                List<String> sectionStationMapIds = sectionStationMapList.stream()
                        .map(SectionStationMap::getId)
                        .collect(Collectors.toList());
                switchCount = switchManagementService.lambdaQuery()
                        .in(SwitchManagement::getSectionStationMapId, sectionStationMapIds)
                        .count();
            }
            Long curveCount = curveManagementService.lambdaQuery()
                    .eq(CurveManagement::getSectionId, id)
                    .count();
            Long verticalCurveCount = verticalCurveManagementService.lambdaQuery()
                    .eq(VerticalCurveManagement::getSectionId, id)
                    .count();
            Long trackBedCount = trackBedManagementService.lambdaQuery()
                    .eq(TrackBedManagement::getSectionId, id)
                    .count();
            Long fastenerCount = fastenerManagementService.lambdaQuery()
                    .eq(FastenerManagement::getSectionId, id)
                    .count();
            Long sleeperCount = sleeperManagementService.lambdaQuery()
                    .eq(SleeperManagement::getSectionId, id)
                    .count();
            Long signBoardCount = signBoardManagementService.lambdaQuery()
                    .eq(SignBoardManagement::getSectionId, id)
                    .count();
            Long movementRecordsCount = movementRecordsMasterService.lambdaQuery()
                    .eq(MovementRecordsMaster::getSubwaySectionId, id)
                    .count();
            Long recordsMasterCount = recordsMasterCheckService.lambdaQuery()
                    .eq(RecordsMasterCheck::getSubwaySectionId, id)
                    .count();
            boolean isDel = false;
            if (railCount != 0) {
                isDel = true;
            }
            if (switchCount != 0) {
                isDel = true;
            }
            if (curveCount != 0) {
                isDel = true;
            }
            if (verticalCurveCount != 0) {
                isDel = true;
            }
            if (trackBedCount != 0) {
                isDel = true;
            }
            if (fastenerCount != 0) {
                isDel = true;
            }
            if (sleeperCount != 0) {
                isDel = true;
            }
            if (signBoardCount != 0) {
                isDel = true;
            }
            if (movementRecordsCount != 0) {
                isDel = true;
            }
            if (recordsMasterCount != 0) {
                isDel = true;
            }

            if (isDel) {
                failNum++;
                failMessage = failMessage + record.getSectionName() + " ";

            } else {
                successNum++;
                sectionStationMapService.lambdaUpdate()
                        .eq(SectionStationMap::getSectionId, id)
                        .remove();
                this.service.removeById(id);
            }
        }
        message = "选中" + totalNum + "条数据已删除数据" + successNum + "条";

        if (totalNum - successNum > 0) {
            message = message + ",未删除" + failNum + "条。未删除" + failMessage + "原因是区间下面有关联数据故不能被删除";
        }
        return Result.batchDelete(message);
    }


    @AutoLog(value = "线路车站-轻轨线路-获取全部线路")
    @ApiOperation(value = "线路车站-轻轨线路-获取全部线路", notes = "线路车站-轻轨线路-获取全部线路")
    @GetMapping(value = "/listAll")
    public Result<List<Map<String, Object>>> listAll() {
        List<SubwaySection> subwaySections = this.service.list();

        List<Map<String, Object>> list = new ArrayList<>();
        for (SubwaySection subwaySection : subwaySections) {
            Map<String, Object> map = new HashMap<>();
            map.put("label", subwaySection.getSectionName());
            map.put("value", subwaySection.getId());
            map.put("parentId", subwaySection.getLightRailId());
            map.put("lineAliasId", subwaySection.getLineAliasId());
            list.add(map);
        }
        return Result.OK(list);
    }
}
