package com.xjrsoft.module.schedule.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.xjrsoft.common.enums.DeleteMark;
import com.xjrsoft.common.enums.EnabledMark;
import com.xjrsoft.common.model.result.RT;
import com.xjrsoft.module.courseTable.entity.CourseTable;
import com.xjrsoft.module.courseTable.service.ICourseTableService;
import com.xjrsoft.module.schedule.dto.CourseTableAdjustDto;
import com.xjrsoft.module.schedule.dto.CourseTableDto;
import com.xjrsoft.module.schedule.dto.CourseTablePreCheckDto;
import com.xjrsoft.module.schedule.dto.ScheduleWeekExportQueryDto;
import com.xjrsoft.module.schedule.entity.CourseReceiveMsg;
import com.xjrsoft.module.schedule.service.ICourseReceiveMsgService;
import com.xjrsoft.module.schedule.util.ScheduleUtil;
import com.xjrsoft.module.schedule.vo.CourseListVo;
import com.xjrsoft.module.schedule.vo.CourseTableVo;
import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
import com.xjrsoft.module.student.service.IBaseStudentSchoolRollService;
import com.xjrsoft.module.teacher.entity.BaseTeacher;
import com.xjrsoft.module.teacher.entity.XjrUser;
import com.xjrsoft.module.teacher.service.IBaseTeacherService;
import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
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 javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

/**
* @title: 课表
* @Author dzx
* @Date: 2023-12-27
* @Version 1.0
*/
@RestController
@RequestMapping("/schedule" + "/schedule")
@Api(value = "/schedule"  + "/schedule",tags = "课表代码")
@AllArgsConstructor
public class ScheduleController {


    private final ICourseReceiveMsgService courseReceiveMsgService;
//    private final IJianyueDataService jianyueDataService;
    private final ICourseTableService courseTableService;
    private final IBaseStudentSchoolRollService baseStudentSchoolRollService;
    private final IBaseTeacherService baseTeacherService;
    private final ITeacherbaseManagerService teacherService;

    @GetMapping(value = "/receive-msg")
    @ApiOperation(value="接收消息")
    @SaCheckPermission("room:detail")
    public RT<CourseReceiveMsg> receiveMsg(@RequestParam String schoolId, @RequestParam String eduYearSerialNo, @RequestParam String startDate, @RequestParam String endDate) throws Exception {
        CourseReceiveMsg courseReceiveMsg = new CourseReceiveMsg();
        courseReceiveMsg.setCreateDate(new Date());
        courseReceiveMsg.setSchoolId(schoolId);
        courseReceiveMsg.setEduYearSerialNo(eduYearSerialNo);
        courseReceiveMsg.setStartDate(startDate);
        courseReceiveMsg.setEndDate(endDate);
        courseReceiveMsg.setDeleteMark(DeleteMark.NODELETE.getCode());
        courseReceiveMsg.setEnabledMark(EnabledMark.ENABLED.getCode());
        courseReceiveMsgService.save(courseReceiveMsg);

        return RT.ok(courseReceiveMsg);
    }

    @GetMapping(value = "/course-table")
    @ApiOperation(value="课表接口(PC端)")
    @SaCheckPermission("room:detail")
    public RT<CourseTableVo> courseInfo(CourseTableDto dto){
        CourseTableVo list = courseTableService.getList(dto);
        return RT.ok(list);
    }

    @GetMapping(value = "/course-table-day")
    @ApiOperation(value="今日课表接口(手机端)")
    @SaCheckPermission("room:detail")
    public RT<CourseTableVo> courseInfoDay(CourseTableDto dto){
        LocalDateTime now = LocalDateTime.now();
        DayOfWeek dayOfWeek = now.getDayOfWeek();
        dto.setWeekDay(dayOfWeek.getValue());
        dto.setToDay(now);
        if(ObjectUtil.isNotNull(dto.getStudentId())){
            List<BaseStudentSchoolRoll> schoolRolls = baseStudentSchoolRollService.list(
                    new QueryWrapper<BaseStudentSchoolRoll>().lambda().eq(BaseStudentSchoolRoll::getUserId, dto.getStudentId())
            );
            if(schoolRolls != null && !schoolRolls.isEmpty()){
                dto.setCourseType("class");
                dto.setClassId(schoolRolls.get(0).getClassId());
            }
        }else{
            // 查询登录者身份
            long loginIdAsLong = StpUtil.getLoginIdAsLong();
            List<BaseStudentSchoolRoll> schoolRolls = baseStudentSchoolRollService.list(
                    new QueryWrapper<BaseStudentSchoolRoll>().lambda().eq(BaseStudentSchoolRoll::getUserId, loginIdAsLong)
            );
            if(schoolRolls != null && !schoolRolls.isEmpty()){
                dto.setCourseType("class");
                dto.setClassId(schoolRolls.get(0).getClassId());
            }
            List<BaseTeacher> teachers = baseTeacherService.list(new QueryWrapper<BaseTeacher>().lambda().eq(BaseTeacher::getUserId, loginIdAsLong));
            if(teachers != null && !teachers.isEmpty()){
                dto.setCourseType("teacher");
                dto.setTeacherId(loginIdAsLong);
            }
        }

        CourseTableVo list = courseTableService.getList(dto);
        return RT.ok(list);
    }


    @GetMapping(value = "/adjust-list")
    @ApiOperation(value = "可以调课的课程")
    @SaCheckPermission("evaluateobject:detail")
    public RT<List<CourseListVo>> adjustList(CourseTableAdjustDto dto){
//        if(dto.getAdjustDate() == null || dto.getTeacherId() == null){
//            return RT.error("请传入调整日期和教师id");
//        }
//        List<CourseListVo> list = courseTableService.getAdjustList(dto);
//        if(list.isEmpty()){
//            return RT.error("暂无可调课程");
//        }
        return RT.ok();
    }

