package cn.teammodel.controller.admin.service.impl;

import cn.teammodel.common.ErrorCode;
import cn.teammodel.common.PK;
import cn.teammodel.config.exception.ServiceException;
import cn.teammodel.controller.admin.service.TeacherService;
import cn.teammodel.model.dto.admin.teacher.TeacherDto;
import cn.teammodel.model.entity.common.GroupList;
import cn.teammodel.model.entity.school.LessonRecord;
import cn.teammodel.model.entity.school.School;
import cn.teammodel.model.entity.school.SchoolTeacher;
import cn.teammodel.repository.LessonRecordRepository;
import cn.teammodel.repository.SchoolGroupListRepository;
import cn.teammodel.repository.SchoolRepository;
import cn.teammodel.repository.SchoolTeacherRepository;
import cn.teammodel.utils.GroupUtil;
import cn.teammodel.utils.SchoolDateUtil;
import com.azure.spring.data.cosmos.core.query.CosmosPageRequest;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.*;
import java.util.*;

import static cn.teammodel.utils.SchoolDateUtil.calculateWeekNum;

@Service
public class TeacherServiceImpl implements TeacherService {
    @Resource
    private SchoolTeacherRepository schoolTeacherRepository;
        @Resource
    private SchoolGroupListRepository schoolGroupListRepository;
    @Resource
    private SchoolRepository  schoolRepository;
    @Resource
    private LessonRecordRepository lessonRecordRepository;
    @Autowired
    private Environment env;
    @Override
    public List<Map<String, Integer>> getTeacherList(TeacherDto teacherDto) {
        List<Map<String, Integer>> result = new ArrayList<>();
        Map<String, Integer> teacherCountMap = new HashMap<>();
        Map<String, Integer> groupCountMap = new HashMap<>();
       List<GroupList> groupLists = schoolGroupListRepository.findAllByCode("GroupList-" + teacherDto.getCode());
       List<SchoolTeacher> schoolTeachers = schoolTeacherRepository.findAllByCode("Teacher-" + teacherDto.getCode());
       teacherCountMap.put("教师总人数", schoolTeachers.size());
       List<School> school = schoolRepository.findBaseById(teacherDto.getCode());
       List<School.Subject> subjects = new ArrayList<>();
       List<School.Period> periods = new ArrayList<>();
       for (School sc : school) {
           if (sc.getPeriod() != null) {
               // 遍历每个 Period 对象
               for (School.Period period : sc.getPeriod()) {
                   periods.add(period);
                   // 检查 period 是否有 subjects 列表
                   if (period.getSubjects() != null) {
                       // 将 period 中的 subjects 添加到总的 subjects 列表中
                       subjects.addAll(period.getSubjects());
                   }
               }
           }

       }

        Map<String, Integer> updatedSubjectCountMap = getStringIntegerMap(subjects, schoolTeachers);

        // 创建一个映射，用于存储每个职位的教师数量
        Map<String, Integer> jobCountMap = new HashMap<>();

        // 遍历所有教师
        for (SchoolTeacher teacher : schoolTeachers) {
            // 获取教师的职位
            String job = teacher.getJob();
            if (job != null) {
                // 更新每个职位的教师数量
                jobCountMap.put(job, jobCountMap.getOrDefault(job, 0) + 1);
            }
        }
        jobCountMap.entrySet().removeIf(entry -> entry.getKey().isEmpty());
        Map<String, Integer> periodCountMap = getPeriodCountMap(periods,schoolTeachers);
        for (GroupList groupList : groupLists) {
            groupCountMap.put(groupList.getName(), groupList.getMembers().size());
        }
        periodCountMap.entrySet().removeIf(entry -> entry.getKey().isEmpty());
        updatedSubjectCountMap.entrySet().removeIf(entry -> entry.getKey().isEmpty());
        result.add(updatedSubjectCountMap);
        result.add(jobCountMap);
        result.add(periodCountMap);
        result.add(teacherCountMap);
        result.add(groupCountMap);
        return result;
    }

    @Override
    public Map<String, Object> getTeacherDetail(TeacherDto teacherDto, HttpServletRequest request) {

        Map<String, Object> teachers;
        //获取全学校教师名单详情
        String url = env.getProperty("ies.server-url-get-teacher-all");
        try {
            teachers =  GroupUtil.getGroupId(teacherDto,new GroupUtil(env), request,url);
        }catch (Exception e) {
            throw new ServiceException(ErrorCode.SYSTEM_ERROR.getCode(), "数据转换错误");

        }
        return teachers;
    }

