package org.fouram.service;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.fouram.constants.WebConstants;
import org.fouram.constants.WebConstants.DelFlagEnum;
import org.fouram.core.base.model.PageData;
import org.fouram.core.base.service.BaseService;
import org.fouram.core.base.service.RequestService;
import org.fouram.core.plugin.weixin.cp.util.WXCpUserUtil;
import org.fouram.core.util.Base64Util;
import org.fouram.core.util.JSONUtil;
import org.fouram.core.util.JsonNodeUtil;
import org.fouram.core.util.Tools;
import org.fouram.entity.SapOrg;
import org.fouram.entity.SapUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Lists;

import me.chanjar.weixin.cp.bean.WxCpUser;

@Service
public class SapUserService extends BaseService {

	@Autowired
	private SapOrgService sapOrgService;
	@Autowired
	private RequestService requestService;
	@Autowired
	private SapEmpJobService sapEmpJobService;
	@Autowired
	private SapOprLogService sapOprLogService;
	@Autowired
	private SapPersonalService sapPersonalService;

	private static boolean isTestWXSync = true;
	private static boolean isTestMobile = false;

	public List<SapUser> getSapUsers() throws Exception {
		HttpHeaders headers = getHttpHeaders();
		String userUrl = "https://api15.sapsf.cn/odata/v2/User?$filter=status in 'active'&$format=json&$expand=personKeyNav";
		// get
		JsonNode node = requestService.getForObject(userUrl, headers);
		List<SapUser> sapUsers = Lists.newArrayList();
		if (node != null) {
			Iterator<JsonNode> iterator = node.get("d").get("results").elements();
			while (iterator.hasNext()) {
				JsonNode userNode = iterator.next();
				String userId = JsonNodeUtil.getValue(userNode, "userId");
				// 去除非员工账号和测试数据
				if (!userId.startsWith("Test")) {
					String username = JsonNodeUtil.getValue(userNode, "username");
					String name = JsonNodeUtil.getValue(userNode, "lastName")
							+ JsonNodeUtil.getValue(userNode, "firstName");
					String mobile = JsonNodeUtil.getValue(userNode, "cellPhone");
					String businessPhone = JsonNodeUtil.getValue(userNode, "businessPhone");
					String email = JsonNodeUtil.getValue(userNode, "email");
					String personId = JsonNodeUtil.getValue(userNode, "personKeyNav", "personIdExternal");
					// 手机号码脱敏
					if (isTestMobile) {
						if (StringUtils.isNotBlank(mobile) && mobile.length() == 11) {
							mobile = mobile.substring(0, 8) + "999";
						} else {
							mobile = "";
						}
					}
					SapUser sapUser = SapUser.builder().userId(userId).personId(personId).username(username).name(name)
							.mobile(mobile).formatMobile(mobile).businessPhone(businessPhone)
							.formatBusinessPhone(formatBusinessPhone(businessPhone)).email(email).formatEmail(email)
							.isPrimary(userId.equals(personId)).build();
					sapUsers.add(sapUser);
				}
			}
		}
		// 获取用户对应机构
		sapOrgService.setOrg(sapUsers);
		// 获取用户对应性别
		sapPersonalService.setGender(sapUsers);
		// 获取用户对应职务
		sapEmpJobService.setPosition(sapUsers);
		return sapUsers;
	}

	public void saveOneAndSyncWX(SapUser entity) throws Exception {
		entity.setCreateDate(new Date());
		entity.setDelFlag(DelFlagEnum.ENABLE);
		save("SapUserMapper.saveOne", entity);
		// 更新同步企业微信备注
		updateWXResult(entity.getPersonId());
	}

	public void updateEnable(String userId) throws Exception {
		SapUser entity = SapUser.builder().userId(userId).delFlag(DelFlagEnum.ENABLE).build();
		update("SapUserMapper.updateDelFlag", entity);
	}

