package com.yonyou.hrcloud.pm.ps.impl;


import com.yonyou.hrcloud.adder.model.param.Sorter;
import com.yonyou.hrcloud.adder.model.query.Condition;
import com.yonyou.hrcloud.adder.model.query.Operator;
import com.yonyou.hrcloud.pm.base.model.GradeItem;
import com.yonyou.hrcloud.pm.base.model.ImportExcel;

import com.yonyou.hrcloud.pm.common.model.PmStaff;
import com.yonyou.hrcloud.pm.helper.ListHelper;
import com.yonyou.hrcloud.pm.helper.StaffHelper;
import com.yonyou.hrcloud.pm.ps.model.*;
import com.yonyou.hrcloud.pm.ps.service.*;
import com.yonyou.hrcloud.pm.result.model.Score;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.util.WebUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 * 导入结果实现类
 *
 * @author zengcl
 */
@Service
@Transactional
public class ImportResultServiceImpl implements IImportResultService {
	@Resource
	public com.yonyou.hrcloud.adder.service.IGenericService daoex;

	@Resource
	 IExclQueryService iExclQueryService;

	@Resource
	ISchemeService schemeService;

	@Override
	public String indicatorLibImport(HttpServletRequest request, HttpServletResponse response) {
		// 一、初始化 ExcelImportHelper 对象
		String[][] headsinfo = { { "序号", "row" }, { "人员编码", "staffcode" }
				, { "姓名", "staffname" },{ "任职组织", "orgname" }
				,{ "部门", "deptname" } ,{ "考核得分", "numvalue" },{ "考核等级", "text" } };
		// 获取 workbook
		MultipartFile[] f = WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class)
				.getFileMap().values().toArray(new MultipartFile[0]);
		MultipartFile file = (f == null || f.length == 0 ? null : f[0]);
		ImportExcel helper = new ImportExcel(request, response, headsinfo, file.getName());
		// 二、读取数据
		List<Map<String, Object>> importResult = helper.readExcel();
		// 三、验证数据
		// 收集错误信息 errormap 正确的数据 arrayLists
		Map<Integer, Map<Integer, String>> errormap = new HashMap<Integer, Map<Integer, String>>(); // 行，列，错误信息。
		ArrayList<Score> arrayLists = new ArrayList<Score>();
		ArrayList<Score> arrayLists1 = new ArrayList<Score>();
		ArrayList<Sheet> arrayLists2 = new ArrayList<Sheet>();
		ArrayList<Score> arrayLists3 = new ArrayList<Score>();
		ArrayList<Score> arrayLists4 = new ArrayList<Score>();
		List<String> grades = collectMap(importResult, "text");
		Map<String, String> mapGradeName = new HashMap<String, String>();
		//获取request中的参数 schemeid 方案id
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		String schemeid = multipartRequest.getParameter("schemeid");
		//获取方案信息详情
		Scheme scheme=schemeService.querySchemeByID(schemeid,false);
		//获取存在的考核等级
		if (grades.size() > 0) {
			for(String grade : grades){
				if(grade==null){
					mapGradeName.put("text","");
				}else {
					GradeItem gradeItem = iExclQueryService.getGradeInfoByName(grade,scheme.getGradeid());
					if(gradeItem!=null) {
						mapGradeName.put(gradeItem.getGradeitemname(), gradeItem.getGradeitemname());
					}
				}
			}
		}
		
		//获取考核对象的所有信息
		List<String> listschemeid=new ArrayList();
		listschemeid.add(schemeid);
		List<EvaObject> evaObjList = queryEvaObjPageBySchemeList(listschemeid);
		List<String> staffidList = ListHelper.collect(evaObjList, "getStaffid");
		List<PmStaff> pmStaffList = StaffHelper.queryStaffByIds3(staffidList);
		String[] psncodes=new String[pmStaffList.size()];
		for(int j=0;j<psncodes.length;j++){
			psncodes[j]=pmStaffList.get(j).code;
		}

