package nccloud.impl.hryf.handover.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.hr.utils.InSQLCreator;
import nc.hr.utils.PubEnv;
import nc.hr.utils.SQLHelper;
import nc.itf.hi.entrymng.IEntrymngQueryService;
import nc.itf.hr.frame.IPersistenceRetrieve;
import nc.itf.hr.frame.IPersistenceUpdate;
import nc.itf.trn.transmng.ITransmngQueryService;
import nc.itf.uap.rbac.IUserManageQuery;
import nc.itf.uap.rbac.IUserManageQuery_C;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.vo.hi.entrymng.AggEntryapplyVO;
import nc.vo.hi.entrymng.EntryapplyVO;
import nc.vo.hi.entrymng.EntrymngConst;
import nc.vo.hi.psndoc.CtrtVO;
import nc.vo.hi.psndoc.PsnJobVO;
import nc.vo.ml.MultiLangUtil;
import nc.vo.org.DeptVO;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.sm.UserVO;
import nc.vo.trn.pub.TRNConst;
import nc.vo.trn.transmng.AggStapply;
import nc.vo.trn.transmng.StapplyVO;
import nc.vo.uif2.LoginContext;
import nccloud.commons.lang.ArrayUtils;
import nccloud.commons.lang.StringUtils;
import nccloud.dto.hryf.handitem.HandItemVO;
import nccloud.dto.hryf.handitemset.HandCondVO;
import nccloud.dto.hryf.handitemset.HandItemSetVO;
import nccloud.dto.hryf.handover.HandoverVO;
import nccloud.itf.hrsscpub.utils.BusiActionConst;
import nccloud.itf.hrsscpub.utils.WorkLoadCountUtil;
import nccloud.itf.hryf.dimissionmng.IDimissionmngService;
import nccloud.itf.hryf.entrymng.IEntrymngService;
import nccloud.itf.hryf.handitem.IHanditemsService;
import nccloud.itf.hryf.handover.IHandoverService;

public class HandoverServiceImpl implements IHandoverService {

	private BaseDAO baseDAO;

	public BaseDAO getBaseDAO() {
		if (baseDAO == null) {
			baseDAO = new BaseDAO();
		}
		return baseDAO;
	}