	public void updateOneAndSyncWX(SapUser entity) throws Exception {
		entity.setDelFlag(DelFlagEnum.ENABLE);
		update("SapUserMapper.updateOne", entity);
		// 更新同步企业微信备注
		updateWXResult(entity.getPersonId());
	}

	public void updateWXResult(String personId) throws Exception {
		String result = createOrUpdateWXUser(personId);
		SapUser entity = SapUser.builder().personId(personId).result(result).build();
		update("SapUserMapper.updateResult", entity);
	}

	private String createOrUpdateWXUser(String personId) throws Exception {
		// 测试
		if (isTestWXSync) {
			return "TEST-" + WebConstants.SUCCESS;
		}
		List<SapUser> sapUsers = selectListByPersonId(personId);
		SapUser wxSapUser = sapUsers.get(0);
		Long[] firstOrgWxDepartIdList = new Long[sapUsers.size()];
		Long[] secondOrgWxDepartIdList = new Long[sapUsers.size()];
		Long[] thirdOrgWxDepartIdList = new Long[sapUsers.size()];
		Long[] fourthOrgWxDepartIdList = new Long[sapUsers.size()];
		for (int i = 0; i < sapUsers.size(); i++) {
			SapUser sapUser = sapUsers.get(i);
			String checkResult = checkSapUser(sapUser);
			if (StringUtils.isNotBlank(checkResult)) {
				return checkResult;
			}
			firstOrgWxDepartIdList[i] = sapUser.getFirstOrgWxDepartId();
			secondOrgWxDepartIdList[i] = sapUser.getSecondOrgWxDepartId();
			thirdOrgWxDepartIdList[i] = sapUser.getThirdOrgWxDepartId();
			fourthOrgWxDepartIdList[i] = sapUser.getFourthOrgWxDepartId();
		}
		return WXCpUserUtil.createOrUpdate(personId, wxSapUser.getName(), firstOrgWxDepartIdList,
				secondOrgWxDepartIdList, thirdOrgWxDepartIdList, fourthOrgWxDepartIdList, wxSapUser.getFormatPosition(),
				wxSapUser.getFormatMobile(), wxSapUser.getGender(), wxSapUser.getUsername(),
				wxSapUser.getFormatBusinessPhone(), wxSapUser.getFirstOrgName());
	}

	public String checkSapUser(SapUser sapUser) {
		if (Tools.isEmpty(sapUser.getPersonId())) {
			return "员工ID为空";
		} else if (Tools.isEmpty(sapUser.getFirstOrgName())) {
			return "一级组织为空";
		}
		if (WebConstants.INGORE_PERSONIDS.contains("," + sapUser.getPersonId() + ",")) {
			return "忽略数据（兼职用户）";
		}
		return null;
	}

	public SapUser selectByUserId(String userId) throws Exception {
		return (SapUser) findObject("SapUserMapper.selectByUserId", userId);
	}

	@SuppressWarnings("unchecked")
	public List<SapUser> selectListByPersonId(String personId) throws Exception {
		return (List<SapUser>) findList("SapUserMapper.selectListByPersonId", personId);
	}

	@SuppressWarnings("unchecked")
	public List<SapUser> selectUnSyncList() throws Exception {
		return (List<SapUser>) findList("SapUserMapper.selectUnSyncList", null);
	}

	@SuppressWarnings("unchecked")
	public List<SapUser> selectDeleteList() throws Exception {
		return (List<SapUser>) findList("SapUserMapper.selectDeleteList", null);
	}

	public void updateAllDelete() throws Exception {
		update("SapUserMapper.updateAllDelete", null);
	}

	public static void main(String[] args) {
		StringBuilder stringBuilder = new StringBuilder();
		String sapApiUser = "API01@cmccoltd:cmccoltd123";
		String authorizationStr = stringBuilder.append("Basic ").append(Base64Util.encodeString(sapApiUser)).toString();
		System.out.println(authorizationStr);
	}

