package com.yizhi.application.assignment.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.yizhi.assignment.application.feign.AssignmentClient;
import com.yizhi.assignment.application.vo.AssignmentAnswerExport;
import com.yizhi.assignment.application.vo.AssignmentAnswerListExport;
import com.yizhi.assignment.application.vo.DownloadAnswerVO;
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.core.application.file.util.OssUpload;
import com.yizhi.system.application.system.remote.AccountClient;
import com.yizhi.system.application.system.remote.OrganizationClient;
import com.yizhi.system.application.vo.AccountVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
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.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.yizhi.application.assignment.util.FileReadUtil;

@Component
public class AssignmentReadResultExport extends AbstractDefaultTask<String, Map<String,Object>> {


	private static final Logger logger = LoggerFactory.getLogger(AssignmentReadResultExport.class);

	@Autowired
	private AssignmentClient assignmentClient;
	@Autowired
	private AccountClient accountClient;
	@Autowired
	private OrganizationClient organizationClient;
	@Autowired
	private FileReadUtil fileReadUtil;
	@Override
	protected String execute(Map<String, Object> arg0) {
		// TODO Auto-generated method stub


		Long accountId=(Long) arg0.get("accountId");
		List<Long> answerIds=(List<Long>) arg0.get("answerIds");
		Long assignmentId=(Long) arg0.get("assignmentId");
		Long siteId=(Long) arg0.get("siteId");
		Long companyId=(Long) arg0.get("companyId");
		Long taskId=(Long) arg0.get("taskId");
		Date submitTime=(Date) arg0.get("submitTime");
		String serialNo=(String) arg0.get("serialNo");
		String taskName=(String) arg0.get("taskName");

        Map<Long, String> accountOrgFullNameMap = organizationClient.getAccountOrgFullNameMap(companyId);
        logger.info("返回当前的组织列表：{}", JSON.toJSON(accountOrgFullNameMap));
		/**
		 * 走异步任务
		 */
        TaskContext taskContext = new TaskContext(taskId, serialNo, taskName, accountId, submitTime, siteId, companyId);
		working(taskContext);


		String upLoadUrl=null;
		String requestPath= FileConstant.SAVE_PATH;
		File fileDir=new File(requestPath);
		if(!fileDir.exists()) {
			fileDir.mkdir();
		}



		//批阅结果数据开始组装
		DownloadAnswerVO vo=new DownloadAnswerVO();
		vo.setAssignmentId(assignmentId);
		vo.setAnswerIds(answerIds);
		AssignmentAnswerListExport assignmentResultDate=assignmentClient.exportSuggetionExcel(vo);


		String assignmentName = fileReadUtil.getSpecialCharacter(assignmentResultDate.getName());
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		try {
			//excel生成过程: excel-->sheet-->row-->cell
			// 第一步，创建一个Excel文件
			HSSFWorkbook wb = new HSSFWorkbook();
			// 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
			HSSFSheet sheet = wb.createSheet(assignmentName+"批阅结果");
			HSSFCellStyle style = wb.createCellStyle();
			style.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式
			// 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
			HSSFRow row = sheet.createRow((int) 0);
			// 合并单元格
			CellRangeAddress cra=new CellRangeAddress(0,0,0,10); // 起始行, 终止行, 起始列, 终止列
			sheet.addMergedRegion(cra);
			HSSFCell cell = row.createCell((short) 0);
			cell.setCellValue(assignmentName+"批阅结果");
			cell.setCellStyle(style);
			// 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
			HSSFRow row2 = sheet.createRow((int) 1);
			// 第四步，创建单元格
			CellRangeAddress cra2=new CellRangeAddress(1,1,0,8);
			sheet.addMergedRegion(cra2);
			HSSFCell cell2 = row2.createCell((short) 0);
			cell2.setCellValue("统计周期：截止"+df.format(submitTime));
			HSSFRow row3 = sheet.createRow((int) 2);
			row3.createCell((short) 0).setCellValue("用户名");
			row3.createCell((short) 1).setCellValue("姓名");
			row3.createCell((short) 2).setCellValue("所在部门");
			row3.createCell((short) 3).setCellValue("所在组织架构");
			row3.createCell((short) 4).setCellValue("提交时间");
			row3.createCell((short) 5).setCellValue("批阅状态");
			row3.createCell((short) 6).setCellValue("最后批阅时间");
			row3.createCell((short) 7).setCellValue("作业成绩");
			row3.createCell((short) 8).setCellValue("作业等级");
			row3.createCell((short) 9).setCellValue("作业评语");
			row3.createCell((short) 10).setCellValue("作业内容");
			row3.createCell((short) 11).setCellValue("用户状态");
			//作业提交人的批阅信息
			List<AssignmentAnswerExport> listAss=assignmentResultDate.getList();
            setListOrder(answerIds, listAss);

			logger.info("作业后台微服务获取基本答案信息{}",listAss);
			//系统信息
			List<AccountVO> listAcc=new ArrayList<AccountVO>();
			AssignmentAnswerExport ass=new AssignmentAnswerExport();
			AccountVO acc=new AccountVO();
			//提交人的账号Id集合
			List<Long> listAccountIds=new ArrayList<Long>();
			//提交人的orgId集合
			List<Long> listOrgIds=new ArrayList<Long>();
			if(listAss!=null&&listAss.size()>0) {
				//将作业查出来的信息list装载到mapAss中     键:answerId  值:作业主体信息
				Map<Long,AssignmentAnswerExport> mapAss=new HashMap<Long,AssignmentAnswerExport>();
				for (int i = 0; i < listAss.size(); i++) {
					listAccountIds.add(listAss.get(i).getAccountId());
					mapAss.put(listAss.get(i).getAnswerId(), listAss.get(i));
				}
				//调用服务得到这些人的部门和状态信信息放在mapAcc中    键:账号id  值：账号id对应的信息
				Map<Long,AccountVO> mapAcc=new HashMap<Long,AccountVO>();
				listAcc=accountClient.idsGet(listAccountIds);
				if(listAcc!=null&&listAcc.size()>0) {
					for (int i = 0; i < listAcc.size(); i++) {
						listOrgIds.add(listAcc.get(i).getOrgId());
						mapAcc.put(listAcc.get(i).getId(), listAcc.get(i));
					}
				}


				logger.info("调用系统得到用户基本信息{}",listAcc);


				//根据orgId集合（组织Id）找到组织对应的部门全路径
				Date dateOrgIdsStart=new Date();
				Map<Long, List<String>> mapOrg=null;
				if(!CollectionUtils.isEmpty(listOrgIds)) {
					mapOrg=organizationClient.selectOrgsParentOrgs(listOrgIds);
				}
				Date dateOrgIdsEnd=new Date();
				logger.info("根据组织ID集合查询组织所有上级信息花费时间{}",(dateOrgIdsEnd.getTime()-dateOrgIdsStart.getTime())/1000);

				Long orgIdByAccountId=null;
//				List<String> orgParams=new ArrayList<String>();

				for (int i = 0; i < listAss.size(); i++) {
					ass=mapAss.get(listAss.get(i).getAnswerId());  //批阅信息的类
					acc=mapAcc.get(listAss.get(i).getAccountId()); //账号信息的类
//					orgIdByAccountId=acc.getOrgId();
//					orgParams=mapOrg.get(orgIdByAccountId);
					logger.info("作业信息--根据记录的账号Id查找到人信息{}",ass);
					logger.info("系统信息--根据记录的账号Id查找到人信息{}",acc);
//					String orgParam="";
//					if(!CollectionUtils.isEmpty(orgParams)) {
//						for (int j = 0; j < orgParams.size(); j++) {
//							orgParam=orgParam+"/"+orgParams.get(j);
//						}
//					}

					row = sheet.createRow(i + 3);
					// 第四步，创建单元格，并设置值
					if(ass!=null&&ass.getAccountName()!=null) {
						row.createCell((short) 0).setCellValue(ass.getAccountName());
					}
					if(ass!=null&&ass.getRealName()!=null) {
						row.createCell((short) 1).setCellValue(ass.getRealName());
					}
                    String fullOrgName = accountOrgFullNameMap.get(acc.getOrgId());

                    if (StringUtils.isNotEmpty(fullOrgName)) {
                        row.createCell((short) 2).setCellValue(fullOrgName.substring(fullOrgName.lastIndexOf("+")+1));
                    }
                    logger.info("返回的组织id：{}",acc.getOrgId());
					row.createCell((short) 3).setCellValue(fullOrgName);

					if(ass!=null&&ass.getCommitTime()!=null) {
						row.createCell((short) 4).setCellValue(df.format(ass.getCommitTime()));
					}
					if(ass!=null&&ass.getState()!=null) {
						row.createCell((short) 5).setCellValue(ass.getState()==1?"未阅":"已阅");
					}

					if(ass.getLastReadTime()!=null) {
					    row.createCell((short) 6).setCellValue(df.format(ass.getLastReadTime()));
					}

					if(ass.getScore()!=null) {
						row.createCell((short) 7).setCellValue(ass.getScore().toString());
					}
					if(ass.getGrade()!=null){
					    row.createCell((short) 8).setCellValue(ass.getGrade());
					}
					if(ass!=null&&ass.getSuggestion()!=null) {
						row.createCell((short) 9).setCellValue(ass.getSuggestion());
					}
					if(ass!=null&&ass.getContent()!=null) {
						row.createCell((short) 10).setCellValue(ass.getContent());
					}
					row.createCell((short) 11).setCellValue(acc==null?"":(acc.getEnabled()?"开通":"未开通"));
					//taskDetail(taskContext.getTaskId(), assignmentResultDate.getName()+"导出数据第+"+(i+1)+"+行成功");
				}
			}	

			// 第五步，写入实体数据 实际应用中这些数据从数据库得到，
			
			
			StringBuffer fileNameSb = new StringBuffer().append(assignmentName).append(System.currentTimeMillis()).append(".xls");
			String fileName = fileNameSb.toString();
			String path = new StringBuffer().append(requestPath).append(fileNameSb).toString();
			FileOutputStream os=null;
			File file=null;
			try {
				os= new FileOutputStream(path);
				wb.write(os);
				//阿里云返回url
				upLoadUrl = OssUpload.upload(path, fileName);
				file=new File(path);
				success(taskContext,"成功", upLoadUrl);
			} catch (Exception e1) {
				e1.printStackTrace();
				fail(taskContext, "写入数据到Excel的过程中或者上传到阿里云中发生错误"+e1.getMessage());
				logger.error("写入数据到Excel的过程中或者上传到阿里云中发生错误"+e1.getMessage());	
			}
			finally {
				if(os!=null) {
				   os.close();
				}
				if(wb!=null) {
				   wb.close();
				}
				if(file!=null) {
				   file.delete();
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			fail(taskContext, assignmentResultDate.getName()+"作业批阅结果导出过程中发生错误，请查看日志"+e.getMessage());	
			logger.error(assignmentResultDate.getName()+"作业批阅结果导出过程中发生错误，请查看日志"+e.getMessage());
		}
		return upLoadUrl;
	}

    /**
     * 根据所选的answerId 进行排序
     *
     * @param orderRegulation
     * @param targetList
     */
    public static void setListOrder(List<Long> orderRegulation, List<AssignmentAnswerExport> targetList) {
        Collections.sort(targetList, ((o1, o2) -> {
            int io1 = orderRegulation.indexOf(o1.getAnswerId());
            int io2 = orderRegulation.indexOf(o2.getAnswerId());

            if (io1 != -1) {
                io1 = targetList.size() - io1;
            }
            if (io2 != -1) {
                io2 = targetList.size() - io2;
            }

            return io2 - io1;
        }));
    }
}
