package yangtz.cs.liu.campus.controller.examination;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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.RestController;
import org.springframework.web.multipart.MultipartFile;
import yangtz.cs.liu.campus.constant.RecruitExamConstant;
import yangtz.cs.liu.campus.domain.recruit.EduRecruitStudent;
import yangtz.cs.liu.campus.domain.recruit.SchoolRecruitExam;
import yangtz.cs.liu.campus.domain.recruit.SchoolRecruitProject;
import yangtz.cs.liu.campus.domain.recruit.SchoolRecruitRelation;
import yangtz.cs.liu.campus.service.recruit.IEduRecruitStudentService;
import yangtz.cs.liu.campus.service.recruit.ISchoolRecruitExamService;
import yangtz.cs.liu.campus.service.recruit.ISchoolRecruitProjectService;
import yangtz.cs.liu.campus.service.recruit.ISchoolRecruitRelationService;
import yangtz.cs.liu.campus.service.recruit.ISchoolRecruitStudentService;
import yangtz.cs.liu.campus.vo.recruit.RecruitEduStudentVo;
import yangtz.cs.liu.campus.vo.recruit.RecruitExamAddressVo;
import yangtz.cs.liu.campus.vo.recruit.RecruitExamBackVo;
import yangtz.cs.liu.campus.vo.recruit.RecruitExamScoreVo;
import yangtz.cs.liu.campus.vo.recruit.SchoolRecruitExamVo;

/**
 * @author xuten
 */
@RestController
@RequestMapping("/recruitExam")
public class SchoolRecruitExamController extends BaseController {

  @Autowired
  private ISchoolRecruitExamService recruitExamService;

  @Autowired
  private ISchoolRecruitStudentService recruitStudentService;

  @Autowired
  private ISchoolRecruitRelationService recruitRelationService;

  @Autowired
  private IEduRecruitStudentService eduRecruitStudentService;

  @Autowired
  private ISchoolRecruitProjectService projectService;

  /**
   * 考务管理-考试管理-列表
   */
  @GetMapping("/list")
  public TableDataInfo list(SchoolRecruitExam exam) {
    startPage();
    return getDataTable(recruitExamService.queryList(exam));
  }

  /**
   * 考务管理-考试管理-新增时点击保存
   */
  @PostMapping("/add")
  public AjaxResult add(@RequestBody SchoolRecruitExamVo exam) {
    SchoolRecruitExam entity = new SchoolRecruitExam();
    BeanUtils.copyProperties(exam, entity);
    entity.setStatus(RecruitExamConstant.NOPUB);
    //将测试项目ids,整成id之间用逗号隔开的字符串
    String projectIds = StringUtils.join(exam.getProjectIdList(), ",");
    entity.setProjectIds(projectIds);
    entity.insert();
    return toAjax(recruitExamService.save(entity));
  }

  /**
   * 考务管理-考试管理-新增时点击发布
   */
  @PostMapping("/addPub")
  public AjaxResult addPub(@RequestBody SchoolRecruitExamVo exam) {
    SchoolRecruitExam entity = new SchoolRecruitExam();
    BeanUtils.copyProperties(exam, entity);
    entity.setStatus(RecruitExamConstant.INFOCHECK);
    //将测试项目ids,整成id之间用逗号隔开的字符串
    String projectIds = StringUtils.join(exam.getProjectIdList(), ",");
    entity.setProjectIds(projectIds);
    entity.insert();
    return toAjax(recruitExamService.save(entity));
  }

  /**
   * 考务管理-考试管理-获取详情
   */
  @GetMapping("/getInfo/{id}")
  public AjaxResult getInfo(@PathVariable Long id) {
    SchoolRecruitExam entity = recruitExamService.getById(id);
    SchoolRecruitExamVo exam = new SchoolRecruitExamVo();
    BeanUtils.copyProperties(entity, exam);
    //id之间用逗号隔开的字符串 整成Long数组
    String[] strArr = entity.getProjectIds().split(",");
    List<Long> projectIdList = new ArrayList<>();
    for (String str : strArr) {
      projectIdList.add(Long.parseLong(str));
    }

    //获取测试项目名
    LambdaQueryWrapper<SchoolRecruitProject> lqw = new LambdaQueryWrapper<>();
    lqw.in(SchoolRecruitProject::getId, projectIdList)
        .orderByDesc(SchoolRecruitProject::getCreateTime);
    List<SchoolRecruitProject> projects = projectService.list(lqw);
    exam.setProjectName(
        projects.stream().map(SchoolRecruitProject::getProject).collect(Collectors.joining(",")));
    exam.setProjectIdList(projectIdList);
    return AjaxResult.success(exam);
  }

