package cn.com.qmth.stmms.ms.admin.api;

import cn.com.qmth.stmms.ms.admin.service.DataUploadService;
import cn.com.qmth.stmms.ms.commons.utils.specification.PagingAndSortingDTO;
import cn.com.qmth.stmms.ms.core.domain.MarkStage;
import cn.com.qmth.stmms.ms.core.domain.MarkSubject;
import cn.com.qmth.stmms.ms.core.domain.Student;
import cn.com.qmth.stmms.ms.core.repository.MarkSubjectRepo;
import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
import cn.com.qmth.stmms.ms.core.repository.StudentRepo;
import cn.com.qmth.stmms.ms.core.specification.StudentSpecification;
import cn.com.qmth.stmms.ms.core.vo.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 考生数据api
 */
@RestController
@RequestMapping("api/students")
public class StudentApi {

    @Autowired
    private DataUploadService dataUploadService;

    @Autowired
    private StudentRepo studentRepo;

    @Autowired
    private PaperRepo paperRepo;

    @Autowired
    MarkSubjectRepo markSubjectRepo;

    /**
     * 考生列表
     *
     * @param params
     * @return
     */
    @RequestMapping(method = RequestMethod.GET)
    public PagingAndSortingDTO list(StudentSpecification params) {
        Page<Student> result = studentRepo.findAll(params.getSpecification(), params.getPageRequest());
        return new PagingAndSortingDTO(result.getNumber(), result.getSize(), result.getTotalPages(),
                result.getTotalElements(), result.getContent());
    }

    /**
     * 单个考生
     *
     * @param domain 考生id
     * @return
     */
    @RequestMapping(value = "{domain}", method = RequestMethod.GET)
    public Student getOne(@PathVariable Student domain) {
        return domain;
    }

    /**
     * 删除
     *
     * @param domain
     */
    @RequestMapping(value = "{domain}", method = RequestMethod.DELETE)
    public void remove(@PathVariable Student domain) {
        Long isExist = paperRepo.countByWorkIdAndExamNumber(domain.getWorkId(), domain.getExamNumber());
        if (isExist > 0) {
            throw new RuntimeException("该考生已上传，无法删除");
        }
        studentRepo.delete(domain);
    }

    /**
     * 修改信息
     *
     * @param domain
     * @param student
     */
    @RequestMapping(value = "{domain}", method = RequestMethod.PUT)
    public Student update(@PathVariable Student domain, @RequestBody Student student) {
        Long isExist = paperRepo.countByWorkIdAndExamNumber(domain.getWorkId(), domain.getExamNumber());
        if (isExist > 0) {
            throw new RuntimeException("该考生已上传，无法修改");
        }
        Student temp = studentRepo.findByWorkIdAndExamNumber(domain.getWorkId(), student.getExamNumber());
        if(temp != null && domain.getId() != temp.getId()){
            throw new RuntimeException("该考号已存在");
        }
        domain.setName(student.getName());
        domain.setExamNumber(student.getExamNumber());
        domain.setExamRoom(student.getExamRoom());
        domain.setAreaCode(student.getAreaCode());
        domain.setAreaName(student.getAreaName());
        domain.setSchool(student.getSchool());
        domain.setRelateExamNumber(student.getExamNumber());
        return studentRepo.save(domain);
    }

    /**
     * 新增
     *
     * @param domain
     * @return
     */
    @RequestMapping(method = RequestMethod.POST)
    public Student create(@RequestBody Student domain) throws Exception {
        try {
            //进入打分阶段，不能添加
            List<MarkSubject> markSubjects= markSubjectRepo.findAllByWorkIdAndStage(domain.getWorkId(), MarkStage.SCORE);
            if(!markSubjects.isEmpty() && markSubjects.size() > 0){
                throw new RuntimeException("进入打分阶段，不能添加考生");
            }
            domain.setTest("0");
            //关联考号默认为考号
            domain.setRelateExamNumber(domain.getExamNumber());
            Student student = studentRepo.findByWorkIdAndAreaCodeAndExamNumber(domain.getWorkId(), domain.getAreaCode(), domain.getExamNumber());
            if(student != null){
                throw new RuntimeException("添加失败，同一个考区不允许有重复的考号");
            }
            return studentRepo.save(domain);
        } catch (Exception e) {
//            if (e instanceof DataIntegrityViolationException) {
//                throw new Exception("失败，同一个考区不允许有重复的考号");
//            }
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 清空所有
     *
     * @param workId 评卷工作id
     */
    @RequestMapping(method = RequestMethod.DELETE)
    public void clear(@RequestParam Long workId) {
        dataUploadService.clearStudents(workId);
    }

    /**
     * 新增
     *
     * @param studentId
     * @param subject
     * @param isManual
     * @param file
     * @throws IOException
     */
    @RequestMapping(value = "{studentId}", method = RequestMethod.POST)
    public void addPaper(@PathVariable Long studentId,
                         @RequestParam Subject subject,
                         @RequestParam(required = false) boolean isManual,
                         @RequestParam MultipartFile file)
            throws Exception {
        dataUploadService.uploadPaper(studentId, subject, file.getInputStream(), isManual);
    }

    /**
     * 级联查询
     */
    @RequestMapping(value = "select/{workId}", method = RequestMethod.GET)
    public List<Map> addPaper(@PathVariable Long workId) {
        List<Student> students = studentRepo.findByWorkId(workId);
        List<String> areaNames = students.stream().map(s->s.getAreaCode()+":"+s.getAreaName()).distinct().collect(Collectors.toList());
        List<Map> areaList = new ArrayList<>();
        for (String areas : areaNames) {
            String[] as = areas.split(":");
            String areaCode = as[0];
            String areaName = as[1];
            Map areaMap = new HashMap();
            areaMap.put("areaCode", areaCode);
            areaMap.put("areaName", areaName);
            List<String> schools = students.stream().filter(s-> Objects.equals(s.getAreaName(), areaName)).map(student -> student.getSchool()).distinct().collect(Collectors.toList());
            List<Map> schList = new ArrayList<>();
            for (String school : schools) {
                Map schMap = new HashMap();
                schMap.put("school", school);
                List<String> rooms = students.stream().filter(s -> Objects.equals(s.getAreaName(), areaName) && Objects.equals(s.getSchool(), school)).map(student -> student.getExamRoom()).distinct().collect(Collectors.toList());
                schMap.put("rooms", rooms);
                schList.add(schMap);
            }
            areaMap.put("schools", schList);
            areaList.add(areaMap);
        }
        return areaList;
    }

}