	@Override
	public void createHandoverList(String pk_bill, int type) throws BusinessException {
		AggregatedValueObject agg = null;
		if (type == 1) {
			agg = NCLocator.getInstance().lookup(IEntrymngQueryService.class).queryByPk(pk_bill);
		} else if (type == 2) {
			agg = NCLocator.getInstance().lookup(ITransmngQueryService.class).queryByPk(pk_bill);
		}
		if (agg == null) {
			return;
		}

		IPersistenceRetrieve service = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
		String pk_psnjob = (String) agg.getParentVO().getAttributeValue("pk_psnjob");
		PsnJobVO psnjob = (PsnJobVO) service.retrieveByPk(null, PsnJobVO.class, pk_psnjob);
		CtrtVO[] ctrts = (CtrtVO[]) service.retrieveByClause(null, CtrtVO.class, "pk_psnorg = '" + psnjob.getPk_psnorg() + "' and lastflag = 'Y'");

		String pk_org = (String) agg.getParentVO().getAttributeValue("pk_org");
		String sql = " pk_org = '" + pk_org + "' and type = " + type + " ";
		String pk_majorcorp = ArrayUtils.isEmpty(ctrts) ? null : ctrts[0].getPk_majorcorp();
		if (StringUtils.isBlank(pk_majorcorp)) {
			sql += " and ( " + SQLHelper.getNullSql("pk_adminorg") + " ) ";
		} else {
			sql += " and ( pk_adminorg = '" + pk_majorcorp +  "' or " + SQLHelper.getNullSql("pk_adminorg") +" ) ";
		}
		String pk_pnscl = psnjob.getPk_psncl();
		if (StringUtils.isBlank(pk_pnscl)) {
			sql += " and ( " + SQLHelper.getNullSql("pk_psncl") + " ) ";
		} else {
			sql += " and ( pk_psncl = '" + pk_pnscl +  "' or " + SQLHelper.getNullSql("pk_psncl") +  " ) ";
		}

		String order = " order by case when pk_psncl <> '~' then 1 else 0 end + case when pk_adminorg <> '~' then 2 else 0 end  desc";

		HandCondVO[] conds = (HandCondVO[]) service.retrieveByClause(null, HandCondVO.class, sql + order);
		if (ArrayUtils.isEmpty(conds)) {
			return;
		}

		HandItemSetVO[] items = (HandItemSetVO[]) service.retrieveByClause(null, HandItemSetVO.class, "pk_handcond = '" + conds[0].getPk_handcond() + "'");
		if (ArrayUtils.isEmpty(items)) {
			return;
		}
		
		UserVO[] userVO = (UserVO[]) service.retrieveByClause(null, UserVO.class, "user_name = '部门负责人' and nvl(dr,0) = 0");
		String userid = "";
		if(userVO != null && userVO.length > 0) {
			userid = userVO[0].getCuserid();
		}
		DeptVO deptVO = (DeptVO) service.retrieveByPk(null, DeptVO.class, psnjob.getPk_dept());
		String deptPrincipal = "";//部门负责人
		if(deptVO != null) {
			UserVO[] deptUserVO = (UserVO[]) service.retrieveByClause(null, UserVO.class, " pk_psndoc = '"+deptVO.getPrincipal()+"' and nvl(dr,0) = 0");
			if(deptUserVO != null && deptUserVO.length > 0) {
				deptPrincipal = deptUserVO[0].getCuserid();
			}
		}
		
		HandoverVO[] handovers = new HandoverVO[items.length];
		ArrayList<String> userList = new ArrayList<>();
		for (int i = 0; i < handovers.length; i++) {
			handovers[i] = new HandoverVO();
			handovers[i].setIscheck(UFBoolean.FALSE);
			handovers[i].setPk_bill(pk_bill);
			handovers[i].setPk_psndoc(psnjob.getPk_psndoc());
			handovers[i].setPk_psnjob(pk_psnjob);
			if (ctrts != null && ctrts.length > 0) {
				handovers[i].setPk_psndoc_ctrt(ctrts[0].getPk_psndoc_sub());
			}
			handovers[i].setPk_handitem(items[i].getPk_handitem());
			//add by@chenzf 如果pk_handler为虚拟部门负责人用户的话，则查询对应人员部门的负责人 2021-10-13 08:53:08 begin
			if(!"".equals(userid) && StringUtils.isNotBlank(items[i].getPk_handler()) && Arrays.asList(items[i].getPk_handler().split(",")).contains(userid)) {
				if(StringUtils.isBlank(deptVO.getPrincipal())) {
					HandItemVO handItemVO = (HandItemVO) service.retrieveByPk(null, HandItemVO.class, items[i].getPk_handitem());
					throw new BusinessException("入职事项"+handItemVO.getName()+"需要部门负责人处理，未维护该部门负责人，无法确认入职");
				}
				String pk_handler = items[i].getPk_handler();
				if(StringUtils.isNotBlank(deptPrincipal)) {
					pk_handler = pk_handler.replace(userid, deptPrincipal);
				}
				handovers[i].setPk_linkman(pk_handler);
				if (StringUtils.isNotBlank(pk_handler)) {
					userList.addAll(Arrays.asList(pk_handler.split(",")));
				}
			}else {
				handovers[i].setPk_linkman(items[i].getPk_handler());
				if (StringUtils.isNotBlank(items[i].getPk_handler())) {
					userList.addAll(Arrays.asList(items[i].getPk_handler().split(",")));
				}
			}
			//add by@chenzf 如果pk_handler为虚拟部门负责人用户的话，则查询对应人员部门的负责人 2021-10-13 08:53:08 end
			handovers[i].setSetmemo(items[i].getMemo());
			handovers[i].setCreator(PubEnv.getPk_user());
			handovers[i].setCreationtime(PubEnv.getServerTime());
			handovers[i].setPk_group(PubEnv.getPk_group());
			handovers[i].setPk_org(pk_org);
		}
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).insertVOArray(null, handovers, null);

