package com.qmth.qrzk.repository.user.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.qmth.qrzk.repository.common.base.BaseDao;
import com.qmth.qrzk.repository.service.query.TaskQueryParams;
import com.qmth.qrzk.repository.task.TaskBatch;
import com.qmth.qrzk.repository.user.model.AuditQuesTask;
import com.qmth.qrzk.repository.user.model.AuditQuesTaskUserLink;
import com.qmth.qrzk.repository.user.model.AuditorJob;
import com.qmth.qrzk.repository.user.model.Course;
import com.qmth.qrzk.repository.user.model.User;
import com.qmth.qrzk.repository.utils.Consts;
import com.qmth.qrzk.repository.utils.General;

@Service
public class AuditQuesTaskServiceImpl {
	
	@Autowired private BaseDao dao;
	
	@Autowired
	private CourseServiceImpl courseService;
	
	@Autowired
	private BookServiceImpl bookService;
	
	@Autowired
	private TaskBatchImpl taskBatchService;
	
	public List<AuditQuesTask> getAuditQuesTasksWithStatByBatchId(int batchId){
		List<AuditQuesTask> tasks = dao.getList("getAuditQuesTasksByBatchId", batchId);
		Map<Integer,Object[]> auditorDataMap = new LinkedHashMap<Integer, Object[]>();
		for(AuditQuesTask t:tasks){
			List<Map<String,Object>> statInfo = dao.getList("statAuditQuesTaskById", t.getId());
			for(Map<String,Object> stat:statInfo){
				String statusCode = (String)stat.get("statusCode");
				int num = General.toInteger(stat.get("num"), 0);
				if("QUESTION_DRAFT".equals(statusCode)){
					t.setDraftNum(num);
				}else if("QUESTION_APPROVED".equals(statusCode)){
					t.setApprovedNum(num);
				}else if("QUESTION_REJECTED".equals(statusCode)){
					t.setRejectedNum(num);
				}
			}
			t.setCourseCode(t.getCourse().getCode());
			t.setCourseName(t.getCourse().getName());
			String auditors = "";
			for(AuditQuesTaskUserLink ul:t.getAuditorLinks()){
				Map<String,Object> param = new HashMap<String, Object>();
				param.put("courseId", t.getCourseId());
				param.put("auditor", ul.getAuditorId());
				List<Map<String,Object>> statInfo2 = dao.getList("statAuditorJobByCourseIdAndAuditorId", param);
				int approvedNum = 0;
				int rejectedNum = 0;
				for(Map<String,Object> stat:statInfo2){
					String statusCode = (String)stat.get("statusCode");
					int num = General.toInteger(stat.get("num"), 0);
					if("QUESTION_APPROVED".equals(statusCode)){
						approvedNum = num;
					}else if("QUESTION_REJECTED".equals(statusCode)){
						rejectedNum = num;
					}
				}
				Object[] auditorData = auditorDataMap.get(ul.getAuditorId());
				if(auditorData == null){
					auditorData = new Object[3];
					auditorDataMap.put(ul.getAuditorId(), auditorData);
					auditorData[0] = Consts.UserMap.get(ul.getAuditorId()).getName();
					auditorData[1] = 0;
					auditorData[2] = 0;
				}
				auditorData[1] = (Integer)auditorData[1] + approvedNum;
				auditorData[2] = (Integer)auditorData[2] + rejectedNum;
				auditors = auditors + Consts.UserMap.get(ul.getAuditorId()).getName() + "(" + approvedNum + "," + rejectedNum + ")，";
			}
			if(auditors.length() > 0){
				auditors = auditors.substring(0, auditors.length() - 1);
			}
			t.setAuditors(auditors);
		}
		{
			AuditQuesTask total = new AuditQuesTask();
			total.setCourseCode("总计");
			total.setCourseName("");
			String auditors = "";
			for(Object[] auditorData:auditorDataMap.values()){
				auditors = auditors + auditorData[0] + "(" + auditorData[1] + "," + auditorData[2] + ")，";
			}if(auditors.length() > 0){
				auditors = auditors.substring(0, auditors.length() - 1);
			}
			total.setAuditors(auditors);
			for(AuditQuesTask job:tasks){
				total.setDraftNum(total.getDraftNum() + job.getDraftNum());
				total.setApprovedNum(total.getApprovedNum() + job.getApprovedNum());
				total.setRejectedNum(total.getRejectedNum() + job.getRejectedNum());
			}
			tasks.add(total);
		}
		return tasks;
	}
	
