package com.yida.data.user.controller;


import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yida.data.common.core.common.ModuleName;
import com.yida.data.common.core.common.ResultBean;
import com.yida.data.common.core.entity.CurrentUser;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.system.Dept;
import com.yida.data.common.core.entity.system.enums.DeptTypeEnum;
import com.yida.data.common.core.entity.system.enums.OperationLogTypeEnum;
import com.yida.data.common.core.entity.user.EduStudent;
import com.yida.data.common.core.entity.user.EduTeacherDept;
import com.yida.data.common.core.enums.FileDealStatusEnum;
import com.yida.data.common.core.exception.FebsException;
import com.yida.data.common.core.file.common.export.ExportExcelData;
import com.yida.data.common.core.file.common.export.ExportLargeData;
import com.yida.data.common.core.utils.FebsUtil;
import com.yida.data.common.core.utils.FileUtil;
import com.yida.data.log.annotation.OperationLog;
import com.yida.data.school.dto.transaction.ListBuyStudentDTO;
import com.yida.data.system.feign.RemoteDeptService;
import com.yida.data.user.dto.ListStudentDTO;
import com.yida.data.user.dto.PageStudentDTO;
import com.yida.data.user.service.EduParentService;
import com.yida.data.user.service.EduStaffService;
import com.yida.data.user.service.EduStudentService;
import com.yida.data.user.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 学生管理
 */
@Api(tags = "学生管理")
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/student")
public class EduStudentController {

    private final EduStudentService eduStudentService;
    private final EduStaffService eduStaffService;
    private final EduParentService eduParentService;

    private final RemoteDeptService remoteDeptService;
    private final RedisService redisService;

    @ApiOperation("家长查询拥有的学生")
    @GetMapping("/listStudentByParent")
    public ResultBean<List<EduStudent>> listStudentByParent(@ApiParam("家长id") @RequestParam Long parentId,
                                                            @ApiParam("应用编码") @RequestParam(required = false) String applyCode) {
        return ResultBean.buildSuccess(parentId != null ? eduStudentService.listStudentByParent(parentId, applyCode)
                : new ArrayList<>());
    }

    @ApiOperation("查询学生列表数据")
    @GetMapping("/listStudentPage")
    @PreAuthorize("hasAuthority('student:view')")
    public ResultBean<IPage<EduStudent>> listStudentPage(PageStudentDTO dto) {
        IPage<EduStudent> list = eduStudentService.findStudentPage(dto);
        return ResultBean.buildSuccess(list);
    }