  /**
   * 考务管理-考试管理-修改时点击保存
   */
  @PutMapping("/edit")
  public AjaxResult edit(@RequestBody SchoolRecruitExamVo exam) {
    if (StringUtils.isNull(exam.getId())) {
      throw new ServiceException("id为空,请检查");
    }
    SchoolRecruitExam entity = new SchoolRecruitExam();
    BeanUtils.copyProperties(exam, entity);
    //将测试项目ids,整成id之间用逗号隔开的字符串
    String projectIds = StringUtils.join(exam.getProjectIdList(), ",");
    entity.setProjectIds(projectIds);
    entity.update();
    return toAjax(recruitExamService.updateById(entity));
  }

  /**
   * 考务管理-考试管理-修改时点击发布（考试管理-点击未发布进入考试信息tab页的发布按钮也是这个按钮）
   */
  @PutMapping("/editPub")
  public AjaxResult editPub(@RequestBody SchoolRecruitExamVo exam) {
    if (StringUtils.isNull(exam.getId())) {
      throw new ServiceException("id为空,请检查");
    }
    SchoolRecruitExam entity = new SchoolRecruitExam();
    BeanUtils.copyProperties(exam, entity);
    entity.setStatus(RecruitExamConstant.INFOCHECK);
    //将测试项目ids,整成id之间用逗号隔开的字符串
    String projectIds = StringUtils.join(exam.getProjectIdList(), ",");
    entity.setProjectIds(projectIds);
    entity.update();
    return toAjax(recruitExamService.updateById(entity));
  }

  /**
   * 考务管理-考试管理-单个删除 删除考试与考生关系 删除该考试对应的教育局信息
   */
  @DeleteMapping("/delete/{id}")
  public AjaxResult delete(@PathVariable Long id) {
    //删考试与考生关系
    LambdaQueryWrapper<SchoolRecruitRelation> relatonLqw = new LambdaQueryWrapper<>();
    relatonLqw.eq(SchoolRecruitRelation::getExamId, id);
    recruitRelationService.remove(relatonLqw);

    //删除该考试对应的教育局信息
    LambdaQueryWrapper<EduRecruitStudent> eduLqw = new LambdaQueryWrapper<>();
    eduLqw.eq(EduRecruitStudent::getExamId, id);
    eduRecruitStudentService.remove(eduLqw);
    return AjaxResult.success(recruitExamService.removeById(id));
  }


  /**
   * 考试管理-信息审核-列表
   */
  @GetMapping("/checkList/{examId}")
  public TableDataInfo checkList(@PathVariable Long examId, RecruitEduStudentVo vo) {
    vo.setExamId(examId);
    return getDataTable(recruitStudentService.getInfoCheck(vo));
  }

  /**
   * 考试管理-信息审核-通过 所有信息都匹配才能将审核状态改为通过
   */
  @PutMapping(value = {"/pass/{examId}/{studentIds}", "/pass/{examId}/"})
  public AjaxResult pass(@PathVariable Long examId,
      @PathVariable(value = "studentIds", required = false) List<Long> studentIds) {
    if (StringUtils.isNull(studentIds) || studentIds.size() == 0) {
      throw new ServiceException("所选数据都为未报名数据，无法通过");
    }
    return AjaxResult.success(recruitStudentService.pass(examId, studentIds));
  }

  /**
   * 考试管理-信息审核-单个通过 所有信息都匹配才能将审核状态改为通过
   */
  @PutMapping("/passOne/{examId}/{studentId}")
  public AjaxResult passOne(@PathVariable Long examId, @PathVariable Long studentId) {
    return toAjax(recruitStudentService.passOne(examId, studentId));
  }

  /**
   * 考试管理-信息审核-退回修改 只有待审核状态擦可以退回修改
   */
  @PutMapping(value = {"/back/{examId}/{studentIds}", "/back/{examId}/"})
  public AjaxResult back(@PathVariable Long examId,
      @PathVariable(value = "studentIds", required = false) List<Long> studentIds) {
    if (StringUtils.isNull(studentIds) || studentIds.size() == 0) {
      throw new ServiceException("所选数据都为未报名数据，无法退回修改");
    }
    return AjaxResult.success(recruitStudentService.back(examId, studentIds));
  }

  /**
   * 考试管理-信息审核-单个退回修改 只有待审核状态擦可以退回修改
   */
  @PutMapping("/backOne/{examId}/{studentId}")
  public AjaxResult backOne(@PathVariable Long examId, @PathVariable Long studentId,
      @RequestBody(required = false) RecruitExamBackVo recruitExamBackVo) {
    return toAjax(recruitStudentService.backOne(examId, studentId,
        recruitExamBackVo == null ? "" : recruitExamBackVo.getMessage()));
  }

  /**
   * 考试管理-信息审核-驳回 只有待审核状态才能驳回
   */
  @PutMapping(value = {"/reject/{examId}/{studentIds}", "/reject/{examId}/"})
  public AjaxResult reject(@PathVariable Long examId,
      @PathVariable(value = "studentIds", required = false) List<Long> studentIds) {
    if (StringUtils.isNull(studentIds) || studentIds.size() == 0) {
      throw new ServiceException("所选数据都为未报名数据，无法驳回");
    }
    return AjaxResult.success(recruitStudentService.reject(examId, studentIds));
  }

