package com.qmth.qrzk.web.controller;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.ResponseBody;

import com.qmth.qrzk.repository.user.model.Book;
import com.qmth.qrzk.repository.user.model.Code;
import com.qmth.qrzk.repository.user.model.Course;
import com.qmth.qrzk.repository.user.model.Question;
import com.qmth.qrzk.repository.user.model.QuestionOption;
import com.qmth.qrzk.repository.user.model.QuestionType;
import com.qmth.qrzk.repository.user.model.User;
import com.qmth.qrzk.repository.user.service.ICodeSerivce;
import com.qmth.qrzk.repository.user.service.IQuestionOptionService;
import com.qmth.qrzk.repository.user.service.IQuestionTypeService;
import com.qmth.qrzk.repository.user.service.IUserService;
import com.qmth.qrzk.repository.user.service.impl.BookServiceImpl;
import com.qmth.qrzk.repository.user.service.impl.CourseServiceImpl;
import com.qmth.qrzk.repository.user.service.impl.QuestionServiceImpl;
import com.qmth.qrzk.repository.utils.Consts;
import com.qmth.qrzk.repository.utils.DateHelper;
import com.qmth.qrzk.repository.utils.General;
import com.qmth.qrzk.repository.utils.docx.HtmlCreator;

@Controller
@RequestMapping("/client")
public class ClientController extends BaseAjaxController{
	
	private static final Logger log = Logger.getLogger(ClientController.class);
	
	@Autowired
	private QuestionServiceImpl questionService;
	
	@Autowired
	private CourseServiceImpl courseService;
	
	@Autowired
	private BookServiceImpl bookService;

	@Autowired
	@Qualifier("questionTypeServiceImpl")
	private IQuestionTypeService questionTypeService;

	@Autowired
	@Qualifier("questionOptionServiceImpl")
	private IQuestionOptionService questionOptionService;

	@Autowired
	@Qualifier("codeServiceImpl")
	private ICodeSerivce codeSerivce;

	@Autowired
	@Qualifier("userServiceImpl")
	private IUserService userService;
	