		if (type == 2 && userList.size() > 0) {
			// 如果是生成离职交接项,需要给办理人发送通知
			NCLocator.getInstance().lookup(IDimissionmngService.class).sendEmail((AggStapply) agg, "60080202", userList.toArray(new String[0]), false);
		}
		//增加入职交接项负责人发送通知
		if (type == 1 && userList.size() >0) {
			//如果生成入职交接项，需要给办理人发送通知
			LoginContext context = new LoginContext();
			context.setPk_org(pk_org);
			NCLocator.getInstance().lookup(IEntrymngService.class).sendEmail(context,(AggEntryapplyVO) agg, null,"60080109", userList.toArray(new String[0]), false);
		}
	}

	@Override
	public String[] queryPKsByCondition(Integer type, String condition) throws BusinessException {
		if (condition.indexOf("pk_psnjob in") >= 0) {
			condition = condition.replace("pk_psnjob in", "ho.pk_psnjob in");
		}
		if (condition.indexOf("pk_psndoc_ctrt in (") >= 0) {
			condition = condition.replace("pk_psndoc_ctrt in (", "ho.pk_psndoc_ctrt in (");
		}
		if (condition.indexOf("pk_psndoc in (") >= 0) {
			condition = condition.replace("pk_psndoc in (", "ho.pk_psndoc in (");
		}
		String sql = null;
		if (type == 1) {
			// sql = " SELECT ho.pk_handover FROM hi_handover ho JOIN hi_entryapply he ON ho.pk_bill = he.pk_entryapply WHERE " + condition;
			sql = " SELECT distinct ho.pk_bill FROM hi_handover ho JOIN hi_entryapply he ON ho.pk_bill = he.pk_entryapply WHERE " + condition + " AND ho.pk_linkman like '%"
					+ PubEnv.getPk_user() + "%' ";
		} else {
			// sql = " SELECT ho.pk_handover FROM hi_handover ho JOIN hi_stapply hs ON ho.pk_bill = hs.pk_hi_stapply WHERE " + condition;
			sql = " SELECT distinct ho.pk_bill FROM hi_handover ho JOIN hi_stapply hs ON ho.pk_bill = hs.pk_hi_stapply WHERE " + condition + " AND ho.pk_linkman like '%"
					+ PubEnv.getPk_user() + "%' ";
		}
		ArrayList<String> al = (ArrayList<String>) new BaseDAO().executeQuery(sql, new ColumnListProcessor());
		if (al != null && !al.isEmpty()) {
			return al.toArray(new String[0]);
		}
		return null;
	}

	@Override
	public List<HandoverVO> queryHandoverVOByCond(String cond, String order) throws BusinessException {
		cond += " AND pk_linkman like '%" + PubEnv.getPk_user() + "%' ";
		String sql = " SELECT * FROM hi_handover WHERE " + cond;
		List<HandoverVO> list = (List<HandoverVO>) new BaseDAO().executeQuery(sql, new BeanListProcessor(HandoverVO.class));
		List<HandoverVO> retList = new ArrayList<HandoverVO>();
		if (list != null && !list.isEmpty()) {
			for (HandoverVO vo : list) {
				if (retList.isEmpty()) {
					retList.add(vo);
				} else {
					boolean flag = false;
					for (HandoverVO retvo : retList) {
						if (vo.getPk_bill().equals(retvo.getPk_bill())) {
							flag = true;
						}
					}
					if (!flag) {
						retList.add(vo);
					}
				}
			}
		}
		return retList;
	}

	@Override
	public HandoverVO[] qryByPkbill(String pk_bill, String type, LoginContext context) throws BusinessException {
		// enablestate; //启用状态 2：已启用， 3：已停用
		Integer enablestate = 2;
		String[] pk_handitems = NCLocator.getInstance().lookup(IHanditemsService.class).queryPKsByCondition(context, null, type, enablestate);
		if (ArrayUtils.isEmpty(pk_handitems)) {
			return null;
		}
		String sql = new InSQLCreator().getInSQL(pk_handitems);
		String cond = " pk_group = '" + context.getPk_group() + "' AND pk_org = '" + context.getPk_org() + "' AND pk_bill = '" + pk_bill + "' AND pk_handitem IN (" + sql + ")";
		HandoverVO[] vos = (HandoverVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null, HandoverVO.class, cond);
		setLinkmaninfo(vos);
		return vos;
	}

	/**
	 * 设置联系人详情信息
	 *
	 * @param vos
	 * @throws BusinessException
	 */
	private void setLinkmaninfo(HandoverVO[] vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos)) {
			return;
		}
		// 获取联系人主键信息
		List<String> userPKsList = new ArrayList<String>();
		for (HandoverVO vo : vos) {
			String pk_linkman = vo.getPk_linkman();
			if (StringUtils.isNotEmpty(pk_linkman)) {
				String[] arr = pk_linkman.split(",");
				for (String pk : arr) {
					if (!userPKsList.contains(pk)) {
						userPKsList.add(pk);
					}
				}
			}
		}
		if (userPKsList.isEmpty()) {
			return;
		}
		String insql = new InSQLCreator().getInSQL(userPKsList.toArray(new String[0]));
		UserVO[] userVOs = NCLocator.getInstance().lookup(IUserManageQuery_C.class).findUserByIDs(userPKsList.toArray(new String[0]));
		if (!ArrayUtils.isEmpty(userVOs)) {
			String sql = "select sm_user.cuserid , " + getLangNameColume("sm_user.user_name") + " as psnname, bd_psndoc.email , bd_psndoc.mobile ,"
					+ getLangNameColume("org_dept.name") + " as deptname from sm_user "
					+ "left outer join bd_psndoc on bd_psndoc.pk_psndoc = sm_user.pk_psndoc left outer join hi_psnorg on bd_psndoc.pk_psndoc = hi_psnorg.pk_psndoc and hi_psnorg.lastflag = 'Y' "
					+ "left outer join hi_psnjob on hi_psnorg.pk_psnorg = hi_psnjob.pk_psnorg and hi_psnjob.ismainjob = 'Y' and hi_psnjob.lastflag = 'Y' "
					+ "left outer join org_dept on org_dept.pk_dept = hi_psnjob.pk_dept  where  cuserid in(" + insql + ")";
			List<Map<String, String>> linkmaninfoList = (List<Map<String, String>>) getBaseDAO().executeQuery(sql, new MapListProcessor());
			Map<String, String> linkmaninfoMap = new HashMap<String, String>();
			if (linkmaninfoList != null && !linkmaninfoList.isEmpty()) {
				StringBuffer strBuf = null;
				for (Map<String, String> map : linkmaninfoList) {
					if (!linkmaninfoMap.containsKey(map.get("cuserid"))) {
						strBuf = new StringBuffer();
						String psnname = map.get("psnname") == null ? "" : map.get("psnname");
						String deptname = map.get("deptname") == null ? "" : map.get("deptname");
						String email = map.get("email") == null ? "" : map.get("email");
						String mobile = map.get("mobile") == null ? "" : map.get("mobile");
						strBuf.append("cuserid:" + map.get("cuserid")).append(",psnname:" + psnname).append(",deptname:" + deptname).append(",email:" + email)
								.append(",mobile:" + mobile);
						linkmaninfoMap.put(map.get("cuserid"), strBuf.toString());
					}
				}

				// 处理联系人没有关联人员的用户数据begin
				List<String> noEmpUserList = new ArrayList<String>();
				if (userPKsList != null && !userPKsList.isEmpty()) {
					for (String pk : userPKsList) {
						if (!linkmaninfoMap.containsKey(pk)) {
							if (!noEmpUserList.contains(pk)) {
								noEmpUserList.add(pk);
							}
						}
					}
				}
				if (noEmpUserList != null && !noEmpUserList.isEmpty()) {
					UserVO[] uservos = NCLocator.getInstance().lookup(IUserManageQuery.class).findUserByIDs(noEmpUserList.toArray(new String[0]));
					if (uservos != null && uservos.length > 0) {
						for (UserVO user : uservos) {
							strBuf.append("cuserid:" + user.getCuserid()).append(",psnname:" + user.getUser_name()).append(",deptname:" + "").append(",email:" + "")
									.append(",mobile:" + "");
							linkmaninfoMap.put(user.getCuserid(), strBuf.toString());
						}
					}
				}
				// 处理联系人没有关联人员的用户数据 end

				StringBuffer linkmaninfo = null;
				for (HandoverVO vo : vos) {
					String pk_linkman = vo.getPk_linkman();
					linkmaninfo = new StringBuffer();
					if (StringUtils.isNotEmpty(pk_linkman)) {
						String[] arr = pk_linkman.split(",");
						for (String pk : arr) {
							if (linkmaninfoMap.containsKey(pk)) {
								linkmaninfo.append(linkmaninfoMap.get(pk) + ";");
							}
						}
					}
					vo.setLinkmaninfo(linkmaninfo.toString());
				}
			}
		}
	}

	private String getLangNameColume(String nameField) {
		String multilangIndex = MultiLangUtil.getCurrentLangSeqSuffix();
		if (StringUtils.isBlank(multilangIndex)) {
			return nameField;
		}

		String currLangName = nameField + multilangIndex;
		return " isnull(" + currLangName + "," + nameField + ")";
	}

	@Override
	public void updateHandoverVOs(HandoverVO[] vos) throws BusinessException {
		String[] selFields = { "ischeck", "checker", "checkdate", "modifier", "modifiedtime", "memo" };
		for (HandoverVO vo : vos) {
			vo.setIscheck(UFBoolean.TRUE);
			vo.setChecker(PubEnv.getPk_user());
			vo.setCheckdate(PubEnv.getServerLiteralDate());
			vo.setModifier(PubEnv.getPk_user());
			vo.setModifiedtime(PubEnv.getServerTime());
		}
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVOArray(null, vos, selFields, null);
		// 工作量统计l
		String whereCondStr = " pk_handitem = '" + vos[0].getPk_handitem() + "'";
		List<HandItemVO> hivos = NCLocator.getInstance().lookup(IHanditemsService.class).queryHandItemsVOByCond(whereCondStr, null);
		if(hivos != null && hivos.size()==1){
			Integer type = hivos.get(0).getType();
			if(type==1){
				EntryapplyVO entryvo = (EntryapplyVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, EntryapplyVO.class, vos[0].getPk_bill());
				AggEntryapplyVO aggvo =new AggEntryapplyVO();
				aggvo.setParentVO(entryvo);
				WorkLoadCountUtil.count(aggvo, BusiActionConst.ENTRYITEMS, EntrymngConst.BillTYPE_ENTRY);
			}else{
				StapplyVO stapplyvo = (StapplyVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, StapplyVO.class, vos[0].getPk_bill());
				AggStapply aggvo =new AggStapply();
				aggvo.setParentVO(stapplyvo);
				WorkLoadCountUtil.count(aggvo, BusiActionConst.DIMISITEMS, TRNConst.BUSITYPE_DIMISSION);
			}
		}
		// 更新之后,需要检查是否都审核完成,如果都审核完成,需要将单据状态设置为待离职
		int count = NCLocator.getInstance().lookup(IPersistenceRetrieve.class).getCountByCondition("hi_handover", "ischeck='N' and  pk_bill = '" + vos[0].getPk_bill() + "'");
		if (count == 0) {
			NCLocator.getInstance().lookup(IPersistenceUpdate.class)
					.executeSQLs(new String[] { "update hi_stapply set workflow_state = 6 where pk_hi_stapply = '" + vos[0].getPk_bill() + "' and workflow_state <> 102" });
		}
	}

}
