package com.xjrsoft.module.student.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xjrsoft.common.enums.DeleteMark;
import com.xjrsoft.common.enums.GenderDictionaryEnum;
import com.xjrsoft.common.model.result.R;
import com.xjrsoft.common.model.result.RT;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.TreeUtil;
import com.xjrsoft.module.base.entity.BaseClass;
import com.xjrsoft.module.base.entity.BaseGrade;
import com.xjrsoft.module.base.service.IBaseClassService;
import com.xjrsoft.module.base.service.IBaseGradeService;
import com.xjrsoft.module.concat.service.IXjrUserService;
import com.xjrsoft.module.organization.entity.UserDeptRelation;
import com.xjrsoft.module.organization.service.IUserDeptRelationService;
import com.xjrsoft.module.room.service.IRoomBedService;
import com.xjrsoft.module.student.dto.AddBaseStudentUserDto;
import com.xjrsoft.module.student.dto.BaseStudentUserPageDto;
import com.xjrsoft.module.student.dto.UpdateBaseStudentUserDto;
import com.xjrsoft.module.student.entity.BaseStudentUser;
import com.xjrsoft.module.student.service.IStudentManagerService;
import com.xjrsoft.module.student.vo.BaseStudentSchoolRollVo;
import com.xjrsoft.module.student.vo.BaseStudentTreeVo;
import com.xjrsoft.module.student.vo.BaseStudentUserPageVo;
import com.xjrsoft.module.student.vo.BaseStudentUserVo;
import com.xjrsoft.module.teacher.entity.XjrUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/student" + "/studentmanager")
@Api(value = "/student" + "/studentmanager", tags = "学生基本信息管理代码")
@AllArgsConstructor
public class StudentManagerController {

    private final IStudentManagerService studentManagerService;
    private final IBaseGradeService baseGradeService;
    private final IBaseClassService baseClassService;
    private final IXjrUserService xjrUserService;
    private final IRoomBedService roomBedService;
    private final IUserDeptRelationService userDeptRelationService;
    @GetMapping(value = "/page")
    @ApiOperation(value = "学生列表(分页)")
    @SaCheckPermission("studentmanager:detail")
    public R page(@Valid BaseStudentUserPageDto dto) {

        IPage<BaseStudentUserPageVo> page = studentManagerService.getStudentPage(new Page<>(dto.getLimit(), dto.getSize()), dto);
        PageOutput<BaseStudentUserPageVo> pageOutput = ConventPage.getPageOutput(page, BaseStudentUserPageVo.class);
        return R.ok(pageOutput);
    }

    @GetMapping(value = "/tree")
    @ApiOperation(value = "学生年纪班级树")
    @SaCheckPermission("studentmanager:detail")
    public RT<List<BaseStudentTreeVo>> tree() {
        List<String> roleList = StpUtil.getRoleList();

        long teacherId = StpUtil.getLoginIdAsLong();
        List<BaseClass> classList = baseClassService.list(
            new QueryWrapper<BaseClass>().lambda().eq(BaseClass::getDeleteMark, DeleteMark.NODELETE.getCode())
        );
        List<BaseStudentTreeVo> voList = new ArrayList<>();

        List<BaseGrade> gradeList = baseGradeService.list(
            new QueryWrapper<BaseGrade>().lambda().eq(BaseGrade::getDeleteMark, DeleteMark.NODELETE.getCode())
        );
        if(roleList.size() == 2 && roleList.contains("CLASSTE") && roleList.contains("TEACHER")){
            Set<Long> gradeSet = new HashSet<>();
            for (BaseClass baseClass : classList) {
                if(baseClass.getTeacherId().equals(teacherId)){
                    gradeSet.add(baseClass.getGradeId());
                    voList.add(new BaseStudentTreeVo(){{
                        setId(baseClass.getId());
                        setName(baseClass.getName());
                        setParentId(baseClass.getGradeId());
                    }});
                }
            }
            gradeList.forEach((node) -> {
                if(gradeSet.contains(node.getId())){
                    voList.add(new BaseStudentTreeVo(){{
                        setId(node.getId());
                        setName(node.getName());
                    }});
                }
            });

            List<BaseStudentTreeVo> treeVoList = TreeUtil.build(voList);

            return RT.ok(treeVoList);
        }
        gradeList.forEach((node) -> {
            voList.add(new BaseStudentTreeVo(){{
                setId(node.getId());
                setName(node.getName());
            }});
        });

        classList.forEach((node)->{
            voList.add(new BaseStudentTreeVo(){{
                setId(node.getId());
                setName(node.getName());
                setParentId(node.getGradeId());
            }});
        });

        List<BaseStudentTreeVo> treeVoList = TreeUtil.build(voList);

        return RT.ok(treeVoList);
    }

    @GetMapping(value = "/info")
    @ApiOperation(value = "根据id查询学生信息")
    @SaCheckPermission("studentmanager:detail")
    public R info(@RequestParam Long id) {
        BaseStudentUser baseStudentUser = studentManagerService.getByIdDeep(id);
        if (baseStudentUser == null) {
            return R.error("找不到此数据！");
        }
        BaseStudentUserVo userVo = BeanUtil.toBean(baseStudentUser, BaseStudentUserVo.class);

        for (BaseStudentSchoolRollVo roll : userVo.getBaseStudentSchoolRollList()) {
            BaseClass aClass = baseClassService.getById(roll.getClassId());
            XjrUser xjrUser = xjrUserService.getById(aClass.getTeacherId());
            if(xjrUser != null){
                roll.setTeacherName(xjrUser.getName());
            }


            String roomName = roomBedService.getRoomNameByStudentUserId(roll.getUserId());
            roll.setRoomName(roomName);
        }

        List<Long> deptIds = userDeptRelationService.list(Wrappers.lambdaQuery(UserDeptRelation.class)
                        .eq(UserDeptRelation::getUserId, userVo.getId()))
                .stream().map(UserDeptRelation::getDeptId).collect(Collectors.toList());
        String allDeptIdStr = StrUtil.join(StringPool.COMMA, deptIds);
        userVo.setDepartmentIds(allDeptIdStr);

        userVo.setGenderCn(GenderDictionaryEnum.getValue(userVo.getGender()));
        return R.ok(userVo);
    }


    @PostMapping
    @ApiOperation(value = "新增学生")
    @SaCheckPermission("studentmanager:add")
    public R add(@Valid @RequestBody AddBaseStudentUserDto dto) {
        return R.ok(studentManagerService.add(dto));
    }

    @PutMapping
    @ApiOperation(value = "修改学生")
    @SaCheckPermission("studentmanager:edit")
    public R update(@Valid @RequestBody UpdateBaseStudentUserDto dto) {


        return R.ok(studentManagerService.update(dto));

    }

    @DeleteMapping
    @ApiOperation(value = "删除")
    @SaCheckPermission("studentmanager:delete")
    public R delete(@Valid @RequestBody List<Long> ids) {
        return R.ok(studentManagerService.delete(ids));
    }

    @GetMapping(value = "/class")
    @ApiOperation(value = "获取当前学生的班主任")
    public R studentClass() {
        Long userId = StpUtil.getLoginIdAsLong();
        return R.ok(studentManagerService.getStudentClass(userId));
    }


    @PostMapping("/import")
    @ApiOperation(value = "导入学生信息")
    public RT<Boolean> importData(@RequestParam("file") MultipartFile file) throws IOException, ParseException {
        List<Map<Integer, Object>> excelDataList = EasyExcel.read(file.getInputStream()).sheet().headRowNumber(3).doReadSync();

        return RT.ok(studentManagerService.importStudentData(excelDataList));
    }
}
