package cn.com.qmth.stmms.api.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.com.qmth.stmms.admin.vo.ExamSubjectVO;
import cn.com.qmth.stmms.api.exception.ApiException;
import cn.com.qmth.stmms.biz.exam.model.Exam;
import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
import cn.com.qmth.stmms.biz.exam.query.ExamSearchQuery;
import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
import cn.com.qmth.stmms.biz.exam.service.ExamService;
import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
import cn.com.qmth.stmms.biz.file.service.FileService;
import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
import cn.com.qmth.stmms.biz.school.model.School;
import cn.com.qmth.stmms.common.annotation.Logging;
import cn.com.qmth.stmms.common.annotation.RoleRequire;
import cn.com.qmth.stmms.common.domain.ApiUser;
import cn.com.qmth.stmms.common.enums.ExamStatus;
import cn.com.qmth.stmms.common.enums.ExamType;
import cn.com.qmth.stmms.common.enums.LogType;
import cn.com.qmth.stmms.common.enums.Role;
import cn.com.qmth.stmms.common.utils.DateUtils;
import cn.com.qmth.stmms.common.utils.RequestUtils;

@Controller("examInfoApiController")
@RequestMapping("/api")
public class ExamInfoController extends BaseApiController {

    @Autowired
    private ExamService examService;

    @Autowired
    private ExamSubjectService subjectService;

    @Autowired
    private FileService fileService;

    @Autowired
    private ExamQuestionService questionService;