		// 对数据进行校验和补全
		for (int row = 0; row < importResult.size(); row++) {
			Map<String, Object> indidata = importResult.get(row);
			HashMap<Integer, String> errorinfo = new HashMap<Integer, String>();
			//生成两条记录  002 004
			Score score = new Score();
			Score score1=new Score();
			Score score2=new Score();
			Score score3=new Score();
			Sheet sheet;
			// 分类名称
			// 考核得分
			String numvalue = (String) indidata.get("numvalue");
			String grade = (String) indidata.get("text");
			GradeItem gradeItem=iExclQueryService.getGradeInfoByName(grade,scheme.getGradeid());
			String indiclassid = null;
//			if (StringUtils.isEmpty(grade)) {
//				errorinfo.put(7, "考核等级不能为空;");
//			} else if (StringUtils.isEmpty(mapGradeName.get(grade))) {
//				errorinfo.put(7, "考核等级数据中没有该等级;");
//			}else if(gradeItem!=null){
//				if(!StringUtils.isEmpty(numvalue)) {
//					BigDecimal bigDecimal=new BigDecimal(numvalue);
//					if (bigDecimal.compareTo(gradeItem.getLowerlimit()) == -1) {
//						errorinfo.put(6, "考核成绩超出考核等级界限,该等级界限为" + gradeItem.getLowerlimit() + "-" + gradeItem.getUpperlimit() + ";");
//					} else if (bigDecimal.compareTo(gradeItem.getUpperlimit()) == 1) {
//						errorinfo.put(6, "考核成绩超出考核等级界限,该等级界限为" + gradeItem.getLowerlimit() + "-" + gradeItem.getUpperlimit() + ";");
//					} else {
//						indiclassid = mapGradeName.get(grade);
//						indidata.put("text", indiclassid);
//						score.setText(grade);
//					}
//				}
//			}
//			else {
				indiclassid = mapGradeName.get(grade);
				indidata.put("text", indiclassid);
				score.setText(grade);
//			}

			// 人员编码
			String staffcode = (String) indidata.get("staffcode");
			if (StringUtils.isEmpty(staffcode)) {
				errorinfo.put(2, "人员编码不能为空;");
			} else{
					String name=iExclQueryService.getPsnBycode(staffcode);
					if("".equals(name)||name==null){
						errorinfo.put(2, "该人员不存在，请勿修改模板原本信息;");
					}else if(!Arrays.asList(psncodes).contains(staffcode))
					{
						errorinfo.put(2, "该方案不存在该考核人员;");
					}else{
						indidata.put("staffcode", staffcode);
						if(score.getText()!=null) {
							score.setStaffid(staffcode);
						}
					}
			}

			if(StringUtils.isEmpty(numvalue)){
//				errorinfo.put(6, "考核成绩不能为空;");
				score.setNumvalue(null);
			} else{
				if(isNumeric(numvalue)) {
					indidata.put("numvalue", numvalue);
					if(score.getText()!=null && score.getStaffid()!=null) {
						score.setNumvalue(new BigDecimal(numvalue));
					}
				}else{
//					errorinfo.put(6, "考核成绩只能是数值;");
					score.setNumvalue(null);
				}
			}
			if (errorinfo.size() > 0) {
				errormap.put(row, errorinfo);
			}

			//组装所有正确信息
			if(score.getText()!=null&& score.getStaffid()!=null) {
				String psnPk=null;
				String deptid=null;
				for(PmStaff staff:pmStaffList){
					if(staffcode.equals(staff.code)){
						psnPk=staff.id;
						deptid=staff.deptid;
					}
				}
				//010
				score.setColumncode("003");
				score.setPeriodcode(scheme.getPeriodcode());
				score.setStaffid(psnPk);
				score.setDeptid(deptid);
				sheet=iExclQueryService.querySheetID(schemeid,psnPk);
				score.setSheetid(sheet!=null?sheet.getId():null);
				score.setSchemeid(schemeid);
				score.setDeptname(indidata.get("deptname").toString());
				
				//003 ,002,004,010 显示分数, 显示等级  
				BeanUtils.copyProperties(score,score1);
				BeanUtils.copyProperties(score,score2);
				BeanUtils.copyProperties(score,score3);
				score1.setColumncode("010");
				score2.setColumncode("002");
				score3.setColumncode("004");
//				score.setNumvalue(null);
				if(sheet!=null) {
					sheet.setIsover(true);
					sheet.setIsaudit(Boolean.TRUE);
					sheet.setIscalc(Boolean.TRUE);
					sheet.setMarkStatus(4);
					arrayLists2.add(sheet);
				}
				arrayLists1.add(score1);
				arrayLists.add(score);
				arrayLists3.add(score2);
				arrayLists4.add(score3);
			}
		}
		//正确的数据进行插入更新
		if(arrayLists.size()>0){
			scheme.setSchemestate(5);
			
//			scheme.setIsresultaudited(true);
			//存在的数据进行更新分数003，更新等级010
			for(int sc=0;sc<arrayLists.size();sc++){
				if(iExclQueryService.checkExistScore(schemeid,arrayLists.get(sc).getStaffid(),arrayLists.get(sc).getColumncode())){
					iExclQueryService.updateScore(arrayLists.get(sc));
				}else {
					//不存在的数据进行插入
					daoex.insert(arrayLists.get(sc));
				}
				if(iExclQueryService.checkExistScore(schemeid,arrayLists1.get(sc).getStaffid(),arrayLists1.get(sc).getColumncode())){
					iExclQueryService.updateScore(arrayLists1.get(sc));
				}else{
					daoex.insert(arrayLists1.get(sc));
				}
				if(iExclQueryService.checkExistScore(schemeid,arrayLists1.get(sc).getStaffid(),arrayLists3.get(sc).getColumncode())){
					iExclQueryService.updateScore(arrayLists3.get(sc));
					}else{
					daoex.insert(arrayLists3.get(sc));
				}
				if(iExclQueryService.checkExistScore(schemeid,arrayLists1.get(sc).getStaffid(),arrayLists4.get(sc).getColumncode())){
					iExclQueryService.updateScore(arrayLists4.get(sc));
					}else{
					daoex.insert(arrayLists4.get(sc));
				}
				if(arrayLists2.size()>0) {
					daoex.update(arrayLists2.get(sc));
				}
			}
			daoex.update(scheme);
			//执行完后更新 考核方案信息
		}
		//下载错误信息
		if (errormap.size() > 0) {
//			Object url = ExcelUtilForEntryResult.uploadErrorExcel(getOutPutDataList(dataList,errorInfoList,scheme.getApplyobj()));
//            errorResult.put("msgcode", 500);
//            errorResult.put("key", url);
//            errorResult.put("msginfo", "导入文件中存在错误数据,请检查后重新导入，正确数据已导入");
//            return errorResult;
			String url = helper.writeErrormsgToExcel(errormap);
			return url;
		}
		return null;
	}

	/**
	 * Map转集合
	 *
	 * @return
	 */
	public static <T> List<String> collectMap(List<Map<String, T>> objList, String getProp) {
		Set<String> keys = new LinkedHashSet<>();
		try {
			for (int i = 0; i < objList.size(); i++) {
				Map<String, T> item = objList.get(i);
				T v = item.get(getProp);
				if(v!=null) {
					keys.add((String) v);
				}
			}
			List<String> ret = new ArrayList<>(keys);
			return ret;
		} catch (Exception e) {
			return new ArrayList<>();
		}
	}

	/**
	 * 判断是否为数值
	 * @param str
	 * @return
	 */
	public boolean isNumeric(String str){
//		Pattern pattern = Pattern.compile("-?[0-9]+.?[0-9]+");
		Pattern pattern = Pattern.compile("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
		Matcher isNum = pattern.matcher(str);
		if( !isNum.matches() ){
			return false;
		}
		return true;
	}


	/**
	 * @author ZhangTao
	 * @description 根据方案查询对应的考核对象
	 * @date 2019/6/20
	 * @param schemeidList
	 * @return java.util.List<com.yonyou.hrcloud.pm.ps.model.EvaObject>
	 **/
	private List<EvaObject> queryEvaObjPageBySchemeList(List<String> schemeidList){
		Condition evaObjCondition = new Condition();
		evaObjCondition.addExpression("schemeid",schemeidList,Operator.IN);
		Sorter evaObjSort = new Sorter(Sort.Direction.ASC,"groupid");
		List<EvaObject> evaObjList = daoex.find(EvaObject.class,evaObjCondition,evaObjSort);
		return evaObjList;
	}


}
