package com.srs.survey.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.srs.common.core.domain.AjaxResult;
import com.srs.common.core.domain.entity.SysUser;
import com.srs.common.utils.WeChatUtil;
import com.srs.comprehensive.domain.CphMsg;
import com.srs.comprehensive.domain.SrsGrade;
import com.srs.comprehensive.domain.SrsStudent;
import com.srs.comprehensive.domain.ViewStuInfo;
import com.srs.comprehensive.domain.Vo.CphSearch;
import com.srs.comprehensive.mapper.SrsClassMapper;
import com.srs.comprehensive.mapper.SrsGradeMapper;
import com.srs.comprehensive.mapper.SrsStudentMapper;
import com.srs.comprehensive.mapper.ViewStuInfoMapper;
import com.srs.comprehensive.service.impl.CphMsgServiceImpl;
import com.srs.dormitory.domain.Dto.DmsSearch;
import com.srs.dormitory.domain.SrsDormitoryStudent;
import com.srs.dormitory.domain.Vo.DomInfo;
import com.srs.dormitory.mapper.DmsDormitoryMapper;
import com.srs.dormitory.mapper.SrsDormitoryStudentMapper;
import com.srs.survey.domain.SurSurvey;
import com.srs.survey.domain.dto.LeaveRes;
import com.srs.survey.domain.dto.ReturnRes;
import com.srs.survey.domain.vo.SurItineraryStatisticsVo;
import com.srs.survey.mapper.SurSurveyMapper;
import com.srs.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.srs.survey.mapper.SurItineraryMapper;
import com.srs.survey.domain.SurItinerary;
import com.srs.survey.service.ISurItineraryService;

import static com.srs.common.utils.DateUtils.getNowDate;
import static com.srs.common.utils.PageUtils.startPage;
import static com.srs.common.utils.SecurityUtils.*;

/**
 * 学生假期返校Service业务层处理
 *
 * @author srs
 * @date 2025-03-14
 */
@Service
public class SurItineraryServiceImpl extends ServiceImpl<SurItineraryMapper,SurItinerary> implements ISurItineraryService {
    @Autowired
    private SurItineraryMapper surItineraryMapper;

    @Autowired
    private SrsClassMapper srsClassMapper;
    @Autowired
    private SrsStudentMapper _stuMapper;
    @Autowired
    private SrsDormitoryStudentMapper srsDormitoryStudentMapper;

    @Autowired
    private DmsDormitoryMapper _dormMapper;

    @Autowired
    private SurSurveyMapper surSurveyMapper;
    @Autowired
    private SrsGradeMapper srsGradeMapper;
    @Autowired
    public ViewStuInfoMapper viewStuInfoMapper;

    @Autowired
    public WeChatUtil weChatUtil;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private CphMsgServiceImpl _cphMsgService;

