package com.ruoyi.web.controller.dz;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.dz.domain.DzClasses;
import com.ruoyi.dz.domain.DzTeacher;
import com.ruoyi.dz.domain.DzTeacherClass;
import com.ruoyi.dz.service.IDzClassesService;
import com.ruoyi.dz.service.IDzTeacherClassService;
import com.ruoyi.dz.service.IDzAgentService;
import com.ruoyi.dz.domain.DzAgent;
import com.ruoyi.enums.UserTypeEnum;
import com.ruoyi.system.service.ISysUserService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.dz.service.IDzTeacherService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import javax.validation.ValidationException;

/**
 * 老师Controller
 *
 * @author ruoyi
 * @date 2025-09-12
 */
@RestController
@RequestMapping("/dz/teacher")
public class DzTeacherController extends BaseController
{
    @Autowired
    private IDzTeacherService dzTeacherService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private IDzClassesService dzClassesService;
    @Autowired
    private IDzTeacherClassService dzTeacherClassService;
    @Autowired
    private IDzAgentService agentService;

    /**
     * 查询老师列表
     */
    @PreAuthorize("@ss.hasPermi('dz:teacher:list')")
    @GetMapping("/list")
    public TableDataInfo list(DzTeacher dzTeacher)
    {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (UserTypeEnum.isAgent(sysUser.getUserType())) {
            dzTeacher.setAgentId(sysUser.getUserTypeId());
        } else if(!UserTypeEnum.isSys(sysUser.getUserType())){
            dzTeacher.setDeptId(SecurityUtils.getLoginUser().getUser().getDeptId());
            if (UserTypeEnum.isSchool(sysUser.getUserType())) {
                if(null == sysUser.getDeptId() || sysUser.getDeptId().equals(100L)) {
                    dzTeacher.setSchoolId(sysUser.getUserTypeId());
                } else {
                    dzTeacher.setCampusId(sysUser.getUserTypeId());
                }
            }
        }
        startPage();
        List<DzTeacher> list = dzTeacherService.selectDzTeacherList(dzTeacher);
        list =  processTeacherList(list);
        return getDataTable(list);
    }

    /**
     * 导出老师列表
     */
    @PreAuthorize("@ss.hasPermi('dz:teacher:export')")
    @Log(title = "老师", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DzTeacher dzTeacher)
    {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (UserTypeEnum.isAgent(sysUser.getUserType())) {
            dzTeacher.setAgentId(sysUser.getUserTypeId());
        } else if(!UserTypeEnum.isSys(sysUser.getUserType())){
            dzTeacher.setDeptId(SecurityUtils.getLoginUser().getUser().getDeptId());
            if (UserTypeEnum.isSchool(sysUser.getUserType())) {
                if(null == sysUser.getDeptId() || sysUser.getDeptId().equals(100L)) {
                    dzTeacher.setSchoolId(sysUser.getUserTypeId());
                } else {
                    dzTeacher.setCampusId(sysUser.getUserTypeId());
                }
            }
        }
        List<DzTeacher> list = dzTeacherService.selectDzTeacherList(dzTeacher);
        list =  processTeacherList(list);
        ExcelUtil<DzTeacher> util = new ExcelUtil<DzTeacher>(DzTeacher.class);
        util.exportExcel(response, list, "老师数据");
    }

    /**
     * 获取老师详细信息
     */
    @PreAuthorize("@ss.hasPermi('dz:teacher:query')")
    @GetMapping(value = "/{teacherId}")
    public AjaxResult getInfo(@PathVariable("teacherId") Long teacherId)
    {
        return success(dzTeacherService.selectDzTeacherByTeacherId(teacherId));
    }

    /**
     * 新增老师
     */
    @PreAuthorize("@ss.hasPermi('dz:teacher:add')")
    @Log(title = "老师", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody DzTeacher dzTeacher)
    {
        Long teacherId = dzTeacherService.insertDzTeacher(dzTeacher);

        processTeacherClass2(dzTeacher);

        return AjaxResult.success(teacherId);
    }

    private void processTeacherClass(DzTeacher dzTeacher) {
        Long teacherId = dzTeacher.getTeacherId();
        if (teacherId != null) {
            // 合并学校班级和校区班级ID
            List<Long> schoolClassIds = Arrays.asList(dzTeacher.getSchoolClassIds());
            List<Long> campusClassIds = Arrays.asList(dzTeacher.getCampusClassIds());

            // 如果有学校班级ID，则关联班级
            if (!schoolClassIds.isEmpty()) {
                processTeacherClass(teacherId, dzTeacher.getSchoolId(), schoolClassIds);
            }   
            // 如果有校区班级ID，则关联班级
            if (!campusClassIds.isEmpty()) {
                processTeacherClass(teacherId, dzTeacher.getSchoolId(), campusClassIds);
            }
        }
    }