	/**
	 * 根据试题id获取详情信息
	 * @param id  试题id
 	 * @return
	 */
	@RequestMapping("/getQuestionInfo/{id}")
	@ResponseBody
	public Map<String, Object> getQuestionInfo(@PathVariable int id) {
		try {
			//根据试题id查询出对应的试题
			Question question = questionService.searchById(id);
			if(question == null){
				throw new RuntimeException("试题不存在");
			}
			question.setBody(null);
			question.setBodySummary(null);
			question.setAnswer(null);
			question.setAnswerSummary(null);
			//或者该课程下面所有的题型
			Course course = courseService.findById(question.getCourseId());
			List<Book> books = bookService.findBooksInCourse(question.getCourseId());
			List<QuestionType> questionTypes = questionTypeService.queryByCourseId(question.getCourseId());
			List<User> setTeachers = userService.queryUsersByCourseId(question.getCourseId());
			{//处理试题里面的命题教师不在配置的命题教师列表里面的情况
				String setTeacher = question.getSetTeacherName();
				if(setTeacher == null){
					setTeacher = "";
					question.setSetTeacherName("");
				}
				boolean tExist = false;
				for(User t:setTeachers){
					if(setTeacher.equals(t.getName())){
						tExist = true;
						break;
					}
				}
				if(!tExist){
					User t = new User();
					t.setName(setTeacher);
					setTeachers.add(0, t);
				}
			}
			
			List<QuestionOption> options = questionOptionService.findByQuestionId(question.getId());
			if(options != null && options.size() > 0){
				for(QuestionOption opt:options){
					opt.setContent(null);
					opt.setSummary(null);
				}
			}
			Map<String,Object> codesMap = new HashMap<String, Object>();
			codesMap.put("abilityTitle", "能力要求");
			codesMap.put("questionDifficultyTitle", "预计难度");
			codesMap.put("assessmentDemandTitle", "考核要求");
			List<Code> codes = codeSerivce.getAllCode();
			List<Code> abilityList = new ArrayList<Code>();
			List<Code> questionDifficultyList = new ArrayList<Code>();
			List<Code> assessmentDemandList = new ArrayList<Code>();
			for(Code code:codes){
				if("ABILITY".equals(code.getItemType())){
					abilityList.add(code);
				}else if("QUESTION_DIFFICULTY".equals(code.getItemType())){
					questionDifficultyList.add(code);
				}else if("ASSESSMENT_DEMAND".equals(code.getItemType())){
					assessmentDemandList.add(code);
				}
			}
			codesMap.put("abilityCodes", abilityList);
			codesMap.put("questionDifficultyCodes", questionDifficultyList);
			codesMap.put("assessmentDemandCodes", assessmentDemandList);

			Map<String,Object> resultMap = successResult("查询试题成功");
			resultMap.put("operType", "update");
			resultMap.put("question", question);
			resultMap.put("course", course);
			resultMap.put("books", books);
			resultMap.put("questionTypes", questionTypes);
			resultMap.put("options", options);
			resultMap.put("setTeachers", setTeachers);
//			resultMap.put("isUsedByPaper", questionService.isUsedByPaper(id));
			resultMap.put("codes", codesMap);
			return resultMap;
		} catch (Exception e) {
			log.error("查询试题[id=" + id + "]信息失败，原因：" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	/**
	 * 根据试题id获取详情信息v2.0接口
	 * @param id  试题id
 	 * @return
	 */
	@RequestMapping("/getQuestionInfoAPI/{id}")
	@ResponseBody
	public Map<String, Object> getQuestionInfoApi(@PathVariable int id) {
		try {
			//根据试题id查询出对应的试题
			Question question = questionService.searchById(id);
			if(question == null){
				throw new RuntimeException("试题不存在");
			}
			question.setBody(null);
			question.setBodySummary(null);
			question.setAnswer(null);
			question.setAnswerSummary(null);
			
//			question.setBodyWord(null);
//			question.setAnswerWord(null);
			//或者该课程下面所有的题型
			Course course = courseService.findById(question.getCourseId());
			List<Book> books = bookService.findBooksInCourse(question.getCourseId());
			List<QuestionType> questionTypes = questionTypeService.queryByCourseId(question.getCourseId());
			List<User> setTeachers = userService.queryUsersByCourseId(question.getCourseId());
			{//处理试题里面的命题教师不在配置的命题教师列表里面的情况
				String setTeacher = question.getSetTeacherName();
				if(setTeacher == null){
					setTeacher = "";
					question.setSetTeacherName("");
				}
				boolean tExist = false;
				for(User t:setTeachers){
					if(setTeacher.equals(t.getName())){
						tExist = true;
						break;
					}
				}
				if(!tExist){
					User t = new User();
					t.setName(setTeacher);
					setTeachers.add(0, t);
				}
			}
			
			List<QuestionOption> options = questionOptionService.findByQuestionId(question.getId());
			if(options != null && options.size() > 0){
				for(QuestionOption opt:options){
					opt.setContent(null);
					opt.setSummary(null);
//					opt.setContentWord(null);
				}
			}
			Map<String,Object> codesMap = new HashMap<String, Object>();
			codesMap.put("abilityTitle", "能力要求");
			codesMap.put("questionDifficultyTitle", "预计难度");
			codesMap.put("assessmentDemandTitle", "考核要求");
			List<Code> codes = codeSerivce.getAllCode();
			List<Code> abilityList = new ArrayList<Code>();
			List<Code> questionDifficultyList = new ArrayList<Code>();
			List<Code> assessmentDemandList = new ArrayList<Code>();
			for(Code code:codes){
				if("ABILITY".equals(code.getItemType())){
					abilityList.add(code);
				}else if("QUESTION_DIFFICULTY".equals(code.getItemType())){
					questionDifficultyList.add(code);
				}else if("ASSESSMENT_DEMAND".equals(code.getItemType())){
					assessmentDemandList.add(code);
				}
			}
			//TODO 组装editWord内容
			codesMap.put("abilityCodes", abilityList);
			codesMap.put("questionDifficultyCodes", questionDifficultyList);
			codesMap.put("assessmentDemandCodes", assessmentDemandList);

			Map<String,Object> resultMap = successResult("查询试题成功");
			resultMap.put("operType", "update");
			resultMap.put("question", question);
			resultMap.put("course", course);
			resultMap.put("books", books);
			resultMap.put("questionTypes", questionTypes);
			resultMap.put("options", options);
			resultMap.put("setTeachers", setTeachers);
//			resultMap.put("isUsedByPaper", questionService.isUsedByPaper(id));
			resultMap.put("codes", codesMap);
			return resultMap;
		} catch (Exception e) {
			log.error("查询试题[id=" + id + "]信息失败，原因：" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	/**
	 * 根据课程Id获取课程相关数据
	 * @param courseId 课程Id
 	 * @return
	 */
	@RequestMapping("/getCourseInfo/{courseId}")
	@ResponseBody
	public Map<String, Object> getCourseInfo(@PathVariable int courseId) {
		try {
			Course course = courseService.findById(courseId);
			//根据试题id查询出对应的试题
			Question question = new Question();
			//或者该课程下面所有的题型
			List<Book> books = bookService.findBooksInCourse(courseId);
			List<QuestionType> questionTypes = questionTypeService.queryByCourseId(courseId);
			List<User> setTeachers = userService.queryUsersByCourseId(courseId);
			if(setTeachers.size() > 0){//设置一个默认命题教师
				question.setSetTeacherName(setTeachers.get(0).getName());
			}else{
				question.setSetTeacherName("");
			}
			
			List<QuestionOption> options = new ArrayList<QuestionOption>();
			question.setOptions(options);
			Map<String,Object> codesMap = new HashMap<String, Object>();
			codesMap.put("abilityTitle", "能力要求");
			codesMap.put("questionDifficultyTitle", "预计难度");
			codesMap.put("assessmentDemandTitle", "考核要求");
			List<Code> codes = codeSerivce.getAllCode();
			List<Code> abilityList = new ArrayList<Code>();
			List<Code> questionDifficultyList = new ArrayList<Code>();
			List<Code> assessmentDemandList = new ArrayList<Code>();
			for(Code code:codes){
				if("ABILITY".equals(code.getItemType())){
					abilityList.add(code);
				}else if("QUESTION_DIFFICULTY".equals(code.getItemType())){
					questionDifficultyList.add(code);
				}else if("ASSESSMENT_DEMAND".equals(code.getItemType())){
					assessmentDemandList.add(code);
				}
			}
			codesMap.put("abilityCodes", abilityList);
			codesMap.put("questionDifficultyCodes", questionDifficultyList);
			codesMap.put("assessmentDemandCodes", assessmentDemandList);

			Map<String,Object> resultMap = successResult("查询课程信息成功");
			resultMap.put("operType", "add");
			resultMap.put("question", question);
			resultMap.put("course", course);
			resultMap.put("books", books);
			resultMap.put("questionTypes", questionTypes);
			resultMap.put("options", options);
			resultMap.put("setTeachers", setTeachers);
//			resultMap.put("isUsedByPaper", false);
			resultMap.put("codes", codesMap);
			return resultMap;
		} catch (Exception e) {
			log.error("查询课程[courseId=" + courseId + "]信息失败，原因：" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	
	/**
	 * 根据课程Id获取课程相关数据v2.0
	 * @param courseId 课程Id 
 	 * @return
	 */
	@RequestMapping("/getCourseInfoAPI/{courseId}")
	@ResponseBody
	public Map<String, Object> getCourseInfoAPI(@PathVariable int courseId) {
		try {
			Course course = courseService.findById(courseId);
			//根据试题id查询出对应的试题
			Question question = new Question();
			//或者该课程下面所有的题型
			List<Book> books = bookService.findBooksInCourse(courseId);
			List<QuestionType> questionTypes = questionTypeService.queryByCourseId(courseId);
			List<User> setTeachers = userService.queryUsersByCourseId(courseId);
			if(setTeachers.size() > 0){//设置一个默认命题教师
				question.setSetTeacherName(setTeachers.get(0).getName());
			}else{
				question.setSetTeacherName("");
			}
			
			List<QuestionOption> options = new ArrayList<QuestionOption>();
			Map<String,Object> codesMap = new HashMap<String, Object>();
			codesMap.put("abilityTitle", "能力要求");
			codesMap.put("questionDifficultyTitle", "预计难度");
			codesMap.put("assessmentDemandTitle", "考核要求");
			List<Code> codes = codeSerivce.getAllCode();
			List<Code> abilityList = new ArrayList<Code>();
			List<Code> questionDifficultyList = new ArrayList<Code>();
			List<Code> assessmentDemandList = new ArrayList<Code>();
			for(Code code:codes){
				if("ABILITY".equals(code.getItemType())){
					abilityList.add(code);
				}else if("QUESTION_DIFFICULTY".equals(code.getItemType())){
					questionDifficultyList.add(code);
				}else if("ASSESSMENT_DEMAND".equals(code.getItemType())){
					assessmentDemandList.add(code);
				}
			}
			codesMap.put("abilityCodes", abilityList);
			codesMap.put("questionDifficultyCodes", questionDifficultyList);
			codesMap.put("assessmentDemandCodes", assessmentDemandList);

			Map<String,Object> resultMap = successResult("查询课程信息成功");
			resultMap.put("operType", "add");
			resultMap.put("question", question);
			resultMap.put("course", course);
			resultMap.put("books", books);
			resultMap.put("questionTypes", questionTypes);
			resultMap.put("options", options);
			resultMap.put("setTeachers", setTeachers);
//			resultMap.put("isUsedByPaper", false);
			resultMap.put("codes", codesMap);
			return resultMap;
		} catch (Exception e) {
			log.error("查询课程[courseId=" + courseId + "]信息失败，原因：" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	/**
	 * 按照课程id分配题号
	 * @param courseId 课程id
 	 * @return
	 */
	@RequestMapping("/getNewQuestionNo/{courseId}")
	@ResponseBody
	public Map<String, Object> getNewQuestionNo(@PathVariable int courseId) {
		try {
			Course course = courseService.findById(courseId);
			String questionNo = General.getNewQuestionNo(course.getCode());

			Map<String,Object> resultMap = successResult("分配题号成功");
			resultMap.put("questionNo", questionNo);
			return resultMap;
		} catch (Exception e) {
			log.error("按照课程[courseId=" + courseId + "]分配题号失败，原因：" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	/**
	 * 保存试题信息v2.0录题客户端
	 * @param courseId 课程id
 	 * @return
	 */
	@RequestMapping("/saveQuestionAPI")
	@ResponseBody
	public Map<String, Object> saveQuestionAPI(@RequestBody Question question) {
		try{
			//TODO,解析试题中editword内容到题干、答案、选项中（如果存在）
			try{
				question.setBody(HtmlCreator.covertToHtml(question.getBodyWord()).toString());
				question.setBodySummary(General.extractText(question.getBody()));
			}catch(Exception e){
				log.warn("试题[id=" + question.getId() + "]的word数据无法转换成html代码，原因：" + e.getMessage(), e);
				throw new RuntimeException("题干数据无法正常解析，请与管理员联系。", e);
			}
			if(General.isEmpty(question.getBodySummary()) && !question.getBody().contains("<img ")){
				throw new RuntimeException("题干不能为空");
			}
			if(question.getAnswerWord() != null && question.getAnswerWord().length > 0){
				try{
					question.setAnswer(HtmlCreator.covertToHtml(question.getAnswerWord()).toString());
					question.setAnswerSummary(General.extractText(question.getAnswer()));
				}catch(Exception e){
					log.warn("试题[id=" + question.getId() + "]的word答案无法转换成html代码，原因：" + e.getMessage(), e);
					throw new RuntimeException("答案数据无法正常解析，请与管理员联系。", e);
				}
				if(General.isEmpty(question.getAnswerSummary()) && !question.getAnswer().contains("<img ")){
					throw new RuntimeException("答案不能为空");
				}
			}
			if(question.getOptions() != null){
				int index = 0;
				for(QuestionOption qo:question.getOptions()){
					try{
						qo.setOptionNo(index);
						qo.setContent(HtmlCreator.covertToHtml(qo.getContentWord()).toString());
						qo.setSummary(General.extractText(qo.getContent()));
					}catch(Exception e){
						log.warn("试题[id=" + question.getId() + "]下面的的选项[id=" + qo.getId() + "]word数据无法转换成html代码，原因：" + e.getMessage(), e);
						throw new RuntimeException("第" + (index + 1) + "个选项数据无法正常解析，请与管理员联系。", e);
					}
					index++;
				}
				for(int i=0;i<question.getOptions().size()-1;i++){
					QuestionOption qoI = question.getOptions().get(i);
					if(General.isEmpty(qoI.getSummary()) && !qoI.getContent().contains("<img ")){
						throw new RuntimeException("第" + (i + 1) + "个选项为空");
					}
					for(int j = i+1;j<question.getOptions().size();j++){
						QuestionOption qoJ = question.getOptions().get(j);
						if(qoI.getContent().equals(qoJ.getContent())){
							throw new RuntimeException("第" + (i + 1) + "个和" + (j + 1) + "选项内容重复");
						}
					}
				}
			}
			int curUserId = (question.getId() == null || question.getId() == 0)?question.getCreatedBy():question.getUpdatedBy();
			if(question.getId() == null || question.getId() == 0){
				if("mingti".equals(question.getLutiType())){
					question.setSetTeacherName(Consts.UserMap.get(curUserId).getName());
					question.setEnableTimeStr("");
					question.setEnableTime(null);
				}
			}
			try{
				if(General.isNotEmpty(question.getEnableTimeStr())){
					question.setEnableTime(DateHelper.parseShorString(question.getEnableTimeStr()));
				}
			}catch(Exception e){
				log.error("启用时间[" + question.getEnableTimeStr() + "]输入有误",e);
				throw new RuntimeException("启用时间输入有误",e);
			}
			if(General.isNotEmpty(question.getSetTeacherName())){
				question.setSetTeacherName(URLDecoder.decode(question.getSetTeacherName(), "UTF-8"));
			}
			int questionId = questionService.save(question, curUserId).getId();
			Map<String,Object> resultMap = successResult("保存试题数据成功");
			resultMap.put("questionId", questionId);
			return resultMap;
		}catch(Exception e){
			log.error("保存试题数据失败，原因:" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	/**
	 * 保存试题信息
	 * @param courseId 课程id
 	 * @return
	 */
	@RequestMapping("/saveQuestion")
	@ResponseBody
	public Map<String, Object> saveQuestion(@RequestBody Question question) {
		try{
			try{
				question.setBody(HtmlCreator.covertToHtml(question.getBodyWord()).toString());
				question.setBodySummary(General.extractText(question.getBody()));
			}catch(Exception e){
				log.warn("试题[id=" + question.getId() + "]的word数据无法转换成html代码，原因：" + e.getMessage(), e);
				throw new RuntimeException("题干数据无法正常解析，请与管理员联系。", e);
			}
			if(General.isEmpty(question.getBodySummary()) && !question.getBody().contains("<img ")){
				throw new RuntimeException("题干不能为空");
			}
			if(question.getAnswerWord() != null && question.getAnswerWord().length > 0){
				try{
					question.setAnswer(HtmlCreator.covertToHtml(question.getAnswerWord()).toString());
					question.setAnswerSummary(General.extractText(question.getAnswer()));
				}catch(Exception e){
					log.warn("试题[id=" + question.getId() + "]的word答案无法转换成html代码，原因：" + e.getMessage(), e);
					throw new RuntimeException("答案数据无法正常解析，请与管理员联系。", e);
				}
				if(General.isEmpty(question.getAnswerSummary()) && !question.getAnswer().contains("<img ")){
					throw new RuntimeException("答案不能为空");
				}
			}
			if(question.getOptions() != null){
				int index = 0;
				for(QuestionOption qo:question.getOptions()){
					try{
						qo.setOptionNo(index);
						qo.setContent(HtmlCreator.covertToHtml(qo.getContentWord()).toString());
						qo.setSummary(General.extractText(qo.getContent()));
					}catch(Exception e){
						log.warn("试题[id=" + question.getId() + "]下面的的选项[id=" + qo.getId() + "]word数据无法转换成html代码，原因：" + e.getMessage(), e);
						throw new RuntimeException("第" + (index + 1) + "个选项数据无法正常解析，请与管理员联系。", e);
					}
					index++;
				}
				for(int i=0;i<question.getOptions().size()-1;i++){
					QuestionOption qoI = question.getOptions().get(i);
					if(General.isEmpty(qoI.getSummary()) && !qoI.getContent().contains("<img ")){
						throw new RuntimeException("第" + (i + 1) + "个选项为空");
					}
					for(int j = i+1;j<question.getOptions().size();j++){
						QuestionOption qoJ = question.getOptions().get(j);
						if(qoI.getContent().equals(qoJ.getContent())){
							throw new RuntimeException("第" + (i + 1) + "个和" + (j + 1) + "选项内容重复");
						}
					}
				}
			}
			int curUserId = (question.getId() == null || question.getId() == 0)?question.getCreatedBy():question.getUpdatedBy();
			if(question.getId() == null || question.getId() == 0){
				if("mingti".equals(question.getLutiType())){
					question.setSetTeacherName(Consts.UserMap.get(curUserId).getName());
					question.setEnableTimeStr("");
					question.setEnableTime(null);
				}
			}
			try{
				if(General.isNotEmpty(question.getEnableTimeStr())){
					question.setEnableTime(DateHelper.parseShorString(question.getEnableTimeStr()));
				}
			}catch(Exception e){
				log.error("启用时间[" + question.getEnableTimeStr() + "]输入有误",e);
				throw new RuntimeException("启用时间输入有误",e);
			}
			if(General.isNotEmpty(question.getSetTeacherName())){
				question.setSetTeacherName(URLDecoder.decode(question.getSetTeacherName(), "UTF-8"));
			}
			int questionId = questionService.save(question, curUserId).getId();
			Map<String,Object> resultMap = successResult("保存试题数据成功");
			resultMap.put("questionId", questionId);
			return resultMap;
		}catch(Exception e){
			log.error("保存试题数据失败，原因:" + e.getMessage(), e);
			return failedResult(e);
		}
	}
}