	public List<AuditQuesTask> getAuditQuesTasksByBatchId(int batchId){
		List<AuditQuesTask> tasks = dao.getList("getAuditQuesTasksByBatchId", batchId);
		for(AuditQuesTask t:tasks){
			t.setCourseCode(t.getCourse().getCode());
			t.setCourseName(t.getCourse().getName());
			String auditors = "";
			for(AuditQuesTaskUserLink ul:t.getAuditorLinks()){
				Map<String,Object> param = new HashMap<String, Object>();
				param.put("courseId", t.getCourseId());
				param.put("auditor", ul.getAuditorId());
				auditors = auditors + Consts.UserMap.get(ul.getAuditorId()).getName() + "，";
			}
			if(auditors.length() > 0){
				auditors = auditors.substring(0, auditors.length() - 1);
			}
			t.setAuditors(auditors);
		}
		return tasks;
	}
	
	public List<AuditQuesTask> queryTodoAuditQuesTasks(TaskQueryParams params){
		return dao.getPagerList("queryTodoAuditQuesTasks", params);
	}
	
	public AuditQuesTask getAuditQuesTaskById(int taskId){
		AuditQuesTask task = dao.get("getAuditQuesTaskById", taskId);
		return task;
	}
	
	public AuditQuesTask addAuditQuesTask(AuditQuesTask task,User curUser){
		TaskBatch taskBatch = taskBatchService.findById(task.getBatchId());
		task.setPlanStartTime(taskBatch.getPlanStartTime());
		task.setPlanEndTime(taskBatch.getPlanEndTime());
		
		task.setCreatedBy(curUser.getId());
		task.setCreatedTime(new Date());
		task.setUpdatedBy(curUser.getId());
		task.setUpdatedTime(new Date());
		dao.insert("addAuditQuesTask", task);
		for(AuditQuesTaskUserLink userLink:task.getAuditorLinks()){
			userLink.setAuditQuesTaskId(task.getId());
			dao.insert("addAuditQuesTaskUserLink", userLink);
		}
		return getAuditQuesTaskById(task.getId());
	}
	
	public void deleteAuditQuesTasks(int[] taskIds){
		for(int id:taskIds){
			dao.delete("delAuditQuesTaskUserLinksByTaskId", id);
			dao.delete("delAuditQuesTaskById", id);
		}
	}

	public void deleteAuditQuesTaskById(int id){
		dao.delete("delAuditQuesTaskUserLinksByTaskId", id);
		dao.delete("delAuditQuesTaskById", id);
	}
	
	public void updateAuditQuesTask(AuditQuesTask task){
		dao.update("updateAuditQuesTask", task);
		updateAuditQuesTaskUserLinks(task);
	}
	
	public void updateAuditQuesTaskUserLinks(AuditQuesTask task){
		dao.delete("delAuditQuesTaskUserLinksByTaskId", task.getId());
		for(AuditQuesTaskUserLink userLink:task.getAuditorLinks()){
			userLink.setAuditQuesTaskId(task.getId());
			dao.insert("addAuditQuesTaskUserLink", userLink);
		}
	}
	
