package com.qmth.distributed.print.api;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.reflect.TypeToken;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.distributed.print.business.bean.dto.CourseWeightDetailDto;
import com.qmth.distributed.print.business.bean.dto.CourseWeightDto;
import com.qmth.distributed.print.business.bean.dto.TCUsualScoreDto;
import com.qmth.distributed.print.business.bean.excel.ExcelField;
import com.qmth.distributed.print.business.bean.result.ObeCourseWeightResult;
import com.qmth.distributed.print.business.bean.result.EditResult;
import com.qmth.distributed.print.business.bean.result.ScoreResult;
import com.qmth.distributed.print.business.entity.TCUsualScore;
import com.qmth.distributed.print.business.service.PrintCommonService;
import com.qmth.distributed.print.business.service.TCUsualScoreService;
import com.qmth.distributed.print.business.service.TRBasicInfoService;
import com.qmth.teachcloud.common.annotation.OperationLogDetail;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.log.OperationTypeEnum;
import com.qmth.teachcloud.common.util.GsonUtil;
import com.qmth.teachcloud.common.util.Result;
import com.qmth.teachcloud.common.util.ResultUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 平常作业成绩表 前端控制器
 * </p>
 *
 * @author wangliang
 * @since 2024-02-18
 */
@Api(tags = "课程目标达成度-成绩管理-平常作业成绩Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_COURSE_DEGREE)
public class TCUsualScoreController {
    private final static Logger log = LoggerFactory.getLogger(TCUsualScoreController.class);

    @Resource
    TCUsualScoreService tcUsualScoreService;

    @Resource
    PrintCommonService printCommonService;

    @Resource
    TRBasicInfoService trBasicInfoService;

    @ApiOperation(value = "成绩管理列表")
    @RequestMapping(value = "/score/list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "分页查询", response = ScoreResult.class)})
    public Result scoreList(@ApiParam(value = "学期ID", required = true) @RequestParam Long semesterId,
                            @ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
                            @ApiParam(value = "课程编码") @RequestParam(required = false) String courseCode,
                            @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                            @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
        if (semesterId == null) {
            throw ExceptionResultEnum.SEMESTER_ID_IS_NULL.exception();
        }
        if (examId == null) {
            throw ExceptionResultEnum.EXAM_ID_IS_NULL.exception();
        }
        return ResultUtil.ok(printCommonService.scoreList(new Page<>(pageNumber, pageSize), examId, courseCode));
    }

    @ApiOperation(value = "导入平时成绩-模板下载")
    @RequestMapping(value = "/usual_score/template_download", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.EXPORT)
    @ApiResponses({@ApiResponse(code = 200, message = "下载成功", response = Object.class)})
    public void usualScoreTemplateDownload(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
                                           @ApiParam(value = "科目编码", required = true) @RequestParam String courseCode,
                                           @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                                           @ApiParam(value = "教学课程id", required = true) @RequestParam Long teachCourseId) throws IOException {
        ObeCourseWeightResult obeCourseWeightResult = trBasicInfoService.findCourseWeightResultRmi(teachCourseId);
        List<CourseWeightDto> courseWeightDtoList = obeCourseWeightResult.getSubmitForm();

        List<ExcelField> excelFieldList = new ArrayList<>();
        excelFieldList.addAll(new ArrayList<>(Arrays.asList(new ExcelField("studentCode", "学号", true), new ExcelField("name", "姓名", true))));
        courseWeightDtoList.stream().peek(e -> {
            List<CourseWeightDetailDto> courseWeightDetailDtoList = e.getEvaluationList();
            courseWeightDetailDtoList.stream().peek(s -> {
                if (Objects.nonNull(s.getEnable()) && s.getEnable() && !Objects.equals(s.getEvaluationName(), SystemConstant.FINAL_SCORE_STR)) {
                    excelFieldList.add(new ExcelField(s.getEvaluationName(), s.getEvaluationName(), true));
                }
            }).collect(Collectors.toList());
        }).collect(Collectors.toList());
        printCommonService.scoreDownLoadExaminationTemplate("1、所有字段均为必填字段；\n" +
                "2、平时成绩各项数据均需要填写；\n" +
                "3、请不要删除此行，也不要删除模板中的任何列。\n" +
                "4、使用前请先删除样例数据。", "sheet1", "平时成绩导入模版", excelFieldList);
    }

    @ApiOperation(value = "导入平时成绩")
    @RequestMapping(value = "/usual_score/import", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.IMPORT)
    @ApiResponses({@ApiResponse(code = 200, message = "导入成功", response = EditResult.class)})
    public Result usualScoreImport(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
                                   @ApiParam(value = "考试id", required = true) @RequestParam Long examId,
                                   @ApiParam(value = "科目编码", required = true) @RequestParam String courseCode,
                                   @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                                   @ApiParam(value = "教学课程id", required = true) @RequestParam Long teachCourseId) throws IOException {
        return ResultUtil.ok(tcUsualScoreService.usualScoreExcelImport(file, examId, courseCode, paperNumber, teachCourseId));
    }

    @ApiOperation(value = "平时成绩列表")
    @RequestMapping(value = "/usual_score/list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "分页查询", response = TCUsualScore.class)})
    public Result usualScoreList(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
                                 @ApiParam(value = "科目编码", required = true) @RequestParam String courseCode,
                                 @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                                 @ApiParam(value = "教学课程id", required = true) @RequestParam Long teachCourseId,
                                 @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                                 @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) throws IOException {
        return ResultUtil.ok(tcUsualScoreService.usualScoreList(new Page<>(pageNumber, pageSize), examId, courseCode, paperNumber, teachCourseId));
    }

    @ApiOperation(value = "平时成绩编辑")
    @RequestMapping(value = "/usual_score/edit", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.SAVE)
    @ApiResponses({@ApiResponse(code = 200, message = "编辑", response = TCUsualScore.class)})
    public Result usualScoreEdit(@ApiParam(value = "主键", required = true) @RequestParam Long id) throws IOException {
        TCUsualScore tcUsualScore = tcUsualScoreService.getById(id);
        Objects.requireNonNull(tcUsualScore, "未找到平时成绩信息");
        return ResultUtil.ok(tcUsualScore);
    }

    @ApiOperation(value = "平时成绩保存")
    @RequestMapping(value = "/usual_score/save", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.UPDATE)
    @ApiResponses({@ApiResponse(code = 200, message = "保存", response = EditResult.class)})
    @Transactional
    public Result usualScoreSave(@ApiParam(value = "平时成绩信息", required = true) @Valid @RequestBody TCUsualScore tcUsualScore, BindingResult bindingResult) throws IOException {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        List<TCUsualScoreDto> tcFinalScoreDtoList = GsonUtil.fromJson(tcUsualScore.getScore(), new TypeToken<List<TCUsualScoreDto>>() {
        }.getType());
        tcFinalScoreDtoList.stream().peek(e -> {
            BigDecimal score = new BigDecimal(e.getScore());
            if (score.compareTo(SystemConstant.PERCENT) == 1) {
                throw ExceptionResultEnum.ERROR.exception("[" + e.getName() + "]分数不能大于试卷总分");
            }
        }).collect(Collectors.toList());

        TCUsualScore tcUsualScoreDb = tcUsualScoreService.getById(tcUsualScore.getId());
        Objects.requireNonNull(tcUsualScoreDb, "未找到平时成绩信息");

        TCUsualScore tcUsualScoreSource = new TCUsualScore();
        BeanUtils.copyProperties(tcUsualScoreDb, tcUsualScoreSource);

        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        tcUsualScoreDb.updateInfo(tcUsualScore, sysUser.getId());
        if (!tcUsualScoreSource.equals(tcUsualScoreDb)) {
            trBasicInfoService.clearReportData(tcUsualScoreDb.getExamId(), tcUsualScoreDb.getCourseCode(), tcUsualScoreDb.getPaperNumber(), tcUsualScoreDb.getTeachCourseId(), false);
            tcUsualScoreService.updateById(tcUsualScoreDb);
        }
        return ResultUtil.ok(true);
    }

    @ApiOperation(value = "平时成绩启用/禁用")
    @RequestMapping(value = "/usual_score/enable", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.UPDATE)
    @ApiResponses({@ApiResponse(code = 200, message = "编辑", response = EditResult.class)})
    @Transactional
    public Result usualScoreEnable(@ApiParam(value = "主键", required = true) @RequestParam Long id,
                                   @ApiParam(value = "启用/禁用", required = true) @RequestParam Boolean enable) throws IOException {
        TCUsualScore tcUsualScoreDb = tcUsualScoreService.getById(id);
        Objects.requireNonNull(tcUsualScoreDb, "未找到平时成绩信息");

        TCUsualScore tcUsualScoreSource = new TCUsualScore();
        BeanUtils.copyProperties(tcUsualScoreDb, tcUsualScoreSource);
        tcUsualScoreDb.setEnable(enable);
        if (!tcUsualScoreSource.equals(tcUsualScoreDb)) {
            SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
            tcUsualScoreDb.updateInfo(sysUser.getId());
            trBasicInfoService.clearReportData(tcUsualScoreDb.getExamId(), tcUsualScoreDb.getCourseCode(), tcUsualScoreDb.getPaperNumber(), tcUsualScoreDb.getTeachCourseId(), false);
            tcUsualScoreService.updateById(tcUsualScoreDb);
        }
        return ResultUtil.ok(true);
    }
}