    @ApiOperation("保存学生信息 新增或编辑")
    @PostMapping("/saveStudent")
    @OperationLog(module = ModuleName.STUDENT, methods = "新增、修改学生", type = OperationLogTypeEnum.SAVE)
    @PreAuthorize("hasAuthority('student:edit')")
    public ResultBean saveStudent(@RequestBody EduStudent eduStudent) {
        eduStudentService.saveStudent(eduStudent, FebsUtil.getCurrentUser(), false);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("根据学生id查询学生详情")
    @GetMapping("/getStudent")
    public ResultBean<EduStudent> getStudent(@ApiParam("学生id") @RequestParam("id") Long id) {
        EduStudent eduStudent = eduStudentService.getStudent(id);
        return ResultBean.buildSuccess(eduStudent);
    }

    @ApiOperation("批量删除学生")
    @PostMapping("/delStudentBatch")
    @OperationLog(module = ModuleName.STUDENT, methods = "批量删除学生", type = OperationLogTypeEnum.DELETE)
    @PreAuthorize("hasAuthority('student:delete')")
    public ResultBean delStudentBatch(@RequestBody List<Long> ids) {
        //批量删除学生信息
        eduStudentService.delStudentBatchIds(ids, false);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("导入学生(压缩包导入)")
    @PostMapping("/import")
    public ResultBean importStudent(@RequestParam("file") MultipartFile file,
                                    @RequestParam("schoolId") Long schoolId) {
        long key = System.currentTimeMillis();
        CurrentUser currentUser = FebsUtil.getCurrentUser();
        Map<Object, Object> map = redisService.hmget(CachePrefixConstant.IMPORT_STUDENT_KEY + currentUser.getUsername());
        if (CollUtil.size(map) >= 5) {
            throw new FebsException("上传文件已达最大值，请稍后重试");
        }
        redisService.hset(CachePrefixConstant.IMPORT_STUDENT_KEY + currentUser.getUsername(), Long.toString(key), 0);
        redisService.hset(CachePrefixConstant.IMPORT_STUDENT_FILE + currentUser.getUsername(), Long.toString(key),
                file.getOriginalFilename());
        eduStudentService.importStudent(FileUtil.uploadMultipartFile(file), currentUser,
                schoolId, System.currentTimeMillis(), file.getName());
        return ResultBean.buildSuccess();
    }

    @ApiOperation("学生导入信息进度")
    @GetMapping("/importStudentHeartbeat")
    public ResultBean<Integer> importStaffHeartbeat(Long key) {
        return ResultBean.buildSuccess(eduStudentService.importStaffHeartbeat(FebsUtil.getCurrentUsername(), key));
    }

    @ApiOperation("导入文件列表key值查询,percent,filename")
    @GetMapping("/listImportKey")
    public ResultBean<List<Map<String, String>>> listImportKey() {
        return ResultBean.buildSuccess(eduStudentService.listImportKey(FebsUtil.getCurrentUsername()));
    }

    @ApiOperation("下载导入模板(学生照片和信息导入模板)")
    @GetMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response) {
        eduStudentService.downloadTemplate(response, FebsUtil.getCurrentUser());
    }

    @ApiOperation("校园卡号导入")
    @PostMapping("/importCard")
    public ResultBean<String> importCard(@RequestParam("file") MultipartFile file,
                                         @RequestParam("schoolId") Long schoolId) {
        long key = System.currentTimeMillis();
        CurrentUser currentUser = FebsUtil.getCurrentUser();
        Map<Object, Object> map = redisService.hmget(CachePrefixConstant.IMPORT_STUDENT_CARD_NUMBER_KEY +
                currentUser.getUsername());
        if (CollUtil.size(map) >= 5) {
            throw new FebsException("上传文件已达最大值，请稍后重试");
        }
        redisService.hset(CachePrefixConstant.IMPORT_STUDENT_CARD_NUMBER_KEY + currentUser.getUsername(), Long.toString(key), 0);
        eduStudentService.importCard(FileUtil.uploadMultipartFile(file), currentUser,
                schoolId, System.currentTimeMillis(), file.getName());
        return ResultBean.buildSuccess();
    }

    @ApiOperation("下载导入模板(校园卡号)")
    @GetMapping("/downloadCardTemplate")
    public void downloadCardTemplate(HttpServletResponse response) {
        eduStudentService.downloadCardTemplate(response, FebsUtil.getCurrentUser());
    }

    @ApiOperation("统计班上学生数量")
    @GetMapping("/countStudentNum")
    public ResultBean countStudentNum(@ApiParam("班级id") Long classId) {
        return ResultBean.buildSuccess(
                eduStudentService.count(Wrappers.lambdaQuery(new EduStudent()).eq(EduStudent::getClassId, classId)));
    }

    @ApiOperation("根据企业微信通讯录初始化学生")
    @PostMapping("/initStudent")
    @PreAuthorize("hasAuthority('student:edit')")
    public ResultBean initStudent(@RequestBody List<EduStudent> student) {
        eduStudentService.initStudent(student);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("查询学生班级信息")
    @GetMapping("/getClassInfoByStudent")
    public ResultBean<StudentClassInfoVO> getClassInfoByStudent(@ApiParam("学生id") Long studentId,
                                                                @ApiParam("家长手机号") String parentMobile) {
        return ResultBean.buildSuccess(eduStudentService.getClassInfoByStudent(studentId, parentMobile));
    }

    @ApiOperation("根据教师查询家长列表")
    @GetMapping("/listParentByTeacher")
    public ResultBean listParentByTeacher(@ApiParam("教师id") Long teacherId,
                                          @ApiParam("家长名称") String parentName) {
        List<EduTeacherDept> teacherRole = eduStaffService.listTeacherDept(teacherId);
        if (CollUtil.isNotEmpty(teacherRole)) {
            List<Long> classIds = teacherRole.stream().map(EduTeacherDept::getClassId).filter(Objects::nonNull)
                    .collect(Collectors.toList());
            if (CollUtil.isNotEmpty(classIds)) {
                List<ParentInfoVO> parentInfoVOList = eduParentService.listParentByClass(classIds, parentName);
                return ResultBean.buildSuccess(parentInfoVOList);
            }
        }
        return ResultBean.buildSuccess();
    }

    @ApiOperation("根据手机号和学校id查询班级信息")
    @PostMapping("/getParentByPhoneAndSchoolId")
    public ResultBean<List<String>> getParentByPhoneAndSchoolId(@RequestBody List<String> phone, @RequestParam Long schoolId) {
        List<String> list = eduStudentService.getParentByPhoneAndSchoolId(phone, schoolId);
        return ResultBean.buildSuccess(list);
    }

    @ApiOperation("查询未购买该商品的学生")
    @PostMapping("/listNotBuyStudent")
    public ResultBean<Page<EduStudent>> listNotBuyStudent(@RequestBody ListBuyStudentDTO dto) {
        return ResultBean.buildSuccess(eduStudentService.listNotBuyStudent(dto));
    }

    @ApiOperation("通过学生id查询学生和家长信息")
    @PostMapping("/listParentByStudentIds")
    public ResultBean<List<ListParentByStudentIdsVO>> listParentByStudentIds(@RequestBody List<Long> studentIds) {
        return ResultBean.buildSuccess(eduStudentService.listParentByStudentIds(studentIds));
    }

    @ApiOperation("根据条件查询学生列表")
    @PostMapping("/listStudent")
    public ResultBean<List<EduStudent>> listStudent(@RequestBody ListStudentDTO dto) {
        CurrentUser currentUser = FebsUtil.getCurrentUser();
        if (DeptTypeEnum.SCHOOL_TYPE.getValue().equals(currentUser.getDeptType())) {
            dto.setSchoolId(currentUser.getDeptId());
        }
        return ResultBean.buildSuccess(eduStudentService.listStudent(dto));
    }

    @ApiOperation("导出学生数据")
    @PostMapping("/exportStudent")
    public ResultBean<ExportExcelData> exportStudent(@RequestBody PageStudentDTO dto) {

        String key = IdUtil.simpleUUID();
        ExportExcelData vo = ExportExcelData.builder()
                .key(key)
                .exportStatus(FileDealStatusEnum.DEALING.getStatus())
                // 初始化数据
                .total(1)
                .finish(0)
                .build();

        redisService.hset(CachePrefixConstant.EXPORT_STUDENT_DATA, key, vo);
        // 异步导出学生数据
        eduStudentService.exportStudent(dto, key);
        return ResultBean.buildSuccess(vo);
    }

    @ApiOperation("查询导出学生详情")
    @GetMapping("/getStudentExportInfo")
    public ResultBean<Object> getExportRosterPicInfo(@RequestParam String key) {
        return ResultBean.buildSuccess(eduStudentService.getStudentExportInfo(key));
    }

    @ApiOperation("解除学生与宿舍的绑定")
    @PostMapping("/unbindDormRoom")
    public ResultBean unbindDormRoom(@RequestBody List<Long> dormIds) {
        eduStudentService.update(Wrappers.<EduStudent>lambdaUpdate()
                .in(EduStudent::getDormRoomId, dormIds)
                .set(EduStudent::getDormRoomId, null));
        return ResultBean.buildSuccess();
    }

    @ApiOperation("统计学生分布数据")
    @PostMapping("/staStudentDistribu")
    public ResultBean<StaStudentVO> staStudentDistribu() {
        List<Long> schoolIds = remoteDeptService.getSchoolByArea(null, null).getData().stream().map(Dept::getDeptId).collect(
                Collectors.toList());
        return ResultBean.buildSuccess(eduStudentService.staStudentDistribu(schoolIds));
    }


    @ApiOperation("下载采集学生照片")
    @PostMapping("/downloadStudentPic")
    public ResultBean<DownLoadPicVO> downloadStudentPic(@RequestBody PageStudentDTO dto) {
        DownLoadPicVO vo = eduStudentService.exportStudentPic(dto);
        return ResultBean.buildSuccess(vo);
    }

    @ApiOperation("获取下载采集学生照片进度")
    @GetMapping("/downloadStudentPicProgress")
    public ResultBean<DownLoadPicVO> downloadStudentPicProgress(String key) {
        DownLoadPicVO dto = (DownLoadPicVO) redisService.hget(CachePrefixConstant.USER_PIC_DOWNLOAD, key);
        return ResultBean.buildSuccess(dto);
    }

    @ApiOperation("批量导入学生类型")
    @PostMapping("/importStudentUpdateType")
    public ResultBean importStudentUpdateType(@RequestParam("file") MultipartFile file,
                                              @RequestParam("schoolId") Long schoolId) {
        eduStudentService.importStudentUpdateType(file, schoolId);
        return ResultBean.buildSuccess();
    }

    @ApiOperation("批量导入学生类型:导入进度")
    @GetMapping("/importStudentDormPercent")
    public ResultBean importStudenrTypePercent() {
        CurrentUser currentUser = FebsUtil.getCurrentUser();
        return ResultBean.buildSuccess(redisService.hget(CachePrefixConstant.IMPORT_STUDENT_TYPE,
                currentUser.getUserId().toString()));
    }

    @ApiOperation("根据班级ID查询学生")
    @GetMapping("/listStudentByClassId")
    public ResultBean<List<EduStudent>> listStudentByClassId(
            @ApiParam(required = true, value = "班级ID") @RequestParam Long classId) {
        List<EduStudent> studentList = eduStudentService.listStudentByClassId(ListStudentDTO.builder().classId(classId).build());
        return ResultBean.buildSuccess(studentList);
    }
}