    @Override
    public AjaxResult sendFdyStuLeaveMsg(SurItinerary param){
        try{

            // 1. 查询学生信息
            QueryWrapper<ViewStuInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("t_no", getUsername())
                    .notIn("status", "03", "02")
                    .orderByDesc("grade_code")
                    .orderByAsc("class_name");

            if (param.stuNo != null && !param.stuNo.isEmpty()) {
                queryWrapper.eq("stu_no", param.stuNo);
            }
            if (param.className != null && !param.className.isEmpty()) {
                queryWrapper.like("class_name", param.className);
            }
            if (param.name != null && !param.name.isEmpty()) {
                queryWrapper.like("stu_name", param.name);
            }
            List<ViewStuInfo> stuList = viewStuInfoMapper.selectList(queryWrapper);

            if (stuList.isEmpty()) {
                throw new Exception("未查询到在校学生信息");
            }

// 2. 批量查询已提交行程的学生
            List<String> stuNos = stuList.stream().map(ViewStuInfo::getStuNo).collect(Collectors.toList());

            QueryWrapper<SurItinerary> itineraryQuery = new QueryWrapper<>();
            itineraryQuery.in("stu_no", stuNos)
                    .eq("survey_id", param.surveyId)
                    .in("leave_status", "1", "2");
            List<SurItinerary> surList = surItineraryMapper.selectList(itineraryQuery);

// 3. 用 Set 存已提交的 stuNo
            Set<String> submittedStuNos = surList.stream()
                    .map(SurItinerary::getStuNo)
                    .collect(Collectors.toSet());

// 4. 分类并设置状态
            List<String> notStuNos = new ArrayList<>();
            for (ViewStuInfo stu : stuList) {
                if (submittedStuNos.contains(stu.getStuNo())) {
                } else {
                    notStuNos.add(stu.getStuNo());
                }
            }

            if(notStuNos.isEmpty()){
                throw new Exception("没有学生未填写");
            }

            int batchSize = 900;
            SurSurvey surSurvey = surSurveyMapper.selectById(param.surveyId);
            String msg = "你还未填写"+surSurvey.getSurveyName()+"去向调查，请<a href=\"http://zhxg.gxsdxy.cn/wab/#/pages/sub/StuApply\">点击前往</a>填写";

//            List<String> test = new ArrayList<>();
//            test.add("20240116");
//            test.add("20210080");
//            test.add("20200016");
//            test.add("20190025");
//            test.add("20210081");

            for (int i = 0; i < notStuNos.size(); i += batchSize) {
                List<String> batch = notStuNos.subList(i, Math.min(i + batchSize, notStuNos.size()));
                // 拼接成"2023001|2023002|2023003"格式
                String toUser = String.join("|", batch);
                // 调用你的发送消息方法
                weChatUtil.sendTextMessage(toUser,msg );
            }

            List<SysUser> userList = sysUserMapper.selectList(
                    new QueryWrapper<SysUser>()
                            .in("user_name", notStuNos)
            );

            List<CphMsg> addList = new ArrayList<>();
            for (SysUser user : userList) {
                CphMsg cphMsg = new CphMsg();
                cphMsg.setCreateTime(getNowDate());
                cphMsg.setCreateBy(getUsername());
                cphMsg.setReceiver(user.getUserId());
                cphMsg.setSender(getUserId());
                cphMsg.setContent( "你还未填写"+surSurvey.getSurveyName()+"去向调查，请前往学工系统手机端填写");
                addList.add(cphMsg);
            }
            boolean res = _cphMsgService.saveBatch(addList);
            if(!res){
                throw new Exception("系统推送消息失败");
            }


            return AjaxResult.success();
        }catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult sendFdyStuReturnMsg(SurItinerary param){
        try{

            // 1. 查询学生信息
            QueryWrapper<ViewStuInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("t_no", getUsername())
                    .notIn("status", "03", "02")
                    .orderByDesc("grade_code")
                    .orderByAsc("class_name");

            if (param.stuNo != null && !param.stuNo.isEmpty()) {
                queryWrapper.eq("stu_no", param.stuNo);
            }
            if (param.className != null && !param.className.isEmpty()) {
                queryWrapper.like("class_name", param.className);
            }
            if (param.name != null && !param.name.isEmpty()) {
                queryWrapper.like("stu_name", param.name);
            }
            List<ViewStuInfo> stuList = viewStuInfoMapper.selectList(queryWrapper);

            if (stuList.isEmpty()) {
                throw new Exception("未查询到在校学生信息");
            }

// 2. 批量查询已提交行程的学生
            List<String> stuNos = stuList.stream().map(ViewStuInfo::getStuNo).collect(Collectors.toList());

            QueryWrapper<SurItinerary> itineraryQuery = new QueryWrapper<>();
            itineraryQuery.in("stu_no", stuNos)
                    .eq("survey_id", param.surveyId)
                    .in("status", "1", "2");
            List<SurItinerary> surList = surItineraryMapper.selectList(itineraryQuery);

// 3. 用 Set 存已提交的 stuNo
            Set<String> submittedStuNos = surList.stream()
                    .map(SurItinerary::getStuNo)
                    .collect(Collectors.toSet());

// 4. 分类并设置状态
            List<String> notStuNos = new ArrayList<>();
            for (ViewStuInfo stu : stuList) {
                if (submittedStuNos.contains(stu.getStuNo())) {
                } else {
                    notStuNos.add(stu.getStuNo());
                }
            }

            if(notStuNos.isEmpty()){
                throw new Exception("没有学生未填写");
            }

            int batchSize = 900;
            SurSurvey surSurvey = surSurveyMapper.selectById(param.surveyId);
            String msg = "你还未填写"+surSurvey.getSurveyName()+"去向调查，请<a href=\\\"http://zhxg.gxsdxy.cn/wab/#/pages/sub/StuApply\\\">点击前往</a>填写";

            for (int i = 0; i < notStuNos.size(); i += batchSize) {
                List<String> batch = notStuNos.subList(i, Math.min(i + batchSize, stuNos.size()));
                // 拼接成"2023001|2023002|2023003"格式
                String toUser = String.join("|", batch);
                // 调用你的发送消息方法
                weChatUtil.sendTextMessage(toUser,msg );
            }


            return AjaxResult.success();
        }catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public Map<String,Object> listFdyStuReturn(SurItinerary param){
        // 1. 查询学生信息
        QueryWrapper<ViewStuInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("t_no", getUsername())
                .notIn("status", "03", "02")
                .orderByDesc("grade_code")
                .orderByAsc("class_name");

        if (param.stuNo != null && !param.stuNo.isEmpty()) {
            queryWrapper.eq("stu_no", param.stuNo);
        }
        if (param.className != null && !param.className.isEmpty()) {
            queryWrapper.like("class_name", param.className);
        }
        if (param.name != null && !param.name.isEmpty()) {
            queryWrapper.like("stu_name", param.name);
        }
        List<ViewStuInfo> stuList = viewStuInfoMapper.selectList(queryWrapper);

        if (stuList.isEmpty()) {
            Map<String,Object> result = new HashMap<>();
            result.put("total", 0);
            result.put("code", 200);
            result.put("rows", new ArrayList<>());
            return result;
        }

// 2. 批量查询已提交行程的学生
        List<String> stuNos = stuList.stream().map(ViewStuInfo::getStuNo).collect(Collectors.toList());

        QueryWrapper<SurItinerary> itineraryQuery = new QueryWrapper<>();
        itineraryQuery.in("stu_no", stuNos)
                .eq("survey_id", param.surveyId)
                .in("status", "1", "2");
        List<SurItinerary> surList = surItineraryMapper.selectList(itineraryQuery);

// 3. 用 Set 存已提交的 stuNo
        Set<String> submittedStuNos = surList.stream()
                .map(SurItinerary::getStuNo)
                .collect(Collectors.toSet());

// 4. 分类并设置状态
        List<ViewStuInfo> notList = new ArrayList<>();
        List<ViewStuInfo> isList = new ArrayList<>();
        for (ViewStuInfo stu : stuList) {
            if (submittedStuNos.contains(stu.getStuNo())) {
                stu.editStatus = "已提交";
                isList.add(stu);
            } else {
                stu.editStatus = "未提交";
                notList.add(stu);
            }
        }

// 5. 拼接返回
        notList.addAll(isList);
        // 分页处理
        int total = notList.size();
        int pageNum = (param.pageNum != null && param.pageNum > 0) ? param.pageNum.intValue() : 1;
        int pageSize = (param.pageSize != null && param.pageSize > 0) ? param.pageSize.intValue() : 10;
        int fromIndex = (pageNum - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);

        if (fromIndex >= total) {
            Map<String,Object> result = new HashMap<>();
            result.put("total", 0);
            result.put("code", 200);
            result.put("rows", new ArrayList<>());
        }

        Map<String,Object> result = new HashMap<>();
        result.put("total", total);
        result.put("code", 200);
        result.put("rows", notList.subList(fromIndex, toIndex));
        return result;
    }

    @Override
    public Map<String,Object> listFdyStuLeave(SurItinerary param){
        // 1. 查询学生信息
        QueryWrapper<ViewStuInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("t_no", getUsername())
                .notIn("status", "03", "02")
                .orderByDesc("grade_code")
                .orderByAsc("class_name");

        if (param.stuNo != null && !param.stuNo.isEmpty()) {
            queryWrapper.eq("stu_no", param.stuNo);
        }
        if (param.className != null && !param.className.isEmpty()) {
            queryWrapper.like("class_name", param.className);
        }
        if (param.name != null && !param.name.isEmpty()) {
            queryWrapper.like("stu_name", param.name);
        }
        List<ViewStuInfo> stuList = viewStuInfoMapper.selectList(queryWrapper);

        if (stuList.isEmpty()) {
            Map<String,Object> result = new HashMap<>();
            result.put("total", 0);
            result.put("code", 200);
            result.put("rows", new ArrayList<>());
            return result;
        }

// 2. 批量查询已提交行程的学生
        List<String> stuNos = stuList.stream().map(ViewStuInfo::getStuNo).collect(Collectors.toList());

        QueryWrapper<SurItinerary> itineraryQuery = new QueryWrapper<>();
        itineraryQuery.in("stu_no", stuNos)
                .eq("survey_id", param.surveyId)
                .in("leave_status", "1", "2");
        List<SurItinerary> surList = surItineraryMapper.selectList(itineraryQuery);

// 3. 用 Set 存已提交的 stuNo
        Set<String> submittedStuNos = surList.stream()
                .map(SurItinerary::getStuNo)
                .collect(Collectors.toSet());

// 4. 分类并设置状态
        List<ViewStuInfo> notList = new ArrayList<>();
        List<ViewStuInfo> isList = new ArrayList<>();
        for (ViewStuInfo stu : stuList) {
            if (submittedStuNos.contains(stu.getStuNo())) {
                stu.editStatus = "已提交";
                isList.add(stu);
            } else {
                stu.editStatus = "未提交";
                notList.add(stu);
            }
        }

// 5. 拼接返回
        notList.addAll(isList);

        // 分页处理
        int total = notList.size();
        int pageNum = (param.pageNum != null && param.pageNum > 0) ? param.pageNum.intValue() : 1;
        int pageSize = (param.pageSize != null && param.pageSize > 0) ? param.pageSize.intValue() : 10;
        int fromIndex = (pageNum - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);

        if (fromIndex >= total) {
            Map<String,Object> result = new HashMap<>();
            result.put("total", 0);
            result.put("code", 200);
            result.put("rows", new ArrayList<>());
        }

        Map<String,Object> result = new HashMap<>();
        result.put("total", total);
        result.put("code", 200);
        result.put("rows", notList.subList(fromIndex, toIndex));
        return result;
    }

    @Override
    public List<Map<String, Object>> listReturnRes1(Long surveyId){
        List<Map<String, Object>> list = surItineraryMapper.listReturnRes1(surveyId);
        QueryWrapper<SrsGrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("grade_status", "1", "3");
        List<SrsGrade> srsGrades = srsGradeMapper.selectList(queryWrapper);
        list.forEach(map->{
            for(SrsGrade srsGrade : srsGrades){
                if(map.get("dept_name") != null){
                    AtomicInteger count = new AtomicInteger();
                    Long gradeId = srsGrade.getGradeId();
                    String deptName = map.get("dept_name").toString();
                    CphSearch cphSearch = new CphSearch();
                    cphSearch.setGradeId(gradeId);
                    cphSearch.deptName = deptName;
                    List<Map<String,Object>> stuList = _stuMapper.selectViewStuInfo(cphSearch);
                    stuList.forEach(stuMap->{
                        if(stuMap.get("status") != null){
                            if(Objects.equals(stuMap.get("status").toString(), "01") ){
                                count.getAndIncrement();
                            }
                        }
                    });
                    map.put(srsGrade.getGradeName() + "在校", count.get());
                }

            }
        });

        list.forEach(map->{
            if(map.get("more_dept_name") != null){
                if(Objects.equals(map.get("more_dept_name").toString(), "信息工程学院（里建）") || Objects.equals(map.get("more_dept_name").toString(), "经济管理学院（里建）")){
                    if(map.get("submit_num") != null && map.get("yingfanxiao")!= null && map.get("weifanxiao") != null) {
                        map.put("stu_num", Integer.parseInt(map.get("submit_num").toString()));
                        map.put("yingfanxiao", Integer.parseInt(map.get("submit_num").toString()));
                        map.put("weifanxiao", Integer.parseInt(map.get("submit_num").toString()) - Integer.parseInt(map.get("yingfanxiao").toString()));
                    }
                }
            }
        });

        list.forEach(map->{
            if(map.get("more_dept_name") != null) {
                if (Objects.equals(map.get("more_dept_name").toString(), "信息工程学院（长堽）")) {
                    Map<String, Object> map1 = list.stream().filter(m -> Objects.equals(m.get("more_dept_name").toString(), "信息工程学院（里建）")).findFirst().orElse(null);
                    if (map1 != null) {
                        if(map.get("stu_num") != null && map.get("yingfanxiao")!= null && map.get("weifanxiao") != null && map.get("submit_num") != null) {
                            map.put("stu_num", Integer.parseInt(map.get("stu_num").toString()) - Integer.parseInt(map1.get("submit_num").toString()));
                            map.put("yingfanxiao", Integer.parseInt(map.get("yingfanxiao").toString()) - Integer.parseInt(map1.get("submit_num").toString()));
                            map.put("weifanxiao", Integer.parseInt(map.get("yingfanxiao").toString()) - Integer.parseInt(map.get("yifanxiao").toString()));
                        }
                    }
                }

                if (Objects.equals(map.get("more_dept_name").toString(), "经济管理学院（长堽）")) {
                    Map<String, Object> map1 = list.stream().filter(m -> Objects.equals(m.get("more_dept_name").toString(), "经济管理学院（里建）")).findFirst().orElse(null);
                    if (map1 != null) {
                        if(map.get("stu_num") != null && map.get("yingfanxiao")!= null && map.get("weifanxiao") != null && map.get("submit_num") != null) {
                            map.put("stu_num", Integer.parseInt(map.get("stu_num").toString()) - Integer.parseInt(map1.get("submit_num").toString()));
                            map.put("yingfanxiao", Integer.parseInt(map.get("yingfanxiao").toString()) - Integer.parseInt(map1.get("submit_num").toString()));
                            map.put("weifanxiao", Integer.parseInt(map.get("yingfanxiao").toString()) - Integer.parseInt(map.get("yifanxiao").toString()));
                        }
                    }
                }
            }
        });

        return list;
    }

    @Override
    public List<Map<String, Object>> countWillLeave(Long surveyId){
        return surItineraryMapper.countWillLeave(surveyId);
    }


    @Override
    public List<Map<String, Object>> countFdyClassWillLeave(Long surveyId,String fdyNo){
        return surItineraryMapper.countFdyClassWillLeave(surveyId,fdyNo);
    }

    @Override
    public List<Map<String, Object>> listSubmitRes(Long surveyId){
        SurSurvey surSurvey = surSurveyMapper.selectById(surveyId);
        List<String> counts;
        if(surSurvey != null){
            String countDate = surSurvey.countDate;
            if(countDate!= null && !countDate.isEmpty()){
                counts = List.of(countDate.split(","));
            } else {
                counts = new ArrayList<>();
            }
        } else {
            counts = new ArrayList<>();
        }

        List<Map<String, Object>> list = surItineraryMapper.listSubmitRes(surveyId);
        list.forEach(map->{
            for (int i = 0 ; i < counts.size() ; i++) {
                String countD = counts.get(i);
                if( map.get("more_dept_name") != null){
                    String dateStr = countD+" 12:00:00";
                    QueryWrapper<SurItinerary> queryWrapper = new QueryWrapper<>();
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    LocalDateTime date = LocalDateTime.parse(dateStr, formatter);

                    LocalDateTime prevDate = date.minusDays(1);


                    String moreDeptName =  map.get("more_dept_name").toString();
                    queryWrapper.eq("survey_id", surveyId);
                    queryWrapper.eq("more_dept_name", moreDeptName);
                    queryWrapper.isNotNull("home_gps_time");
                    queryWrapper.le("home_gps_time", date);
                    if(i != 0){
                        queryWrapper.gt("home_gps_time", prevDate);
                    }
                    long count = surItineraryMapper.selectCount(queryWrapper);
                    map.put(countD+" 12:00:00前", count);
                }

            }
        });
        return list;
    }

    @Override
    public List<LeaveRes> listLeaveRes(Long surveyId){
        return surItineraryMapper.listLeaveRes(surveyId);
    }

    @Override
    public List<ReturnRes> listReturnRes(Long surveyId){
        return surItineraryMapper.listReturnRes(surveyId);
    }


    @Override
    public AjaxResult getStuCampus(){
        try{
            Map<String, Object> data = new HashMap<>();
            String stuNo = getUsername();
            QueryWrapper<SrsDormitoryStudent> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("stu_no", stuNo);
            queryWrapper.last("limit 1");
            SrsDormitoryStudent srsDormitoryStudent = srsDormitoryStudentMapper.selectOne(queryWrapper);
            if(srsDormitoryStudent == null){
                data.put("campus", "长堽校区");
            }else{
                Long dormId = srsDormitoryStudent.getDormitoryId();
                DmsSearch dmsSearch = new DmsSearch();
                dmsSearch.dormitoryId = dormId;
                List<DomInfo> list = _dormMapper.listDormInfo(dmsSearch);
                if(list.size() == 0){
                    data.put("campus", "长堽校区");
                }else{
                    if(list.get(0).campusName != null){
                        data.put("campus", list.get(0).campusName.toString());
                    }else{
                        data.put("campus", "长堽校区");
                    }
                }
            }

            return AjaxResult.success(data);
        }catch (Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult updateStuHomeGpsAddr(SurItinerary param){
        try{

            SurItinerary find = surItineraryMapper.selectById(param.returnSchoolId);
            if(find == null){
                throw new Exception("未找到该记录");
            }

            find.homeGpsAddr = param.homeGpsAddr;
            int res = surItineraryMapper.updateById(find);
            if(res == 0){
                throw new Exception("更新学生定位详细地址记录失败");
            }


            return AjaxResult.success();
        }catch (Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult stuSchoolUpdate(SurItinerary param){
        try{
            SurItinerary find = surItineraryMapper.selectById(param.returnSchoolId);
            if(find == null){
                throw new Exception("未找到该记录");
            }
            if(!Objects.equals(find.getStuNo(), getUsername())){
                throw new Exception("只能修改自己的假期返校记录");
            }
//            if(!Objects.equals(find.leaveStatus, "2")){
//                throw new Exception("只有离校留校申请通过辅导员审核才能填写返校");
//            }
            if(Objects.equals(find.status, "2")){
                throw new Exception("该记录已审核通过");
            }
            find.status = "1";
            find.scheduledReturnTime = param.scheduledReturnTime;
            find.know = param.know;
            find.parentName = param.parentName;
            find.parentPhone = param.parentPhone;
            find.reachSchoolStatus = param.reachSchoolStatus;
            find.attendSchoolTime = param.attendSchoolTime;
            find.attendSchoolGps = param.attendSchoolGps;
            find.absentSchoolRemark = param.absentSchoolRemark;
            find.absentSchoolType = param.absentSchoolType;

            int res = surItineraryMapper.updateById(find);
            if(res == 0){
                throw new Exception("更新记录失败");
            }

            return AjaxResult.success();
        }catch (Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }


    @Override
    public AjaxResult manyReturnAudit(Long[] ids){
        try{
            QueryWrapper<SurItinerary> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("return_school_id", ids);
            queryWrapper.eq("status", "1");
            List<SurItinerary> list = surItineraryMapper.selectList(queryWrapper);
            if(list.size() == 0) {
                throw new Exception("未找到待审核记录");
            }
            for(SurItinerary surItinerary : list){
                surItinerary.status = "2";
            }
            boolean res = this.updateBatchById(list);
            if(!res){
                throw new Exception("批量审核失败");
            }

            return AjaxResult.success();
        }catch(Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult returnAudit(SurItinerary param){
        try{
            SurItinerary find = surItineraryMapper.selectById(param.returnSchoolId);
            if(find == null){
                throw new Exception("未找到该记录");
            }
            if(!Objects.equals(find.status, "1")){
                throw new Exception("该记录已审核");
            }

            find.status = param.status;
            int res = surItineraryMapper.updateById(find);
            if(res == 0){
                throw new Exception("更新审核状态失败");
            }

            return AjaxResult.success();
        }catch(Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult stuWillReturnUpdate(SurItinerary param){
        try{
            SurItinerary find = surItineraryMapper.selectById(param.returnSchoolId);
            if(find == null) {
                throw new Exception("未找到该记录");
            }
            if(!Objects.equals(find.getStuNo(), getUsername())){
                throw new Exception("只能修改自己的假期返校记录");
            }
            if(!Objects.equals(find.leaveStatus, "2")){
                throw new Exception("只有离校留校申请通过辅导员审核才能填写返校");
            }
            if(Objects.equals(find.status, "2")){
                throw new Exception("该记录已审核通过");
            }
            find.status = "1";
            find.scheduledReturnTime = param.scheduledReturnTime;
            find.know = param.know;
            find.parentName = param.parentName;
            find.parentPhone = param.parentPhone;
            int res = surItineraryMapper.updateById(find);
            if(res == 0) {
                throw new Exception("更新记录失败");
            }
            return AjaxResult.success();
        }catch (Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult boolStuOwnReturn(Long id){
        try{
            SurItinerary surItinerary = surItineraryMapper.selectById(id);
            if(surItinerary == null){
                throw new Exception("未找到该记录");
            }
            if(surItinerary.getStuNo() == null){
                throw new Exception("该记录无学生信息");
            }
            if(!surItinerary.getStuNo().equals(getUsername())){
                throw new Exception("未找到学生记录");
            }

            return AjaxResult.success(surItinerary);
        }catch (Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult stuHomeUpdate(SurItinerary param){
        try{

            SurItinerary find = surItineraryMapper.selectById(param.returnSchoolId);
            if(find == null){
                throw new Exception("未找到该记录");
            }

            if(!Objects.equals(find.stuNo, getUsername())){
                throw new Exception("只能修改自己的假期返校记录");
            }

            find.isHome = param.isHome;
            find.homeGps = param.homeGps;
            find.homeSubmit = "1";
            find.homeGpsTime = getNowDate();
            int res = surItineraryMapper.updateById(find);
            if(res == 0){
                throw new Exception("更新记录失败");
            }

            return AjaxResult.success();
        }catch (Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }


    @Override
    public AjaxResult manyLeaveAudit(Long[] ids){
        try{
            QueryWrapper<SurItinerary> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("return_school_id", ids);
            queryWrapper.eq("leave_status", "1");
            List<SurItinerary> list = surItineraryMapper.selectList(queryWrapper);
            if(list.size() == 0) {
                throw new Exception("未找到待审核记录");
            }
            for(SurItinerary surItinerary : list){
                surItinerary.leaveStatus = "2";
            }
            boolean res = this.updateBatchById(list);
            if(!res){
                throw new Exception("批量审核失败");
            }

            return AjaxResult.success();
        }catch(Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult leaveAudit(SurItinerary param){
        try{

            SurItinerary find = surItineraryMapper.selectById(param.returnSchoolId);
            if(find == null){
                throw new Exception("未找到该记录");
            }
            if(!Objects.equals(find.getLeaveStatus(), "1")){
                throw new Exception("该记录已审核");
            }

            find.leaveStatus = param.leaveStatus;
            int res = surItineraryMapper.updateById(find);
            if(res == 0){
                throw new Exception("更新审核状态失败");
            }

            return AjaxResult.success();
        }catch(Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public List<SurItinerary> listView(SurItinerary param){
        return surItineraryMapper.listView(param);
    }

    @Autowired
    private ViewStuInfoMapper stuInfoMapper;

    @Override
    public AjaxResult stuGetRecordBySvId(Long svId) {
        try{
            QueryWrapper<SurItinerary> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("survey_id", svId);
            queryWrapper.eq("stu_no", getUsername());
            SurItinerary surItinerary = surItineraryMapper.selectOne(queryWrapper);
            if(surItinerary == null){
                throw new Exception("未找到该记录");
            }
            QueryWrapper<ViewStuInfo> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("stu_no", getUsername());
            ViewStuInfo viewStuInfo = stuInfoMapper.selectOne(queryWrapper1);
            if(viewStuInfo != null){
                surItinerary.setClassName(viewStuInfo.getClassName());
            }

            return AjaxResult.success(surItinerary);
        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }


    @Override
    public AjaxResult stuLeaveApply(SurItinerary param){
        try{
            String stuNo = getUsername();
            param.setStuNo(stuNo);
            param.setDeptId(getDeptId());

            QueryWrapper<SrsStudent> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("stu_no",stuNo);
            SrsStudent srsStudent = _stuMapper.selectOne(queryWrapper);
            if(srsStudent == null){
                throw new Exception("学生信息不存在");
            }
            Long classId = srsStudent.getClassId();
            SurSurvey surSurvey = surSurveyMapper.selectById(param.getSurveyId());
            if(surSurvey == null){
                throw new Exception("未找到该问卷");
            }
            Date cutoffTime = surSurvey.getCutoffTime();
            if(cutoffTime != null){
                Date willLeaveTime = param.getWillLeaveTime();
                if(willLeaveTime != null){
                    if (willLeaveTime.after(cutoffTime)) {
                        throw new Exception("预计离校时间不能晚于收假时间");
                    }
                }
            }


            if(param.returnSchoolId != null){
                SurItinerary find = surItineraryMapper.selectById(param.returnSchoolId);
                if(find!= null){
                    if(Objects.equals(find.leaveStatus, "2")){
                        throw new Exception("该记录已审核通过");
                    }

                    int res = surItineraryMapper.updateById(param);
                    if(res == 0){
                        throw new Exception("更新记录失败");
                    }
                }else{
                    param.returnSchoolId = null;
                    param.setClassId(classId);
                    param.name = srsStudent.getName();

                    if(Objects.equals(param.leaveStatus, "2")){
                        throw new Exception("错误的状态");
                    }

                    int res = surItineraryMapper.insert(param);
                    if(res == 0){
                        throw new Exception("插入新记录失败");
                    }
                }
            }else{
                param.setClassId(classId);
                param.name = srsStudent.getName();

                if(Objects.equals(param.leaveStatus, "2")){
                    throw new Exception("请选择假期类型");
                }

                int res = surItineraryMapper.insert(param);
                if(res == 0){
                    throw new Exception("插入新记录失败");
                }
            }

            return AjaxResult.success();
        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 查询学生假期返校
     *
     * @param returnSchoolId 学生假期返校主键
     * @return 学生假期返校
     */
    @Override
    public SurItinerary selectSurItineraryByReturnSchoolId(Long returnSchoolId) {
        return surItineraryMapper.selectSurItineraryByReturnSchoolId(returnSchoolId);
    }

    /**
     * 查询学生假期返校列表
     *
     * @param surItinerary 学生假期返校
     * @return 学生假期返校
     */
    @Override
    public List<SurItinerary> selectSurItineraryList(SurItinerary surItinerary) {
        return surItineraryMapper.selectSurItineraryList(surItinerary);
    }

    /**
     * 新增学生假期返校
     *
     * @param surItinerary 学生假期返校
     * @return 结果
     */
    @Override
    public int insertSurItinerary(SurItinerary surItinerary) {
            return surItineraryMapper.insertSurItinerary(surItinerary);
    }

    /**
     * 修改学生假期返校
     *
     * @param surItinerary 学生假期返校
     * @return 结果
     */
    @Override
    public int updateSurItinerary(SurItinerary surItinerary) {
        return surItineraryMapper.updateSurItinerary(surItinerary);
    }

    /**
     * 批量删除学生假期返校
     *
     * @param returnSchoolIds 需要删除的学生假期返校主键
     * @return 结果
     */
    @Override
    public int deleteSurItineraryByReturnSchoolIds(Long[] returnSchoolIds) {
        return surItineraryMapper.deleteSurItineraryByReturnSchoolIds(returnSchoolIds);
    }

    /**
     * 删除学生假期返校信息
     *
     * @param returnSchoolId 学生假期返校主键
     * @return 结果
     */
    @Override
    public int deleteSurItineraryByReturnSchoolId(Long returnSchoolId) {
        return surItineraryMapper.deleteSurItineraryByReturnSchoolId(returnSchoolId);
    }
    /**
     * 审核学生返校
     */
    @Override
    public int auditItinerary(Long returnSchoolId){
        return surItineraryMapper.auditItinerary(returnSchoolId);
    }
    /***
     * 批量审核
     */
    public int batchAuditItinerary(Long[] returnSchoolId){
        return  surItineraryMapper.batchAuditItinerary(returnSchoolId);
    }

    @Override
    public List<SurItineraryStatisticsVo> getItineraryStatistics(Long surveyId) {
        List<SurItineraryStatisticsVo> originalData = surItineraryMapper.getItineraryStatistics(surveyId);

        // 判空处理，避免 NullPointerException
        if (originalData == null) {
            originalData = new ArrayList<>();
        }

        // 定义全校合计数据
        SurItineraryStatisticsVo totalSummary = new SurItineraryStatisticsVo();
        totalSummary.setMoreDeptName("合计");

        // 定义校区分类数据
        List<String> lijianCampus = List.of("水利工程学院", "电力工程学院", "机电工程学院", "信息工程学院（里建）", "经济管理学院（里建）", "土木建筑工程学院", "交通工程学院", "自动化工程学院");
        List<String> changguCampus = List.of("信息工程学院（长堽）", "经济管理学院（长堽）");

        SurItineraryStatisticsVo lijianTotal = new SurItineraryStatisticsVo();
        lijianTotal.setMoreDeptName("里建校区");

        SurItineraryStatisticsVo changguTotal = new SurItineraryStatisticsVo();
        changguTotal.setMoreDeptName("长堽校区");

        // 遍历原始数据，进行统计
        for (SurItineraryStatisticsVo item : originalData) {
            // 计算全校合计
            totalSummary.setExpectedLeaveCount((totalSummary.getExpectedLeaveCount() == null ? 0 : totalSummary.getExpectedLeaveCount()) +
                    (item.getExpectedLeaveCount() == null ? 0 : item.getExpectedLeaveCount()));
            totalSummary.setStayCount((totalSummary.getStayCount() == null ? 0 : totalSummary.getStayCount()) +
                    (item.getStayCount() == null ? 0 : item.getStayCount()));
            totalSummary.setHomeCount((totalSummary.getHomeCount() == null ? 0 : totalSummary.getHomeCount()) +
                    (item.getHomeCount() == null ? 0 : item.getHomeCount()));
            totalSummary.setReturnCount((totalSummary.getReturnCount() == null ? 0 : totalSummary.getReturnCount()) +
                    (item.getReturnCount() == null ? 0 : item.getReturnCount()));

            // 计算校区统计
            if (lijianCampus.contains(item.getMoreDeptName())) {
                lijianTotal.setExpectedLeaveCount((lijianTotal.getExpectedLeaveCount() == null ? 0 : lijianTotal.getExpectedLeaveCount()) +
                        (item.getExpectedLeaveCount() == null ? 0 : item.getExpectedLeaveCount()));
                lijianTotal.setStayCount((lijianTotal.getStayCount() == null ? 0 : lijianTotal.getStayCount()) +
                        (item.getStayCount() == null ? 0 : item.getStayCount()));
                lijianTotal.setHomeCount((lijianTotal.getHomeCount() == null ? 0 : lijianTotal.getHomeCount()) +
                        (item.getHomeCount() == null ? 0 : item.getHomeCount()));
                lijianTotal.setReturnCount((lijianTotal.getReturnCount() == null ? 0 : lijianTotal.getReturnCount()) +
                        (item.getReturnCount() == null ? 0 : item.getReturnCount()));
            } else if (changguCampus.contains(item.getMoreDeptName())) {
                changguTotal.setExpectedLeaveCount((changguTotal.getExpectedLeaveCount() == null ? 0 : changguTotal.getExpectedLeaveCount()) +
                        (item.getExpectedLeaveCount() == null ? 0 : item.getExpectedLeaveCount()));
                changguTotal.setStayCount((changguTotal.getStayCount() == null ? 0 : changguTotal.getStayCount()) +
                        (item.getStayCount() == null ? 0 : item.getStayCount()));
                changguTotal.setHomeCount((changguTotal.getHomeCount() == null ? 0 : changguTotal.getHomeCount()) +
                        (item.getHomeCount() == null ? 0 : item.getHomeCount()));
                changguTotal.setReturnCount((changguTotal.getReturnCount() == null ? 0 : changguTotal.getReturnCount()) +
                        (item.getReturnCount() == null ? 0 : item.getReturnCount()));
            }
        }

        // 创建最终返回列表
        List<SurItineraryStatisticsVo> finalResult = new ArrayList<>(originalData);

        // 先添加合计数据
        finalResult.add(totalSummary);

        // 只有当校区数据不全为 0 时才添加
        if (lijianTotal.getExpectedLeaveCount() > 0 || lijianTotal.getStayCount() > 0 || lijianTotal.getHomeCount() > 0 || lijianTotal.getReturnCount() > 0) {
            finalResult.add(lijianTotal);
        }
        if (changguTotal.getExpectedLeaveCount() > 0 || changguTotal.getStayCount() > 0 || changguTotal.getHomeCount() > 0 || changguTotal.getReturnCount() > 0) {
            finalResult.add(changguTotal);
        }

        return finalResult;
    }
}
