package com.qmth.jkserver.controller.system;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.qmth.jkserver.constant.SystemConstant;
import com.qmth.jkserver.core.annotation.TokenValidate;
import com.qmth.jkserver.dto.QueryResultDto;
import com.qmth.jkserver.enums.*;
import com.qmth.jkserver.service.JkExamPlanService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
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 com.qmth.jkserver.core.exception.ApiException;
import com.qmth.jkserver.core.exception.JkServerException;
import com.qmth.jkserver.core.kj.IKjValidateAndStore;
import com.qmth.jkserver.core.kj.validate.ExamRoomSolfegeKjValidateAndStore;
import com.qmth.jkserver.core.kj.validate.NormalKjValidateAndStore;
import com.qmth.jkserver.core.kj.validate.UtestKjValidateAndStore;
import com.qmth.jkserver.core.ow.IOW2Export;
import com.qmth.jkserver.core.ow.Normal2OWExport;
import com.qmth.jkserver.core.ow.Solfege2OWExport;
import com.qmth.jkserver.core.ow.Utest2OWExport;
import com.qmth.jkserver.core.upload.LocalNormalUtestKjFileUploader;
import com.qmth.jkserver.core.upload.LocalSolfegeKjFileUploader;
import com.qmth.jkserver.dto.ExamKjProgressDto;
import com.qmth.jkserver.model.Attachment;
import com.qmth.jkserver.model.ExamPlan;
import com.qmth.jkserver.model.User;
import com.qmth.jkserver.service.ExamKjHZService;

/**
 * 考试结果汇总进度 
 * @author tianjun
 *
 */
@Controller
@RequestMapping("/system/kj/hz")
public class ExamKjHZController extends BaseSystemController {
	private static final Logger LOGGER = LoggerFactory.getLogger(ExamKjHZController.class);
	
	@Resource
    @Lazy
	private JkExamPlanService examPlanService;
	
	@Resource
    @Lazy
	private ExamKjHZService examKjStatisticService;
	