    @RequestMapping("/version")
    @ResponseBody
    public String version(HttpServletRequest request) {
        return "ft";
    }

    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER, Role.SCHOOL_DEV })
    @RequestMapping("/exams")
    @ResponseBody
    public JSONArray getExamInfos(HttpServletRequest request, ExamSearchQuery query,
            @RequestParam(required = false) String schoolCode) {
        ApiUser user = RequestUtils.getApiUser(request);
        JSONArray array = new JSONArray();
        School school = validate(user.getSchoolId(), schoolCode);
        query.setSchoolId(school.getId());
        query.setType(ExamType.SCAN_IMAGE);
        query.setStatus(ExamStatus.START);
        if (query.getPageSize() < 1) {
            query.setPageSize(20);
        }
        query.orderByIdDesc();
        query = examService.findByQuery(query);
        for (Exam exam : query.getResult()) {
            JSONObject obj = new JSONObject();
            obj.accumulate("id", exam.getId());
            obj.accumulate("name", exam.getName());
            obj.accumulate("examTime", DateUtils.formatDate(exam.getExamTime()));
            if (exam.getCardType() != null) {
                obj.accumulate("cardType", exam.getCardType().getExtName());
                obj.accumulate("cardUrl",
                        fileService.getFileServer() + fileService.getCardUri(exam.getId(), exam.getCardType()));
            }
            obj.accumulate("sliceConfig", StringUtils.trimToEmpty(exam.getSliceConfig()));
            obj.accumulate("updateTime", exam.getUpdateTime() == null ? exam.getCreateTime().getTime() : exam
                    .getUpdateTime().getTime());
            array.add(obj);
        }
        return array;
    }

    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER })
    @RequestMapping(value = "/campus", method = RequestMethod.GET)
    @ResponseBody
    public JSONArray getCampus(HttpServletRequest request) {
        // ApiUser user = RequestUtils.getApiUser(request);
        JSONArray array = new JSONArray();
        // List<Campus> list = campusService.findBySchoolId(user.getSchoolId());
        // for (Campus c : list) {
        // JSONObject obj = new JSONObject();
        // obj.accumulate("code", c.getId().toString());
        // obj.accumulate("name", c.getName());
        // array.add(obj);
        // }
        return array;
    }

    @RequestMapping(value = "/subjects/{examId}", method = RequestMethod.GET)
    @ResponseBody
    public JSONArray getSubjects(@PathVariable Integer examId) {
        List<ExamSubject> sList = subjectService.list(examId);
        JSONArray array = new JSONArray();
        for (ExamSubject subject : sList) {
            JSONObject obj = new JSONObject();
            obj.accumulate("code", subject.getCode());
            obj.accumulate("name", subject.getName());
            if (subject.getCardType() != null) {
                obj.accumulate("cardType", subject.getCardType().getExtName());
                obj.accumulate(
                        "cardUrl",
                        fileService.getFileServer()
                                + fileService.getCardUri(subject.getExamId(), subject.getCode(), subject.getCardType()));
            }
            obj.accumulate("sliceConfig", StringUtils.trimToEmpty(subject.getSliceConfig()));
            array.add(obj);
        }
        return array;
    }

    @Logging(menu = "扫描端-修改科目信息", type = LogType.UPDATE)
    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER })
    @RequestMapping(value = "/subject/update", method = RequestMethod.POST)
    @ResponseBody
    public JSONObject updateSubject(HttpServletRequest request, @RequestBody ExamSubjectVO subject) {
        ApiUser user = RequestUtils.getApiUser(request);
        Exam exam = examService.findById(subject.getExamId());
        JSONObject result = new JSONObject();
        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
            ExamSubject es = subjectService.find(subject.getExamId(), subject.getCode());
            if (es != null) {
                // if (subject.getHasAnswer() != null) {
                // es.setHasAnswer(subject.getHasAnswer());
                // }
                // if (subject.getHasPaper() != null) {
                // es.setHasPaper(subject.getHasPaper());
                // }
                // subjectService.save(es);
                result.accumulate("code", subject.getCode());
                return result;
            } else {
                result.accumulate("code", "");
            }
        } else {
            throw ApiException.EXAM_NOT_ACCESSIBLED;
        }
        return result;
    }

    @Logging(menu = "扫描端-修改考试裁切图坐标", type = LogType.UPDATE)
    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER })
    @RequestMapping(value = "/sliceConfig/{examId}", method = RequestMethod.POST)
    @ResponseBody
    public boolean updateSliceConfig(HttpServletRequest request, @PathVariable Integer examId,
            @RequestBody PictureConfigItem[] configs) {
        ApiUser user = RequestUtils.getApiUser(request);
        Exam exam = examService.findById(examId);
        boolean success = false;
        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
            if (configs != null && configs.length > 0) {
                examService.updateSliceConfig(examId, Arrays.asList(configs));
                success = true;
            } else {
                success = false;
            }
        } else {
            throw ApiException.EXAM_NOT_ACCESSIBLED;
        }
        return success;
    }

    @Logging(menu = "扫描端-修改科目裁切图坐标", type = LogType.UPDATE)
    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER })
    @RequestMapping(value = "/sliceConfig/{examId}/{subjectCode}", method = RequestMethod.POST)
    @ResponseBody
    public boolean updateSubjectSliceConfig(HttpServletRequest request, @PathVariable Integer examId,
            @PathVariable String subjectCode, @RequestBody PictureConfigItem[] configs) {
        ApiUser user = RequestUtils.getApiUser(request);
        Exam exam = examService.findById(examId);
        boolean success = false;
        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
            ExamSubject es = subjectService.find(examId, subjectCode);
            if (configs != null && configs.length > 0 && es != null) {
                subjectService.updateSliceConfig(examId, subjectCode, Arrays.asList(configs));
                success = true;
            }
        } else {
            throw ApiException.EXAM_NOT_ACCESSIBLED;
        }
        return success;
    }

    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER, Role.SUBJECT_HEADER })
    @RequestMapping(value = "/questions/{examId}", method = RequestMethod.POST)
    @ResponseBody
    public JSONArray getQuestion(HttpServletRequest request, @PathVariable Integer examId,
            @RequestParam List<String> subjectCodes,
            @RequestParam(required = false, defaultValue = "#") String paperType, @RequestParam Boolean objective) {
        ApiUser user = RequestUtils.getApiUser(request);
        JSONArray result = new JSONArray();
        // 输入字段预处理并初步校验
        Exam exam = examService.findById(examId);
        if (exam == null || !exam.getSchoolId().equals(user.getSchoolId()) || exam.getStatus() != ExamStatus.START) {
            throw ApiException.EXAM_NOT_ACCESSIBLED;
        }
        for (String subjectCode : subjectCodes) {
            subjectCode = validate("subjectCode", subjectCode, true, 64);
            ExamSubject subject = subjectService.find(examId, subjectCode);
            if (subject == null) {
                throw ApiException.QUERY_PARAM_ERROR.appendMessage(": subjectCode error");
            }
            List<ExamQuestion> list = new ArrayList<ExamQuestion>();
            if (objective == null) {
                list.addAll(questionService.findByExamAndSubjectAndObjectiveAndPaperType(examId, subjectCode, true,
                        paperType));
                list.addAll(questionService.findByExamAndSubjectAndObjective(examId, subjectCode, false));
            } else {
                list.addAll(questionService.findByExamAndSubjectAndObjective(examId, subjectCode, objective));
            }
            for (ExamQuestion q : list) {
                JSONObject value = new JSONObject();
                value.accumulate("subjectCode", q.getSubjectCode());
                value.accumulate("objective", q.isObjective());
                value.accumulate("mainNumber", q.getMainNumber());
                value.accumulate("subNumber", q.getSubNumber());
                value.accumulate("mainTitle", q.getMainTitle());
                value.accumulate("totalScore", q.getTotalScore());
                value.accumulate("answer", q.getAnswer() == null ? "" : q.getAnswer());
                result.add(value);
            }
        }
        return result;
    }
}
