package com.yizhi.application.exam.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.yizhi.application.course.util.OssUpload;
import com.yizhi.core.application.context.TaskContext;
import com.yizhi.core.application.file.constant.FileConstant;
import com.yizhi.core.application.file.task.AbstractDefaultTask;
import com.yizhi.exam.application.feign.ExamAnswerClient;
import com.yizhi.exam.application.feign.ExamAuthorizeClient;
import com.yizhi.exam.application.feign.ExamClient;
import com.yizhi.exam.application.vo.*;
import com.yizhi.exam.application.vo.domain.Exam;
import com.yizhi.exam.application.vo.domain.TrExamAuthorize;
import com.yizhi.system.application.system.remote.AccountClient;
import com.yizhi.system.application.system.remote.OrganizationClient;
import com.yizhi.system.application.system.remote.SiteClient;
import com.yizhi.system.application.vo.AccountVO;
import com.yizhi.util.application.date.DateUtil;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;



@Component
public class ExamStatisticalExport extends AbstractDefaultTask<String, Map<String,Object>> {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(ExamStatisticalExport.class);

	@Value("${ACTIVE}")
	public String active;
	
	@Autowired
	ExamClient examClient;
	@Autowired
	ExamAuthorizeClient examAuthorizeClient;
	@Autowired
	AccountClient accountClient;
	@Autowired
	ExamAnswerClient examAnswerClient;
	@Autowired
	OrganizationClient organizationClient;
	@Autowired
	SiteClient siteClient;
    @Autowired
    ExamStatisticalExport examStatisticalExport;