  /**
   * 考试管理-信息审核-单个驳回 只有待审核状态才能驳回
   */
  @PutMapping("/rejectOne/{examId}/{studentId}")
  public AjaxResult reject(@PathVariable Long examId, @PathVariable Long studentId) {
    return toAjax(recruitStudentService.rejectOne(examId, studentId));
  }

  /**
   * 考试管理-信息审核-结束 没有到报名截止时间，这里不能结束
   */
  @PutMapping("/checkEnd/{examId}")
  public AjaxResult checkEnd(@PathVariable Long examId) {
    SchoolRecruitExam exam = recruitExamService.getById(examId);
    if (DateUtils.getNowDate().before(exam.getDeadline())) {
      //未到报名截止时间
      throw new ServiceException("没有到报名截止时间，不能结束此环节");
    }
    exam.setStatus(RecruitExamConstant.ADDRESS);
    return toAjax(recruitExamService.updateById(exam));
  }

  /**
   * 考试管理-考场分配-列表
   */
  @GetMapping("/addressList/{examId}")
  public TableDataInfo addressList(@PathVariable Long examId, RecruitExamAddressVo vo) {
    vo.setExamId(examId);
    vo.setAuditStatus(RecruitExamConstant.PASS);
    return getDataTable(recruitRelationService.getAddressList(vo));
  }

  /**
   * 考试管理-考场分配-导出
   */
  @PostMapping("/exportAddress/{examId}")
  public void exportAddress(HttpServletResponse response, RecruitExamAddressVo vo,
      @PathVariable Long examId) {
    vo.setExamId(examId);
    vo.setAuditStatus(RecruitExamConstant.PASS);
    List<RecruitExamAddressVo> list = recruitRelationService.getAddressList(vo);
    int i = 1;
    for (RecruitExamAddressVo addressVo : list) {
      addressVo.setXh(i);
      i++;
    }
    ExcelUtil<RecruitExamAddressVo> util = new ExcelUtil<>(RecruitExamAddressVo.class);
    util.exportExcel(response, list, "考场分配表");
  }

  /**
   * 考试管理-考场分配-导入
   */
  @PostMapping("/importAddressData/{examId}")
  public AjaxResult importAddressData(@PathVariable Long examId, MultipartFile file)
      throws Exception {
    ExcelUtil<RecruitExamAddressVo> util = new ExcelUtil<>(RecruitExamAddressVo.class);
    List<RecruitExamAddressVo> list = util.importExcel(file.getInputStream());

    //校验数据
    recruitRelationService.checkImportAddress(list);
    //数据导入
    return AjaxResult.success(recruitRelationService.importDataAddress(list, examId));
  }

  /**
   * 考试管理-考场分配-结束 有考场分配信息为空的要进行提示
   */
  @PutMapping("/addressEnd/{examId}")
  public AjaxResult addressEnd(@PathVariable Long examId) {
    return toAjax(recruitRelationService.addressEnd(examId));
  }


  /**
   * 考试管理-成绩管理-列表
   */
  @GetMapping("/scoreList/{examId}")
  public TableDataInfo scoreList(@PathVariable Long examId, RecruitExamScoreVo vo) {
    vo.setExamId(examId);
    vo.setAuditStatus(RecruitExamConstant.PASS);
    return getDataTable(recruitRelationService.getScoreList(vo));
  }

  /**
   * 考试管理-成绩发布-导出
   */
  @PostMapping("/exportScore/{examId}")
  public void exportScore(HttpServletResponse response, RecruitExamScoreVo vo,
      @PathVariable Long examId) {
    vo.setExamId(examId);
    vo.setAuditStatus(RecruitExamConstant.PASS);
    List<RecruitExamScoreVo> list = recruitRelationService.getScoreList(vo);
    int i = 1;
    for (RecruitExamScoreVo scoreVo : list) {
      scoreVo.setXh(i);
      i++;
    }
    ExcelUtil<RecruitExamScoreVo> util = new ExcelUtil<>(RecruitExamScoreVo.class);
    util.exportExcel(response, list, "成绩发布信息表");
  }

  /**
   * 考试管理-成绩发布-导入
   */
  @PostMapping("/importScoreData/{examId}")
  public AjaxResult importScoreData(@PathVariable Long examId, MultipartFile file)
      throws Exception {
    ExcelUtil<RecruitExamScoreVo> util = new ExcelUtil<>(RecruitExamScoreVo.class);
    List<RecruitExamScoreVo> list = util.importExcel(file.getInputStream());

    //校验数据
    recruitRelationService.checkImportScore(list);
    //数据导入
    return AjaxResult.success(recruitRelationService.importDataScore(list, examId));
  }

  /**
   * 考试管理-成绩发布-结束 有成绩信息为空的要进行提示
   */
  @PutMapping("/scoreEnd/{examId}")
  public AjaxResult scoreEnd(@PathVariable Long examId) {
    return toAjax(recruitRelationService.scoreEnd(examId));
  }
}