	public void saveImportData(int batchId,List<AuditQuesTask> list,JSONObject object,User curUser){
		TaskBatch taskBatch = taskBatchService.findById(batchId);
		List<String> loginList=new ArrayList<String>();
		Map<String,User> tempMap=new HashMap<String,User>();
		for(Map.Entry<Integer, User> entry : Consts.UserMap.entrySet()){
			tempMap.put(entry.getValue().getLoginName(), entry.getValue());
			loginList.add(entry.getValue().getLoginName());
		}
		boolean existsCourseCode=true;
		boolean isSameCourseCode=false;
		int i=1;
		Set<String> courseCodeSet = new HashSet<String>();
		
		List<AuditQuesTask> paperTasks = dao.getList("getAuditQuesTasksByBatchId", batchId);
		
		//把当前批次下所有的课程代码和任务单编号放到map里面
		for(AuditQuesTask pp:paperTasks){
			Course course=courseService.findById(pp.getCourseId());
			courseCodeSet.add(course.getCode());
		}
		
		for(AuditQuesTask at:list){
			
			Course course=courseService.findByCode(at.getCourseCode());
			//校验课程代码是否在系统中存在
			if(course==null){
				existsCourseCode=false;
				break;
			}
			//校验课程代码是否在批次中存在
			if(courseCodeSet.contains(at.getCourseCode())){
				isSameCourseCode=true;
				break;
			}
			
			String[] auditorArr = at.getAuditors().split(",|，");
			for(String auditorLoginName:auditorArr){
				if(!loginList.contains(auditorLoginName)){
					//返回前端用户登录名不存在
					object.put("result", "fail");
					object.put("lineNum",i );
					object.put("msg", "审题教师[" + auditorLoginName + "]用户信息不存在");
					return;
				}
				AuditQuesTaskUserLink userLink = new AuditQuesTaskUserLink();
				userLink.setAuditorId(tempMap.get(auditorLoginName).getId());
				at.getAuditorLinks().add(userLink);
			}
			i++;
		}
		
		if(!existsCourseCode){
			object.put("result", "fail");
			object.put("lineNum",i);
			object.put("msg", "导入的课程代码在基础库中不存在");
		}else if(isSameCourseCode){	//导入的信息中存在相同的courseCode
			object.put("result", "fail");
			object.put("lineNum",i);
			object.put("msg", "导入的文件该批次下存在相同的课程编号");
		}else{
			for(AuditQuesTask at:list){
				Course course=courseService.findByCode(at.getCourseCode());
				at.setCourseId(course.getId());
				at.setBatchId(batchId);
				at.setPlanStartTime(taskBatch.getPlanStartTime());
				at.setPlanEndTime(taskBatch.getPlanEndTime());
				
				at.setCreatedBy(curUser.getId());
				at.setCreatedTime(new Date());
				at.setUpdatedBy(curUser.getId());
				at.setUpdatedTime(new Date());
				dao.insert("addAuditQuesTask", at);
				for(AuditQuesTaskUserLink userLink:at.getAuditorLinks()){
					userLink.setAuditQuesTaskId(at.getId());
					dao.insert("addAuditQuesTaskUserLink", userLink);
				}
			}
			if(object.isEmpty()){
				object.put("result", "success");
				object.put("successNum", list.size());
				object.put("msg", "导入成功!");
			}
		}
	}
	
	public List<AuditorJob> statBatchAuditorJob(int batchId){
		Map<Integer,AuditorJob> jobMap = new HashMap<Integer, AuditorJob>();
		List<Integer> allAuditorIds = dao.getList("getAllAuditorIdsByBatchId",batchId);
		for(Integer auditorId:allAuditorIds){
			AuditorJob job = new AuditorJob();
			job.setAuditorId(auditorId);
			job.setAuditorName(Consts.UserMap.get(auditorId).getName());
			jobMap.put(auditorId, job);
		}
		
		List<Map<String,Object>> statInfo = dao.getList("statBatchAuditorJobByBatchId", batchId);
		for(Map<String,Object> stat:statInfo){
			int auditorId = General.toInteger(stat.get("auditorId"), 0);
			AuditorJob job = jobMap.get(auditorId);
			if(job == null){
				job = new AuditorJob();
				job.setAuditorId(auditorId);
				job.setAuditorName(Consts.UserMap.get(auditorId).getName());
				jobMap.put(auditorId, job);
			}
			String statusCode = (String)stat.get("statusCode");
			int num = General.toInteger(stat.get("num"), 0);
			if("QUESTION_APPROVED".equals(statusCode)){
				job.setApprovedNum(num);
			}else if("QUESTION_REJECTED".equals(statusCode)){
				job.setRejectedNum(num);
			}
		}
		List<AuditorJob> jobs = new ArrayList<AuditorJob>(jobMap.values());
		Collections.sort(jobs, new Comparator<AuditorJob>() {
			@Override
			public int compare(AuditorJob o1, AuditorJob o2) {
				int compareValue = o2.getApprovedNum() - o1.getApprovedNum();
				if(compareValue == 0){
					compareValue = o2.getRejectedNum() - o1.getRejectedNum();
				}
				return compareValue;
			}
		});
		AuditorJob total = new AuditorJob();
		total.setAuditorName("总计");
		for(AuditorJob job:jobs){
			total.setDraftNum(total.getDraftNum() + job.getDraftNum());
			total.setApprovedNum(total.getApprovedNum() + job.getApprovedNum());
			total.setRejectedNum(total.getRejectedNum() + job.getRejectedNum());
		}
		jobs.add(total);
		return jobs;
	}
}