    @Override
    public Map<Long, Integer> getTeacherByRecord(TeacherDto teacherDto) {
        final int SLICE_SIZE = 100;
        // 获取学期起止时间
        List<School.Semester> semesters = schoolRepository.findSemestersById(teacherDto.getCode(), teacherDto.getPeriodId());
        SchoolDateUtil.semesterModel semesterModel = SchoolDateUtil.getSemesterByNow(semesters, LocalDate.now());
        LocalDateTime startDatetime;
        LocalDateTime endDatetime;
        if(teacherDto.getStartTime() != null) {
            startDatetime = LocalDateTime.ofInstant(Instant.ofEpochMilli(teacherDto.getStartTime()), ZoneId.systemDefault());
            endDatetime = LocalDateTime.ofInstant(Instant.ofEpochMilli(teacherDto.getEndTime()), ZoneId.systemDefault());
        }else {
            startDatetime = semesterModel.getStartDatetime();
            endDatetime = semesterModel.getEndDatetime();
        }
        if (startDatetime == null || endDatetime == null) throw new ServiceException(ErrorCode.PARAMS_ERROR);
        long totalWeek = calculateWeekNum(startDatetime, endDatetime, null);

        // slice 分段读取
        CosmosPageRequest pageRequest = new CosmosPageRequest(0, SLICE_SIZE, null);
        Slice<LessonRecord> slice;
        Map<Long, Integer> countByWeek = SchoolDateUtil.createEmptyWeekMap(totalWeek);

        do {
            if(StringUtils.isNotEmpty(teacherDto.getGrade())) {
                slice = lessonRecordRepository.findAllByGrade(String.format(PK.PK_LESSON_RECORD, teacherDto.getCode()), teacherDto.getGrade(),pageRequest);
            } else if(StringUtils.isNotEmpty(teacherDto.getTmdId())) {
                slice = lessonRecordRepository.findAllByAcademicYearId(String.format(PK.PK_LESSON_RECORD, teacherDto.getCode()), teacherDto.getTmdId(),pageRequest);
            } else {
                slice = lessonRecordRepository.findAll(String.format(PK.PK_LESSON_RECORD, teacherDto.getCode()), pageRequest);
            }
            List<LessonRecord> content = slice.getContent();
            if (ObjectUtils.isEmpty(content)) {
                break;
            }

            // 分批次计算
            for (LessonRecord item : content) {
                // 处理每周的课程数
                long weekNum = calculateWeekNum(startDatetime, endDatetime, item.getStartTime());
                countByWeek.put(weekNum, countByWeek.getOrDefault(weekNum, 0) + 1);
            }

            if (slice.hasNext()) {
                pageRequest = (CosmosPageRequest) slice.nextPageable();
            }
        } while (slice.hasNext());
        countByWeek.entrySet().removeIf(entry -> entry.getKey() == -1);
        return countByWeek;
    }

    @Override
    public Map<String, Object> getTeacherLearningCategory(TeacherDto teacherDto) {

        Map<String, Object> LearningCategory = new HashMap<>(Collections.emptyMap());
        try {
            // 获取学期起止时间
            List<School.Semester> semesters = schoolRepository.findSemestersById(teacherDto.getCode(), teacherDto.getPeriodId());
            SchoolDateUtil.semesterModel semesterModel = SchoolDateUtil.getSemesterByNow(semesters, LocalDate.now());
            LocalDateTime startDatetime;
            LocalDateTime endDatetime;
            if(teacherDto.getStartTime() != null) {
                startDatetime = LocalDateTime.ofInstant(Instant.ofEpochMilli(teacherDto.getStartTime()), ZoneId.systemDefault());
                endDatetime = LocalDateTime.ofInstant(Instant.ofEpochMilli(teacherDto.getEndTime()), ZoneId.systemDefault());
            }else {
                startDatetime = semesterModel.getStartDatetime();
                endDatetime = semesterModel.getEndDatetime();
            }
            if (startDatetime == null || endDatetime == null) throw new ServiceException(ErrorCode.PARAMS_ERROR);

            // 将 LocalDateTime 转换为 Long 类型的时间戳
            long startTimestamp = startDatetime.toInstant(ZoneOffset.UTC).toEpochMilli();
            long endTimestamp = endDatetime.toInstant(ZoneOffset.UTC).toEpochMilli();

            List<LessonRecord> lessonRecords = lessonRecordRepository.getLessonsByConditions(String.format(PK.PK_LESSON_RECORD, teacherDto.getCode()), startTimestamp, endTimestamp, teacherDto.getTmdId());
            int[] counts = {0, 0, 0, 0, 0};
            String[] keys = {"cooperation", "internet", "task", "exam", "diffential"};

            for (LessonRecord record : lessonRecords) {
                if (record.getLearningCategory() != null) {
                    counts[0] += record.getLearningCategory().getCooperation();
                    counts[1] += record.getLearningCategory().getInteraction();
                    counts[2] += record.getLearningCategory().getTask();
                    counts[3] += record.getLearningCategory().getExam();
                    counts[4] += record.getLearningCategory().getDiffential();
                }
            }

            for (int i = 0; i < keys.length; i++) {
                LearningCategory.put(keys[i], counts[i]);
            }
        }catch (Exception e) {
            throw new ServiceException(ErrorCode.SYSTEM_ERROR.getCode(), "数据转换错误");

        }
        return LearningCategory;
    }