    @GetMapping(value = "/pre-check")
    @ApiOperation(value = "预检查")
    @SaCheckPermission("evaluateobject:detail")
    public RT<String> preCheck(CourseTablePreCheckDto dto) throws Exception {
        if(dto.getPreCheckType() != null){
            if(dto.getPreCheckType() == 1){
                CourseTable courseTable = courseTableService.getById(dto.getCourseId());
                CourseTable swapCourseTable = courseTableService.getById(dto.getSwapCourseId());
                JsonObject preCheck = getExtendPreCheck(dto, courseTable, swapCourseTable);
                if(!preCheck.get("data").getAsBoolean()){
                   return RT.error(preCheck.get("msg").getAsString());
                }
            }else if(dto.getPreCheckType() == 2){
                CourseTable courseTable = courseTableService.getById(dto.getCourseId());
                JsonObject jsonObject = substitutePreTestin(dto, courseTable);
                if(!jsonObject.get("data").getAsBoolean()){
                    return RT.error(jsonObject.get("msg").getAsString());
                }
            }
        }

        return RT.ok("ok");
    }

    /**
     *  顶课预检查
     * @param dto
     * @param courseTable
     * @return 检查结果
     */
    JsonObject substitutePreTestin(CourseTablePreCheckDto dto, CourseTable courseTable) throws Exception {
        JsonParser jsonParser = new JsonParser();
        String url = ScheduleUtil.apiUrl + "RescheduleApply/Extend/Substitute/PreTesting";
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("timetableId", courseTable.getJianyueId());
        jsonObject.addProperty("isCycles", Boolean.FALSE);
        JsonArray extendIds = new JsonArray();
        extendIds.add(dto.getSubTeacherId());
        jsonObject.add("extendIds", extendIds);
        //获取时间戳
        long timestamp = System.currentTimeMillis();
        //生成签名
        String sign = ScheduleUtil.createSign(timestamp);
        String result = ScheduleUtil.doPost(url, jsonObject.toString(), sign, timestamp);
        if(StrUtil.isEmpty(result)){
            return null;
        }

        return jsonParser.parse(result).getAsJsonObject();
    }

    /**
     *  调课预检查
     * @param courseTable 需要调整的课程
     * @param swapCourseTable 对调的课程
     * @return 检查结果
     */
    JsonObject getExtendPreCheck(CourseTablePreCheckDto dto, CourseTable courseTable, CourseTable swapCourseTable) throws Exception {
        JsonParser jsonParser = new JsonParser();
        String url = ScheduleUtil.apiUrl + "RescheduleApply/Extend/PreTesting";
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("timetableId", courseTable.getJianyueId());
        jsonObject.addProperty("isCycles", Boolean.FALSE);
//        jsonObject.addProperty("startDate", "2024-01-01");
//        jsonObject.addProperty("endDate", "2024-01-31");
//        jsonObject.addProperty("dayOfweek", 5);
        jsonObject.addProperty("numberOfday", swapCourseTable.getTimeNumber());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        jsonObject.addProperty("date", dto.getSwapDate().format(formatter));
        jsonObject.addProperty("reschduleId", courseTable.getJianyueId());

        //获取时间戳
        long timestamp = System.currentTimeMillis();
        //生成签名
        String sign = ScheduleUtil.createSign(timestamp);
        String result = ScheduleUtil.doPost(url, jsonObject.toString(), sign, timestamp);
        if(StrUtil.isEmpty(result)){
            return null;
        }

        return jsonParser.parse(result).getAsJsonObject();
    }

    @PostMapping("/schedule-week-export-query")
    @ApiOperation(value = "按周导出课表")
    public ResponseEntity<byte[]> scheduleWeekExportQuery(@Valid @RequestBody ScheduleWeekExportQueryDto dto) {
//    @GetMapping("/schedule-week-export-query")
//    @ApiOperation(value = "按周导出课表")
//    public ResponseEntity<byte[]> textbookClaimExportQuery(@Valid ScheduleWeekExportQueryDto dto) {

        ByteArrayOutputStream bot = courseTableService.listScheduleWeekExportQuery(dto);
        return RT.fileStream(bot.toByteArray(), "scheduleWeek" + ExcelTypeEnum.XLSX.getValue());
    }

    @GetMapping(value = "/login-url")
    @ApiOperation(value = "获取单点登录地址")
    @SaCheckPermission("evaluateobject:detail")
    public RT<String> getAccessToken() throws Exception {
        XjrUser xjrUser = teacherService.getById(StpUtil.getLoginIdAsLong());
        long timeMillis = System.currentTimeMillis();
        String sign = ScheduleUtil.createSign(timeMillis);

        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("mobileNo", xjrUser.getMobile());

        String url = ScheduleUtil.apiUrl + "auth/user/token";
        try {
            String result = ScheduleUtil.doPost(url, jsonObject.toString(), sign, timeMillis);
            JsonParser parser = new JsonParser();
            JsonObject resultJson = parser.parse(result).getAsJsonObject();
            if(resultJson.get("code").getAsInt() != 0){
                return RT.error("无登录权限");
            }
            JsonObject dataJson = resultJson.get("data").getAsJsonObject();
            String loginUrl = ScheduleUtil.hostUrl + "?access_token=" + dataJson.get("access_token").getAsString();
            return RT.ok(loginUrl);
        }catch (Exception e){
            return RT.error(e.getMessage());
        }
    }
}