	@Override
	protected String execute(Map<String, Object> map) {
		// TODO Auto-generated method stub
		
		String upload=null;

		ExamCountExportParamVO vo=(ExamCountExportParamVO) map.get("vo");
		Long companyId=(Long) map.get("companyId");
		Long siteId=(Long) map.get("siteId");
		Calendar cal = Calendar.getInstance();
		if(vo.getStartTime() == null){
			cal.add(Calendar.MONTH, -2);
			vo.setStartTime(DateUtil.toSeconds(cal.getTime()));
		}
		if(vo.getEndTime() == null){
			cal.add(Calendar.MONTH, 4);
			vo.setEndTime(DateUtil.toSeconds(cal.getTime()));
		}
		
    	Long taskId = System.currentTimeMillis();
    	Long accountId = (Long) map.get("accountId");
    	String taskName = "站点考试汇总统计导出任务";
    	Date submitTime = new Date();
    	//创建任务
    	TaskContext taskContext = new TaskContext(taskId, taskName, Long.valueOf(String.valueOf(accountId)), submitTime,Long.valueOf(String.valueOf(siteId)),Long.valueOf(String.valueOf(companyId)));//任务id   任务名字   操作人id  操作时间
    	working(taskContext);
		
		List<ExportByExamVO> list = new ArrayList<ExportByExamVO>();
		
		vo.setCompanyId(companyId);
		vo.setSiteId(siteId);
		List<Exam> examList = examClient.selectExamByName(vo);
		ExportByExamVO evo = null;
		List<StatisticalByUserVO> list1 = null;
		Integer joinNo = 0;  //应参加人数
		Integer actualNo = 0;  //实际参加人数
		Integer passNo = 0;  //通过人数
		BigDecimal avgScore = BigDecimal.ZERO;   //
		Double completeRate = 0D;  //通过率
		
		ExamCountByUserVO ecvo = new ExamCountByUserVO();
		ecvo.setCompanyId(companyId);
		ecvo.setSiteId(siteId);
		for(Exam e : examList){
			Long examId = e.getId();
			if(e.getVisibleRange() == 1){  //全员可见
				joinNo = siteClient.getSitAccountCount(siteId, companyId);
			}else if(e.getVisibleRange() == 2){  //指定 可见  包括用户 和 部门
				joinNo = getExamJoinNo(examId, companyId).size();
			}
			ecvo.setExamId(examId);
			list1 = examClient.examAnswerByExamId(ecvo);
			if(list1 != null && list1.size() > 0){
				actualNo = list1.size();
				passNo = 0;//list1.stream().mapToInt(StatisticalByUserVO::getIsPass).sum();
				BigDecimal sum = BigDecimal.valueOf(1);//list1.stream().map(StatisticalByUserVO::getHighScore).reduce(BigDecimal.ZERO, BigDecimal::add);
				avgScore = sum.divide(new BigDecimal(passNo), 2, RoundingMode.HALF_UP);
				completeRate = new BigDecimal((float) actualNo / joinNo).setScale(4, RoundingMode.HALF_UP).doubleValue() * 100;
			}
			evo = new ExportByExamVO();
			evo.setName(e.getName());
			evo.setStartTime(DateUtil.toSeconds(e.getStartTime()));
			evo.setEndTime(DateUtil.toSeconds(e.getEndTime()));
			evo.setJoinNo(joinNo.toString());  
			evo.setActualNo(actualNo.toString());
			evo.setPassNo(passNo.toString());
			evo.setAvgScore(avgScore.toString());
			evo.setCompleteRate(completeRate.toString() + "%");
			list.add(evo);
		}
		
		try {
			ExportExamBySiteVO exportExamBySiteVO = new ExportExamBySiteVO();
			exportExamBySiteVO.setExportName("站点考试汇总统计");
			exportExamBySiteVO.setPeriod("统计周期：" + vo.getStartTime() + " - " + vo.getEndTime());
			String[] headers = new String[]{"考试名称", "考试开始时间", "考试截止时间", "应参加人数", "实际参加人数", "通过人数", "平均分", "完成率"};
			exportExamBySiteVO.setHeaders(headers);
			exportExamBySiteVO.setVos(list);
			
			StringBuffer fileNameSb = new StringBuffer().append(vo.getExamName()).append(System.currentTimeMillis()).append(".xls");
			String fileName = fileNameSb.toString();
			String path = new StringBuffer().append(FileConstant.SAVE_PATH).append(fileNameSb).toString();
			File fileDir=new File(path);
			if(!fileDir.exists()) {
				fileDir.mkdir();
			}
			
			HSSFWorkbook workBook=null;
			FileOutputStream os=null;
			File file=null;
			try {
				os = new FileOutputStream(path);
				String exportName = exportExamBySiteVO.getExportName();
				String period = exportExamBySiteVO.getPeriod();
				List<ExportByExamVO> vos = exportExamBySiteVO.getVos();
				// 创建新的Excel 工作簿
				workBook = new HSSFWorkbook();
				
				// 在Excel工作簿中建一工作表，其名为缺省值
				HSSFSheet sheet = workBook.createSheet(exportName);
				sheet.setDefaultColumnWidth(15);
				CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, 7);
				sheet.addMergedRegion(cellRangeAddress);
				
				// 第一行
				HSSFRow row = sheet.createRow(0);
				HSSFCell cell = row.createCell(0);
				HSSFCellStyle createCellStyle = workBook.createCellStyle();
				createCellStyle.setAlignment(HorizontalAlignment.CENTER);
				cell.setCellStyle(createCellStyle);   // 居中
				cell.setCellValue(new HSSFRichTextString(exportName));

				// 第二行
				cellRangeAddress = new CellRangeAddress(1, 1, 0, 7);
				sheet.addMergedRegion(cellRangeAddress);
				row = sheet.createRow(1);
				cell = row.createCell(0);
				cell.setCellValue(period);
				
				// 第三行
				row = sheet.createRow(2);
				for(int i = 0; i < headers.length; i++){
					row.createCell(i).setCellValue(headers[i]);
				}
				
				ExportByExamVO evo1 = null;
				// 填充数据
				for (int i = 0; i < vos.size(); i++) {
					evo1 = vos.get(i);
					row = sheet.createRow(3 + i);
					row.createCell(0).setCellValue(evo1.getName());
					row.createCell(1).setCellValue(evo1.getStartTime());
					row.createCell(2).setCellValue(evo1.getEndTime());
					row.createCell(3).setCellValue(evo1.getJoinNo());
					row.createCell(4).setCellValue(evo1.getActualNo());
					row.createCell(5).setCellValue(evo1.getPassNo());
					row.createCell(6).setCellValue(evo1.getAvgScore());
					row.createCell(7).setCellValue(evo1.getCompleteRate());
					taskDetail(taskId, "导出数据第+"+i+"+行成功");
				}
				workBook.write(os);
				upload = OssUpload.upload(path, fileName,active);
				file=new File(path);
				success(taskContext, upload);
			} catch (Exception e1) {
				e1.printStackTrace();
				System.out.println("写入过程中发生错误");
			}
			finally {
				if(os!=null) {
				   os.close();
				}
				if(workBook!=null) {
				   workBook.close();
				}
				if(file!=null) {
				   file.delete();
				}
			}
			//阿里云返回url
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return upload;
	}
	
	
	
	
	// 查询应考人数列表
	public List<Long> getExamJoinNo(Long examId, Long companyId){
		List<Long> ids = new ArrayList<Long>();
		List<TrExamAuthorize> trExamAuthorizes = null;
		try{
			trExamAuthorizes = examAuthorizeClient.examCount(examId);// 查询应考人数列表
		}catch(Exception e){
			LOGGER.error("查询应考人数列表:" + e);
		}
		for(TrExamAuthorize ta : trExamAuthorizes){
			if(ta.getType() == 1){
				ids.add(ta.getRelationId());
			}else if(ta.getType() == 2){
				List<AccountVO> accountList = null;
				try{
					accountList = accountClient.accountsFindByOrgId(ta.getRelationId(), companyId);
				}catch(Exception e){
					LOGGER.error(e.getMessage());
				}
				if(accountList != null && accountList.size() > 0){
					ids.addAll(accountList.stream().map(AccountVO::getId).collect(Collectors.toList()));
				}
			}
		}
		if(ids.size() > 0){
			ids = ids.parallelStream().distinct().collect(Collectors.toList());
		}
		return ids;
	}

}