	/**
	 * 通用机考  优特机考 考试结果数据批量本地导入
	 * 暂时不支持 视唱机考结果数据批量本地导入
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("/file/batchLocalImport/{examCode}")
	public Object execute(HttpServletRequest request, HttpServletResponse response,
			@PathVariable(value="examCode",required=true) String examCode) throws Exception{
		ExamPlan examPlan = examPlanService.findByExamCode(examCode);
		if(StringUtils.isEmpty(examCode) || examPlan== null){
			throw ApiException.EXAM_CODE_INVALID;
		}
		if(!ExamStatus.PUBLISHED.equals(examPlan.getExamStatus())){
			throw ApiException.EXAM_PLAN_UN_PUBLISHED;
		}
		Attachment attachment = null;
		if(ExamType.NORMAL.equals(examPlan.getExamType()) || ExamType.UTEST.equals(examPlan.getExamType())){
			LocalNormalUtestKjFileUploader localNormalUtestKjFileUploader = new LocalNormalUtestKjFileUploader(request, examCode);
			attachment = localNormalUtestKjFileUploader.execute();
			if(attachment == null){
				throw JkServerException.FILE_UPLOAD_ERROR;
			}
		}
		else{
			throw new JkServerException("不支持视唱机考结果数据本地导入!");
		}
		IKjValidateAndStore kjValidateStore = null;
		switch (examPlan.getExamType()) {
			case NORMAL:
				kjValidateStore = new NormalKjValidateAndStore(
							examCode, attachment.getId());
				break;
			case UTEST:
				kjValidateStore = new UtestKjValidateAndStore(examCode, attachment.getId());
				break;
			default:
				throw new ApiException(ApiException.SYSTEM_EXCEPTION.getCode(), 
						"此操作仅只支持通用机考以及优特机考的考试结果上传,不支持其它类型机考");
		}
		kjValidateStore.execute(ProgressType.LOCAL);
		return true;
	}
	
	//本地上传一个考场的视唱机考的答案
	@ResponseBody
	@RequestMapping("/file/solfegeImport/{examCode}")
	public Object solfegeImport(HttpServletRequest request, HttpServletResponse response,
			@PathVariable(required=false) String examCode) throws Exception{
		if (StringUtils.isEmpty(examCode)) {
			throw JkServerException.withFieldValidateError("请传入examCode");
		}
		ExamPlan examPlan = examPlanService.findByExamCode(examCode);
		if(StringUtils.isEmpty(examCode) || examPlan== null){
			throw ApiException.EXAM_CODE_INVALID;
		}
		if(!ExamStatus.PUBLISHED.equals(examPlan.getExamStatus())){
			throw ApiException.EXAM_PLAN_UN_PUBLISHED;
		}
		Attachment attachment = null;
		if(ExamType.SOLFEGE.equals(examPlan.getExamType())){
			LocalSolfegeKjFileUploader fileUploader = new LocalSolfegeKjFileUploader(request, examCode);
			attachment = fileUploader.execute();
			if(attachment == null){
				throw JkServerException.FILE_UPLOAD_ERROR;
			}
		}
		else{
			throw new JkServerException("仅仅只支持视唱机考结果数据本地导入!");
		}
		ExamRoomSolfegeKjValidateAndStore solfegeKjValidateAndStore = new ExamRoomSolfegeKjValidateAndStore(
				examPlan, attachment, true);
		solfegeKjValidateAndStore.execute(ProgressType.LOCAL);
		return true;
	}
	
	//获取所有已经发布的考试任务-尚未归档的考试任务
	@ResponseBody
    @RequestMapping(value ="/getPlans",method = RequestMethod.POST)
    public Object queryPlans(HttpServletRequest request,HttpServletResponse response){
		User user = super.getCachedUser(request);
    	List<ExamPlan> examPlans = examPlanService.findByStatus(ExamStatus.PUBLISHED, user);
    	return examPlans;
    }
    
    //获取所有的考点根据考试识别码
	@ResponseBody
    @RequestMapping(value ="/getPlaceByExamCode",method = RequestMethod.POST)
    public Object getPlaceByExamCode(HttpServletRequest request, HttpServletResponse response,
    		@RequestParam(value="examCode",required=true) String examCode){
    	return examKjStatisticService.getPlaceByExamCode(examCode);
    }
    
 
    
    //获取所有的考点根据考试识别码
	@ResponseBody
    @RequestMapping(value ="/getRoomByPlaceCode",method = RequestMethod.POST)
    public Object getRoomByExamCode(HttpServletRequest request, HttpServletResponse response,
    		@RequestParam(value="examCode",required=true) String examCode,
    		@RequestParam(value="placeCode",required=true) String placeCode
    		){
    	return examKjStatisticService.getRoomByPlaceCode(examCode, placeCode);
    }
    
    //获取所有的批次
	@ResponseBody
    @RequestMapping(value ="/getBatches",method = RequestMethod.POST)
    public Object getBatches(HttpServletRequest request, HttpServletResponse response,
    		@RequestParam(value="examCode",required=true) String examCode
    		){
    	return examKjStatisticService.getBatchesByExamCode(examCode);
    }
    
    //汇总结构 统计进度 列表,优特机考  通用机考
	@ResponseBody
    @RequestMapping(value ="/getKjProgress",method = RequestMethod.POST)
    public Object getKjProgress(HttpServletRequest request, HttpServletResponse response,
    		ExamKjProgressDto examKjProgressDto,
    		@RequestParam(required=false) Boolean already,
    		@RequestParam(required=false) String placeName,
    		@RequestParam(required=false) Integer pageNo,
    		@RequestParam(required=false) Integer pageSize
    		){
    	Page<ExamKjProgressDto> page = examKjStatisticService.pageQueryProgress(examKjProgressDto, already, 
    			placeName,pageNo, pageSize);
    	return page;
    }
	
	  //汇总结构 统计进度 列表  视唱机考
	@ResponseBody
    @RequestMapping(value ="/getSolfegeKjProgress",method = RequestMethod.POST)
    public Object getSolfegeKjProgress(HttpServletRequest request, HttpServletResponse response,
    		ExamKjProgressDto examKjProgressDto,
    		@RequestParam(required=false) Integer pageNo,
    		@RequestParam(required=false) Integer pageSize
    		){
    	Page<ExamKjProgressDto> page = examKjStatisticService.pageQuerySolfegeProgress(examKjProgressDto, pageNo, pageSize);
    	return page;
    }
    
    //OW 导出
    @RequestMapping(value ="/owexport",method = RequestMethod.POST)
    public void owExport(HttpServletRequest request, HttpServletResponse response,
    		@RequestParam(value="examCode",required=true) String examCode
    		) throws Exception{
    	IOW2Export oExport = null;
    	ExamPlan examPlan = examPlanService.findByExamCode(examCode);
    	if(examPlan == null){
    		throw new JkServerException("错误的考试识别码:"+examCode);
    	}
    	if(ExamType.UTEST.equals(examPlan.getExamType())){
    		oExport = new Utest2OWExport();
    	}
    	if(ExamType.NORMAL.equals(examPlan.getExamType())){
    		oExport = new Normal2OWExport();
    	}
    	if(ExamType.SOLFEGE.equals(examPlan.getExamType())){
    		oExport = new Solfege2OWExport();
    	}
    	File file = oExport.execute(examCode);
		LOGGER.info("导出file成功");
    	String fileName = URLEncoder.encode(file.getName(), SystemConstant.CHARSET_NAME);
    	response.setCharacterEncoding(SystemConstant.CHARSET_NAME);
    	response.addHeader("fileName", fileName);
		response.addHeader("fileSize", file.length()+ "");
		response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
		InputStream inputStream = null;
		OutputStream outputStream = null;
		try {
			inputStream = new FileInputStream(file);
			outputStream = response.getOutputStream();
			IOUtils.copy(inputStream, outputStream);
		}finally {
			if(inputStream!=null){
				IOUtils.closeQuietly(inputStream);
			}
			if(outputStream!=null){
				IOUtils.closeQuietly(outputStream);
			}
		}
		LOGGER.info("导出file结束");
    }
}