    private void processTeacherClass(Long teacherId,Long schoolId, List<Long> schoolClassIds) {
        if (teacherId != null) {
            // 如果有学校班级ID，则关联班级
            if (!schoolClassIds.isEmpty()) {
                DzTeacherClass dzTeacherClass = new DzTeacherClass();
                dzTeacherClass.setTeacherId(teacherId);
                dzTeacherClass.setClassIds(schoolClassIds.toArray(new Long[0]));
                dzTeacherClass.setSchoolId(schoolId);
                dzTeacherClassService.batchBindTeacherClass(dzTeacherClass);
            }
        }
    }

    /**
     * 处理教师班级关系（先删除所有，再重新插入）
     * 删除该老师下面所有的班级后，重新插入页面上填写的内容
     */
    private void processTeacherClass2(DzTeacher dzTeacher) {
        // 1. 验证：学校班级和校区班级不能同时有值
        boolean hasSchoolClasses = dzTeacher.getSchoolId()!=null || (dzTeacher.getSchoolClassIds() != null && dzTeacher.getSchoolClassIds().length > 0);
        boolean hasCampusClasses = dzTeacher.getCampusClass()!=null || (dzTeacher.getCampusClassIds() != null && dzTeacher.getCampusClassIds().length > 0);
        if (hasSchoolClasses && hasCampusClasses) {
            throw new ValidationException("学校和培训校区只能二选一，不能同时选择学校班级和校区班级");
        }

        Long teacherId = dzTeacher.getTeacherId();
        if (teacherId != null) {
            // 2. 查询该老师的所有班级关系
            DzTeacherClass queryCondition = new DzTeacherClass();
            queryCondition.setTeacherId(teacherId);
            List<DzTeacherClass> existingList = dzTeacherClassService.selectDzTeacherClassList(queryCondition);
            
            // 3. 删除该老师的所有班级关系
            if (CollectionUtils.isNotEmpty(existingList)) {
                String[] ids = existingList.stream()
                        .map(DzTeacherClass::getId)
                        .filter(id -> id != null)
                        .map(String::valueOf)
                        .toArray(String[]::new);
                if (ids.length > 0) {
                    dzTeacherClassService.deleteDzTeacherClassByIds(ids);
                }
            }
            
            // 4. 合并学校班级和校区班级ID（只能有一个有值）
            List<Long> allClassIds = new java.util.ArrayList<>();
            Long schoolId = null;
            if (dzTeacher.getSchoolClassIds()!=null&&dzTeacher.getSchoolClassIds().length > 0) {
                schoolId = dzTeacher.getSchoolId();
                allClassIds.addAll(Arrays.asList(dzTeacher.getSchoolClassIds()));
            } else if (dzTeacher.getCampusClassIds()!=null && dzTeacher.getCampusClassIds().length > 0) {
                schoolId = dzTeacher.getCampusId();
                allClassIds.addAll(Arrays.asList(dzTeacher.getCampusClassIds()));
            }
            
            // 5. 重新插入页面上填写的内容
            if (!allClassIds.isEmpty()) {
                DzTeacherClass dzTeacherClass = new DzTeacherClass();
                dzTeacherClass.setTeacherId(teacherId);
                dzTeacherClass.setClassIds(allClassIds.toArray(new Long[0]));
                // 如果选择的是校区班级，使用campusId作为schoolId；否则使用schoolId
                dzTeacherClass.setSchoolId(schoolId);
                dzTeacherClassService.batchBindTeacherClass(dzTeacherClass);
            }
        }
    }