    @Override
    public Map<String, Object> getTeacherGradeCount(TeacherDto teacherDto, HttpServletRequest request) {

        Map<String, Object> gradeMap;
        String url = env.getProperty("ies.server-url-get-teacher-grade-count");
        try {
            gradeMap =  GroupUtil.getGroupId(teacherDto,new GroupUtil(env), request,url);
        }catch (Exception e) {
            throw new ServiceException(ErrorCode.SYSTEM_ERROR.getCode(), "数据转换错误");

        }
        return gradeMap;
    }

    private static @NotNull Map<String, Integer> getStringIntegerMap(List<School.Subject> subjects, List<SchoolTeacher> schoolTeachers) {
        Map<String, String> subjectNameMap = new HashMap<>();
        for (School.Subject subject : subjects) {
            subjectNameMap.put(subject.getId(), subject.getName());
        }
        Map<String, Integer> subjectCountMap = new HashMap<>();

        // 遍历所有教师
        for (SchoolTeacher teacher : schoolTeachers) {
            // 获取教师的科目列表
            List<String> subjectIds = teacher.getSubjectIds();
            if (subjectIds != null) {
                for (String subjectId : subjectIds) {
                    // 更新每个科目的教师数量
                    subjectCountMap.put(subjectId, subjectCountMap.getOrDefault(subjectId, 0) + 1);
                }
            }
        }
        Map<String, Integer> updatedSubjectCountMap = new HashMap<>();
        for (Map.Entry<String, Integer> entry : subjectCountMap.entrySet()) {
            String subjectId = entry.getKey();
            Integer count = entry.getValue();
            String subjectName = subjectNameMap.get(subjectId);
            if (subjectName != null) {
                updatedSubjectCountMap.put(subjectName, count);
            }
        }
        return updatedSubjectCountMap;
    }

    private static @NotNull Map<String, Integer> getPeriodCountMap(List<School.Period> periods,List<SchoolTeacher> schoolTeachers) {

        Map<String, Integer> periodCountMap = new HashMap<>();
        for (School.Period period : periods) {
            for ( School.Subject subject : period.getSubjects()) {
                for (SchoolTeacher schoolTeacher : schoolTeachers) {
                    if (schoolTeacher.getSubjectIds().contains(subject.getId())) {
                        periodCountMap.put(period.getId(), periodCountMap.getOrDefault(period.getId(), 0) + 1);
                    }
                }
            }
        }
        Map<String, String> periodNameMap = new HashMap<>();
        List<String> periodNames = new ArrayList<>();
        for (School.Period period : periods) {
            periodNameMap.put(period.getId(), period.getName());
            periodNames.add(period.getName());
        }
        //Map<String, Integer> periodCountMap = getStringIntegerMap(groupLists);
        // 更新 periodCountMap 的 key 为 period 名称
        Map<String, Integer> updatedPeriodCountMap = new HashMap<>();
        for (Map.Entry<String, Integer> entry : periodCountMap.entrySet()) {
            String periodId = entry.getKey();
            Integer count = entry.getValue();
            String periodName = periodNameMap.get(periodId);
            if (periodName != null) {
                updatedPeriodCountMap.put(periodName, count);
            }
        }
        for (String periodName : periodNames) {
            if(!updatedPeriodCountMap.containsKey(periodName)) {
                updatedPeriodCountMap.put(periodName, 0);
            }
        }
        return updatedPeriodCountMap;
    }

    /*private static @NotNull Map<String, Integer> getStringIntegerMap(List<GroupList> groupLists) {
        Map<String, Integer> periodCountMap = new HashMap<>();
        // 遍历所有 GroupList 对象
        for (GroupList group : groupLists) {
            // 获取 periodId
            String periodId = group.getPeriodId();
            if (periodId != null) {
                    // 计算成员数量
                    int memberCount = (int) group.getMembers().stream().filter(member -> member.type == 1).count();
                    // 更新 periodCountMap
                    periodCountMap.put(periodId, periodCountMap.getOrDefault(periodId, 0) + memberCount);

            }
        }
        return periodCountMap;
    }*/
}