	@SuppressWarnings("unchecked")
	public List<SapUser> selectListByName(String name) throws Exception {
		return (List<SapUser>) findList("SapUserMapper.selectListByName", name);
	}

	@SuppressWarnings("unchecked")
	public List<SapUser> selectSuccessList() throws Exception {
		return (List<SapUser>) findList("SapUserMapper.selectSuccessList", null);
	}

	@SuppressWarnings("unchecked")
	public List<SapUser> selectListByDepartIdAndLevel(String departId) throws Exception {
		SapOrg sapOrg = sapOrgService.selectById(departId);
		if (StringUtils.isBlank(departId) || WebConstants.TOP_DEPART.toString().equals(departId)) {
			departId = WebConstants.TOP_DEPART.toString();
			sapOrg = SapOrg.builder().id(WebConstants.TOP_DEPART.toString()).sapName(WebConstants.TOP_DEPART_NAME)
					.level("1").build();
		}
		PageData pd = new PageData();
		pd.put("departId", departId);
		pd.put("level", sapOrg.getLevel());
		return (List<SapUser>) findList("SapUserMapper.selectListByDepartIdAndLevel", pd);
	}

	public SapUser toInfoDetail(SapUser sapUser) throws Exception {
		if (sapUser != null) {
			List<SapUser> users = selectListByPersonId(sapUser.getPersonId());
			List<List<SapOrg>> departList = Lists.newArrayList();
			for (int i = 0; i < users.size(); i++) {
				SapUser user = users.get(i);
				List<SapOrg> orgs = Lists.newArrayList();
				if (Tools.notEmpty(user.getFirstOrgId())) {
					orgs.add(sapOrgService.selectById(user.getFirstOrgId()));
				}
				if (Tools.notEmpty(user.getSecondOrgId())) {
					orgs.add(sapOrgService.selectById(user.getSecondOrgId()));
				}
				if (Tools.notEmpty(user.getThirdOrgId())) {
					orgs.add(sapOrgService.selectById(user.getThirdOrgId()));
				}
				if (Tools.notEmpty(user.getFourthOrgId())) {
					orgs.add(sapOrgService.selectById(user.getFourthOrgId()));
				}
				departList.add(orgs);
			}
			sapUser.setDepartList(departList);
		}
		return sapUser;
	}

	public List<SapUser> toInfoDetails(List<SapUser> sapUsers) throws Exception {
		for (SapUser sapUser : sapUsers) {
			toInfoDetail(sapUser);
		}
		return sapUsers;
	}

	public SapUser getDetailById(String userId) throws Exception {
		SapUser sapUser = selectByUserId(userId);
		return toInfoDetail(sapUser);
	}

	public void updateAvatar(SapUser sapUser) throws Exception {
		update("SapUserMapper.updateAvatar", sapUser);
	}

	public void deleteByUserId(String userId) throws Exception {
		update("SapUserMapper.deleteByUserId", userId);
	}
	
	public void updateUnableByUserId(String userId) throws Exception {
		update("SapUserMapper.updateUnableByUserId", userId);
	}

	public void deleteQuitUserByUserId(String userId, String oprUserId) throws Exception {
		SapUser sapUser = selectByUserId(userId);
		String personId = sapUser.getPersonId();
		List<SapUser> sapUsers = selectListByPersonId(personId);
		for(SapUser user : sapUsers) {
			deleteByUserId(user.getUserId());
		}
		WXCpUserUtil.delete(personId);
		sapOprLogService.saveOne(JSONUtil.toString(sapUsers), WebConstants.OPRTYPE_DELETE, oprUserId);
	}
	
	public void updateUnableData() throws Exception {
		List<SapUser> users = selectSuccessList();
		for(SapUser user : users) {
			WxCpUser wxUser = WXCpUserUtil.getByIdOrEmail(user.getUserId(), null);
			if(wxUser == null) {
				System.out.println(user.getUserId());
				updateUnableByUserId(user.getUserId());
			}
		}
	}
}