    /**
     * 修改老师
     */
    @PreAuthorize("@ss.hasPermi('dz:teacher:edit')")
    @Log(title = "老师", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody DzTeacher dzTeacher)
    {
        dzTeacherService.updateDzTeacher(dzTeacher);
        //处理班级关联
        processTeacherClass2(dzTeacher);
        //同时修改sys_user表的nickName
        SysUser user = userService.selectUserByUserName(String.valueOf(dzTeacher.getTeacherId()));
        if (null != user) {
            if (null == user.getNickName() || !user.getNickName().equalsIgnoreCase(dzTeacher.getName())) {
                user.setNickName(dzTeacher.getName());
                userService.updateUserInfo(user);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 删除老师
     */
    @PreAuthorize("@ss.hasPermi('dz:teacher:remove')")
    @Log(title = "老师", businessType = BusinessType.DELETE)
	@DeleteMapping("/{teacherIds}")
    public AjaxResult remove(@PathVariable Long[] teacherIds)
    {
        return toAjax(dzTeacherService.deleteDzTeacherByTeacherIds(teacherIds));
    }

    private List<DzTeacher> processTeacherList(List<DzTeacher> list) {
        // 批量查询用户信息，获取password2字段
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> userIds = list.stream()
                    .map(DzTeacher::getUserId).filter(userId -> userId != null)
                    .distinct().collect(Collectors.toList());
            if (!userIds.isEmpty()) {
                List<SysUser> users = userService.selectUserByUserIds(userIds);
                // 创建userId到SysUser的映射
                Map<Long, SysUser> userMap = users.stream()
                        .filter(user -> user.getUserId() != null)
                        .collect(Collectors.toMap(
                                SysUser::getUserId,
                                user -> user,
                                (existing, replacement) -> existing
                        ));
                // 设置每个teacher的password2
                list.forEach(teacher -> {
                    if (teacher.getUserId() != null && userMap.containsKey(teacher.getUserId())) {
                        teacher.setPassword2(userMap.get(teacher.getUserId()).getPassword2());
                        //设置状态
                        teacher.setStatus(userMap.get(teacher.getUserId()).getStatus());
                    }
                });
            }

            // 批量查询代理商信息，获取agentName字段
            List<Long> agentIds = list.stream()
                    .map(DzTeacher::getAgentId)
                    .filter(agentId -> agentId != null)
                    .distinct()
                    .collect(Collectors.toList());
            if (!agentIds.isEmpty()) {
                List<DzAgent> agentList = agentService.selectDzAgentByAgentIds(agentIds);
                Map<Long, String> agentMap = agentList.stream()
                        .filter(agent -> agent.getAgentId() != null && agent.getName() != null)
                        .collect(Collectors.toMap(
                                DzAgent::getAgentId,
                                DzAgent::getName,
                                (existing, replacement) -> existing
                        ));
                list.forEach(teacher -> {
                    if (teacher.getAgentId() != null && agentMap.containsKey(teacher.getAgentId())) {
                        teacher.setAgentName(agentMap.get(teacher.getAgentId()));
                    }
                });
            }

            // 批量查询班级信息，获取schoolClass和campusClass字段
            Set<Long> schoolIds = list.stream()
                    .flatMap(teacher -> java.util.stream.Stream.of(teacher.getSchoolId(),teacher.getCampusId()).filter(id -> id != null))
                    .collect(Collectors.toSet());
            Set<Long> teacherIds = list.stream().map(DzTeacher::getTeacherId).filter(id -> id != null).collect(Collectors.toSet());

            // 按teacherId分组，得到Map<Long, List<Long>>，key为teacherId，value为该教师关联的classId列表
            Map<Long, List<Long>> teacherClassMap = dzTeacherClassService.selectDzTeacherClassByTeacherIds(teacherIds).stream()
                    .filter(tc -> tc.getTeacherId() != null && tc.getClassId() != null)
                    .collect(Collectors.groupingBy(com.ruoyi.dz.domain.DzTeacherClass::getTeacherId,
                            Collectors.mapping(com.ruoyi.dz.domain.DzTeacherClass::getClassId,Collectors.toList())
                    ));
            if (!schoolIds.isEmpty()) {
                List<DzClasses> classesList = dzClassesService.selectDzClassesBySchoolIds(schoolIds);
                // 构建classId到DzClasses的映射
                Map<Long, DzClasses> classIdMap = classesList.stream()
                        .filter(clazz -> clazz.getClassId() != null)
                        .collect(Collectors.toMap(
                                DzClasses::getClassId,
                                clazz -> clazz,
                                (existing, replacement) -> existing
                        ));

                // 设置每个teacher的schoolClass和campusClass
                list.forEach(teacher -> {
                    if (teacherClassMap.containsKey(teacher.getTeacherId())) {
                        List<Long> classIds = teacherClassMap.get(teacher.getTeacherId());
                        // 根据schoolId分组，分别处理schoolClass和campusClass
                        List<String> schoolClassNames = new java.util.ArrayList<>();
                        List<String> campusClassNames = new java.util.ArrayList<>();

                        for (Long classId : classIds) {
                            DzClasses clazz = classIdMap.get(classId);
                            if (clazz != null && clazz.getName() != null) {
                                if (teacher.getSchoolId() != null && clazz.getSchoolId() != null
                                        && clazz.getSchoolId().equals(teacher.getSchoolId())) {
                                    schoolClassNames.add(clazz.getName());
                                }
                                if (teacher.getCampusId() != null && clazz.getSchoolId() != null
                                        && clazz.getSchoolId().equals(teacher.getCampusId())) {
                                    campusClassNames.add(clazz.getName());
                                }
                            }
                        }

                        // 用英文逗号连接并设置
                        if (!schoolClassNames.isEmpty()) {
                            teacher.setSchoolClass(String.join(",", schoolClassNames));
                        }
                        if (!campusClassNames.isEmpty()) {
                            teacher.setCampusClass(String.join(",", campusClassNames));
                        }
                    }
                });
            }
        }
        return list;
    }
}
