package com.wechat.service;

import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.wechat.common.CommonEnum.PREPARE_FLAG;
import com.wechat.common.CommonHelper;
import com.wechat.common.Constants;
import com.wechat.common.IdGenarator;
import com.wechat.common.utils.DateUtils;
import com.wechat.common.utils.LocalFileUtil;
import com.wechat.common.utils.MailUtil;
import com.wechat.common.utils.MessageUtils;
import com.wechat.common.utils.StringsUtils;
import com.wechat.dao.MdeWorkExperienceDao;
import com.wechat.global.CustomException;
import com.wechat.global.base.dao.RedisWithExpiryTimeDao;
import com.wechat.global.message.InfoMsg;
import com.wechat.model.dbEntity.MdeHotelBrand;
import com.wechat.model.dbEntity.MdePositionAnotherName;
import com.wechat.model.dbEntity.MdeTicketCategory;
import com.wechat.model.dbEntity.MdeTicketDetail;
import com.wechat.model.dbEntity.MdeUser;
import com.wechat.model.dbEntity.MdeWorkExperience;
import com.wechat.model.requestDto.LoginResp;
import com.wechat.model.requestDto.RegisterResp;
import com.wechat.model.responseDto.ResultEntity;

@Service
public class RegisterService {

	@Value("#{configProperties['upload.base.path']}")
	private String basePackagePath;

	@Value("#{configProperties['upload.path.image']}")
	private String basePackagePathImage;

	@Value("#{configProperties['compress.image.size']}")
	private int compressImageSize;
	// 域名
	@Value("#{configProperties['url.base']}")
	private String domain;
	// 域名
	@Value("#{configProperties['enterprise.register.activeUrl']}")
	private String activeUrl;

	@Autowired
	private MdeWorkExperienceService mdeWorkExperienceService;

	@Autowired
	private MdeHotelBrandService mdeHotelBrandService;

	@Autowired
	MdePositionAnotherNameService mdePositionAnotherNameService;

	@Resource
	private CommonService commonService;

	@Resource
	private MdeUserService mdeUserService;
	
	@Resource
	private WeiXinService wxService;

	// 静默授权
	@Resource
	private AuthorizedService auzService;
	@Resource
	private RedisWithExpiryTimeDao redisDao;
	@Autowired
	private MdeWorkExperienceDao mdeWorkExperienceDao;

	@Autowired
	private CommonHelper commonHelper;
	@Resource
	private MdeTicketCategoryService ticketCategoryService;
	@Resource
	private MdeTicketDetailService ticketDetailService;
	@Autowired
	private MailUtil mailUtil;

	private Logger log = LoggerFactory.getLogger(getClass());

	
	private void getTickets(String userCode, String userName, String identityFlag) {
		// 关联用户注册前领取的优惠券
		ticketDetailService.updateByUserName(userName,userCode);
		
		List<MdeTicketCategory> list = ticketCategoryService.accquireLoginTicket(identityFlag);
		for(MdeTicketCategory ca:list) {
			if(Integer.valueOf(ca.getLeftNum())<=0) {
				continue;
			}
			MdeTicketDetail detail = new MdeTicketDetail();
			detail.setTdCode(Long.toHexString(new Date().getTime())+StringsUtils.getRandomString(4));// 券code（13位时间戳装16进制+4位随机字符）
			detail.setTcCode(ca.getTcCode());// 券类别code(uuid)
			detail.setUserCode(Long.valueOf(userCode));// 当前绑定用户code
			detail.setShareBy(null);// 分享来源
			detail.setIdentityFlag(ca.getIdentityFlag());// 可使用身份标识[0-个人；1-企业]
			detail.setShareFlag(ca.getShareFlag());// 可分享标识[0-不可分享；1-可分享]
			detail.setAvailableFrom(ca.getAvailableFrom());// 使用时间from
			detail.setAvailableTo(ca.getAvailableTo());// 使用时间to
			detail.setUsedFlag("1");
			detail.setCreateBy(userCode);
			detail.setUpdateBy(userCode);
			detail.setVersionNo(1);
			detail.setDelFlag(0);
			ticketDetailService.insertTicket(detail);
			if(Integer.valueOf(ca.getIssuedNum())>0) {
				ticketCategoryService.reduceLeftNum(ca.getTcCode());
			}
		}
	}
	public String trimString(String s) {
		if(StringsUtils.isNotEmpty(s)) {
			return s.trim();
		}
		return s;
	}
	private String getUserHeadPortrait(String userCode, Date time) {
		String timeStr = DateUtils.formatString(time, "yyyy-MM-dd HH:mm:ss");
		try {
			time = DateUtils.stringToDate(timeStr, "yyyy-MM-dd HH:mm:ss");
			String fileName = time.getTime() + "_" + userCode + ".jpg";
			return LocalFileUtil.transferDefaultImageToDest(basePackagePath, basePackagePathImage, fileName);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 企业注册成功发送激活邮件
	 * 
	 * @param userInfo
	 * @param request
	 * @return
	 */
	private ResultEntity<String> sendActivationEmail(MdeUser userInfo, HttpServletRequest request) {
		try {
			String activationToken = commonHelper.getActivationToken(String.valueOf(userInfo.getUserCode()));
			redisDao.insert(activationToken, String.valueOf(userInfo.getUserCode()), 5 * 24 * 3600);
			String lang = commonService.getLanguage(request);
			// 发送邮件
			InputStream in = null;
			if (lang.equalsIgnoreCase("en")) {
				in = this.getClass().getClassLoader().getResourceAsStream("template/mdeMailActivate_en.html");
			} else {
				in = this.getClass().getClassLoader().getResourceAsStream("template/mdeMailActivate_cn.html");
			}

			byte[] bytes = new byte[in.available()];
			in.read(bytes);
			String htmlStr = new String(bytes);
			// 连接
			String link = MessageUtils.getText(activeUrl, domain) + "?userCode=" + userInfo.getUserCode()
					+ "&activationToken=" + activationToken;
			//长链转短链
			/*
			 * String shortUrl = wxService.getShortUrl(link);
			 * if(!StringsUtils.isEmpty(shortUrl)) { link = shortUrl; }
			 */

			MailUtil.setDomain(MessageUtils.getText(activeUrl, domain)); // 发邮件之前先 设置链接中的域名

			htmlStr = htmlStr.replace("{0}", link);// 激活连接
			htmlStr = htmlStr.replace("{1}", userInfo.getEntContacts());// 称谓
			htmlStr = htmlStr.replace("{2}", userInfo.getName());// 公司名称
			if (lang.equalsIgnoreCase("en")) {
				htmlStr = htmlStr.replace("{3}", "to be activated"); // 状态描述
				htmlStr = htmlStr.replace("{4}","Please click on the \"Activate\"button below to activate your email.");// 附加信息说明
				htmlStr = htmlStr.replace("{5}", "COMPANY INFORMATION TO BE ACTIVATED");// 标题
				htmlStr = htmlStr.replace("{6}", "This link is valid for 5 days.");// 连接有效期
			} else {
				htmlStr = htmlStr.replace("{3}", "待激活"); // 状态描述
				htmlStr = htmlStr.replace("{4}", "请点击下面的“立即激活”按钮，激活邮箱。");// 附加信息说明
				htmlStr = htmlStr.replace("{5}", "您提交的公司信息审核待激活");// 标题
				htmlStr = htmlStr.replace("{6}", "该链接五天内有效。");// 连接有效期
			}

			String mailContent = htmlStr; // MessageUtils.getText(htmlStr,link, userInfo.getName(), companyName,
											// checkStatusName,addMessage);
			if (mailUtil.sendMailNew(userInfo.getUserName(), mailContent, "门墩儿企业注册认证")) {
				return new ResultEntity<>(InfoMsg.SUCCESS_REQUEST, "请激活");
			}else {
				log.error("企业用户注册，邮件发送失败，邮件地址：["+ userInfo.getUserName()+"]");
				return new ResultEntity<>(InfoMsg.ERROR_SEND_EMAIL_FAIL);
			}
			
		} catch (Exception e) {
			log.error("企业用户注册，邮件发送异常",e);
			throw new CustomException(InfoMsg.ERROR_SEND_EMAIL_FAIL);
		}
	}

	/**
	 * 工作简历提交
	 * 
	 * @param mdeWorkExperiences
	 * @return
	 * @throws Exception
	 * @author jadyn.wu
	 */
	@Transactional
	public ResultEntity<String> expericnceSubmit(List<MdeWorkExperience> mdeWorkExperiences, String userCode, HttpServletRequest req) throws Exception {
		if (CollectionUtils.isEmpty(mdeWorkExperiences)) {
			return new ResultEntity<>(InfoMsg.ERROR_NULL_PARAM);
		}
		//保存工作简历
		ResultEntity<String> resultEntity = inserWorkExperience(mdeWorkExperiences, userCode,req);
		if (!resultEntity.getCode().equals("0")) {
			throw new RuntimeException("保存工作简历失败");
		}
		
		//修改显示title
		int updNu = mdeWorkExperienceDao.setLatestWEShow(userCode);
		if (updNu != 1)
		{
			//只有RuntimeException事务才会回滚
			throw new RuntimeException("修改显示title失败");
		}

		return new ResultEntity<>(InfoMsg.SUCCESS_REQUEST);
	}

	/**
	 * 新增工作履历
	 * 
	 * @param list
	 */
	@Transactional
	public ResultEntity<String> inserWorkExperience(List<MdeWorkExperience> mdeWorkExperiences,String userCode,
			HttpServletRequest req) {
		try {
			for (int i = 0; i < mdeWorkExperiences.size(); i++) {
				MdeWorkExperience mdeWorkExperience = mdeWorkExperiences.get(i);
				if (StringsUtils.isEmpty(mdeWorkExperience.getCoId())
						&& StringsUtils.isEmpty(mdeWorkExperience.getCoName())) {
					return new ResultEntity<>(InfoMsg.ERROR_NULL_PARAM);
				}
				mdeWorkExperience.setShowFlag("1");
				mdeWorkExperience.setUserCode(userCode + "");
				mdeWorkExperience.setOnJob("0");
				String language = commonService.getLanguage(req);
				String enFlag = Constants.LANG_CN.equalsIgnoreCase(language) ? "1" : "2";
				mdeWorkExperience.setEnFlag(enFlag);
				mdeWorkExperience.setVersionNo(1);
				mdeWorkExperience.setDelFlag(0);
				if (StringsUtils.isEmpty(mdeWorkExperience.getCoId())) {
					mdeWorkExperience.setCoId(null);
				}
				mdeWorkExperienceService.insert(mdeWorkExperience);
			}
		} catch (Exception e) {
			log.error("工作履历保存异常",e);
			return new ResultEntity<>(InfoMsg.ERROR_INSERT_ERROR);
		}
		return new ResultEntity<>(InfoMsg.SUCCESS_REQUEST);
	}

	/**
	 * 企业执照上传  在职证明上传
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public ResultEntity<String> upload(MultipartFile picture, String childPath) throws Exception {
		try {
//			String imageUrl = LocalFileUtil.transferHeadProtrait(picture, basePackagePath, basePackagePathImage,
//					compressImageSize);
			String imageUrl = LocalFileUtil.uploadFileWithoutLimit(picture, basePackagePath, basePackagePathImage+childPath);
			return new ResultEntity<String>(InfoMsg.SUCCESS_REQUEST, imageUrl);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ResultEntity<String>(InfoMsg.ERROR_UPLOAD_FIELD);
	}


	/**
	 * 获取酒店品牌 区分国际
	 * 
	 * @param international
	 * @return
	 */
	public List<MdeHotelBrand> getHotelBrandList(String international, String lang) {
		// 国际区分[1-国际;2-国内]
		Map<String, String> map = new HashMap<String, String>();
		map.put("international", international);
		map.put("lang", lang);
		List<MdeHotelBrand> hotelBrandList = mdeHotelBrandService.getHotelByInternational(map);
		return hotelBrandList;
	}

	/**
	 * 获取所有职位
	 * 
	 * @return
	 */
	public ResultEntity<List<MdePositionAnotherName>> getAllPositionAnotherName() {
		try {
			List<MdePositionAnotherName> hotelBrandList = mdePositionAnotherNameService.getAllPositionAnotherName();
			return new ResultEntity<List<MdePositionAnotherName>>(InfoMsg.SUCCESS_REQUEST, hotelBrandList);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ResultEntity<List<MdePositionAnotherName>>(InfoMsg.ERROR_QUERY_FAIL);
	}

	/**
	 * 验证工作履历参数是否合法
	 * 
	 * @param mdeWorkExperiences
	 * @return
	 */
	public boolean validated(List<MdeWorkExperience> mdeWorkExperiences) {
		boolean flag = true;
		if (CollectionUtils.isEmpty(mdeWorkExperiences)) {
			return false;
		}
		for (MdeWorkExperience mdeWorkExperience : mdeWorkExperiences) {
			if (StringsUtils.isEmpty(mdeWorkExperience.getPositionTitle())
					|| (mdeWorkExperience.getEnterDate() == null)
					|| (StringsUtils.isEmpty(mdeWorkExperience.getCoId()) && StringsUtils.isEmpty(mdeWorkExperience.getCoName()))) {
				flag = false;
				break;
			}
		}
		return flag;
	}

	/**
	 * 邮箱验证
	 * 
	 * @param userName
	 * @return
	 */
	public boolean checkPostBox(String userName) {
		boolean flag = false;
		try {
			String check = "^(\\w-*\\.*)+@(\\w-?)+(\\.\\w{2,})+$";
			Pattern regex = Pattern.compile(check);
			Matcher matcher = regex.matcher(userName);
			flag = matcher.matches();
		} catch (Exception e) {
			log.info(e.getMessage());
			return flag;
		}
		return flag;
	}

	/**
	 * 手机号验证
	 * 
	 * @param userName
	 * @return
	 */
	public boolean checkPhone(String userName) {
		boolean flag = false;
		try {
			Pattern regex = Pattern.compile("^1[23456789]\\d{9}$");
			Matcher matcher = regex.matcher(userName);
			flag = matcher.matches();
		} catch (Exception e) {
			log.info(e.getMessage());
		}
		return flag;
	}

	/**
	 * 国际手机号验证
	 * 
	 * @param phone
	 * @param phoneCodeSplit
	 * @return
	 */
	public boolean internationalPhoneCheck(String phone, String[] phoneCodeSplit) {
		try {
			if (phoneCodeSplit[0].equals("86")) {
				// 中国大陆 （手机号）
				Pattern regex = Pattern.compile("^1[23456789]\\d{9}$");
				Matcher matcher = regex.matcher(phone);
				return matcher.matches();
			} 
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}
	
	/**
	 * 个人注册
	 * 
	 * @param request
	 * 
	 */
	@Transactional
	public ResultEntity<String> personalRegister(RegisterResp jo, MdeUser userInfo, HttpServletResponse resp, HttpServletRequest request) {

		// 身份标识[0-个人；1-企业]
		String identityFlag = jo.getIdentityFlag();
		// 登录名[手机号-个人/邮箱-企业]
		String userName = jo.getUserName();
		// 国家电话区号（列 +86）
		String phoneCode = jo.getPhoneCode();
		// 短信验证码
		String phoneCheckCode = jo.getPhoneCheckCode();
		// 国际区分[1-国际;2-国内;9-未知]
		String international = jo.getInternational();
		userInfo.setInternational(international);
		// 从业酒店品牌code（酒店品牌信息表）
		String hotelBrand = jo.getHotelBrand();
		// 邮箱地址（个人）
		String email = jo.getEmail();	
		// 参加工作时间（个人）
		Date firstWork = jo.getFirstWork();
		// 从业酒店品牌名称（品牌信息表中不存在的情况下，用户自由填写）
		String hotelBrandStr = jo.getHotelBrandStr();

		// 验证信息完整
		if (StringUtils.isEmpty(international)
				|| (StringUtils.isEmpty(hotelBrand) && StringUtils.isEmpty(hotelBrandStr))
				|| StringUtils.isEmpty(phoneCode) || firstWork == null || StringUtils.isEmpty(email)) {
			log.error("[个人注册出现空数据]international:"+hotelBrand+"--hotelBrand:"+userName+"--hotelBrandStr:"+hotelBrandStr+"--phoneCode:"+phoneCode+"--firstWork:"+firstWork+"--email:"+email);
			return new ResultEntity<String>(InfoMsg.ERROR_INCOMPLETE_INFORMATION);
		} else {
			//个人用户不需要审核
			userInfo.setCheckStatus("2");

			if (StringsUtils.isNotEmpty(hotelBrand)) {
				userInfo.setHotelBrand(hotelBrand);
			}
			if (StringsUtils.isNotEmpty(hotelBrandStr)) {
				userInfo.setHotelBrandStr(hotelBrandStr);
			}

			//设置第一份工作时间
			userInfo.setFirstWork(firstWork);
			//设置用户联系邮箱
			userInfo.setEmail(email);
			//工作状态默认为 在职-有好的工作可考虑
			userInfo.setWorkStatus(2);
		}

		// 注册成功
		try {
			Date now = new Date();
			userInfo.setCreateDate(now);
			userInfo.setUpdateDate(now);
			//用户code采番
			String userCode = String.valueOf(IdGenarator.nextId());
			userInfo.setUserCode(userCode);
			String pre = now.getTime() + "_" + userCode;
			//上传用户头像并压缩
			String headPortrait = LocalFileUtil.transferHeadProtraitForBase64(jo.getHeadPortrait(), basePackagePath, basePackagePathImage,pre);
			userInfo.setHeadPortrait(headPortrait);
			//用户表存储
			mdeUserService.insertUserInfo(userInfo);

			//注册成功之后领取优惠券
			getTickets(userCode,userInfo.getUserName(),identityFlag);
			
			// 设置cookies
			commonService.setLoginCookies(resp,userCode,identityFlag,userInfo.getCreateDate());
            
            return new ResultEntity<>(InfoMsg.SUCCESS_REQUEST);

		} catch (Exception e) {
			log.error("个人用户注册异常",e);
			throw new CustomException(InfoMsg.ERROR_INSERT_ERROR);
		}
	}
	
	/**
	 * 企业注册
	 * 
	 * @param request
	 * 
	 */
	@Transactional
	public ResultEntity<String> companyRegister(RegisterResp jo, MdeUser userInfo, HttpServletResponse resp, HttpServletRequest request) {
		// 身份标识[0-个人；1-企业]
		String identityFlag = jo.getIdentityFlag();
		// 登录名[手机号-个人/邮箱-企业]
		String userName = jo.getUserName();
		// 企业执照
		String image = jo.getImage();
		// 在职证明
		String onJobImage = jo.getOnJobImage();
		// 企业联系人
		String entContacts = jo.getEntContacts();
		// 企业联系人联系方式
		String entPhone = jo.getEntPhone();
		// 筹开标识
		String prepareFlag = jo.getPrepareFlag();
		// 筹开年份
		String prepareYear = jo.getPrepareYear();
		// 筹开季度
		String prepareQuarter = jo.getPrepareQuarter();
		

		if (StringsUtils.isEmpty(image) || StringsUtils.isEmpty(entContacts) || StringsUtils.isEmpty(entPhone)
				|| StringsUtils.isEmpty(onJobImage)) {
			log.error("[企业注册出现空数据]image:"+image+"--entContacts:"+entContacts+"--entPhone:"+entPhone+"--onJobImage:"+onJobImage);
			return new ResultEntity<String>(InfoMsg.ERROR_INCOMPLETE_INFORMATION);
		} else {
			// 验证联系电话是否合法
			if (!checkPhone(entPhone)) {
				return new ResultEntity<>(InfoMsg.ERROR_PHONE_ERROR);
			}
			// 企业用户 验证邮箱是否合法
			if (!checkPostBox(userName)) {
				return new ResultEntity<>(InfoMsg.ERROR_EMAIL_CHECK);
			}
			
			userInfo.setPhoneCode("86");
			userInfo.setCheckStatus("4"); // 未激活
			userInfo.setImage(image);
			userInfo.setOnJobImage(onJobImage);
			userInfo.setEntContacts(entContacts);
			userInfo.setEntPhone(entPhone);
			userInfo.setInternational("9");// 企业注册默认值
			userInfo.setWorkStatus(2);
			userInfo.setPrepareFlag(prepareFlag);
			
			if(PREPARE_FLAG.OPERATING.getValue().equals(prepareFlag))
			{
				//筹开酒店的情况 记录筹开相关信息
				userInfo.setPrepareYear(prepareYear);
				userInfo.setPrepareQuarter(prepareQuarter);
			}
		}

		// 注册成功
		try {
			Date now = new Date();
			userInfo.setCreateDate(now);
			userInfo.setUpdateDate(now);
			//用户code采番
			String userCode = String.valueOf(IdGenarator.nextId());
			userInfo.setUserCode(userCode);
			String pre = now.getTime() + "_" + userCode;
			//上传用户头像并压缩
			String headPortrait = LocalFileUtil.transferHeadProtraitForBase64(jo.getHeadPortrait(), basePackagePath, basePackagePathImage,pre);
			userInfo.setHeadPortrait(headPortrait);
			//用户表存储
			mdeUserService.insertUserInfo(userInfo);
			
			//注册成功之后领取优惠券
			getTickets(userInfo.getUserCode(),userInfo.getUserName(),identityFlag);

			// 企业注册成功发送激活邮件
			return sendActivationEmail(userInfo, request);
			
		} catch (Exception e) {
			log.error("企业用户注册异常",e);
			throw new CustomException(InfoMsg.ERROR_INSERT_ERROR);
		}
	}
	
	/**
	 * 第三方注册
	 * 
	 * @param request
	 * 
	 */
	public MdeUser theThirdRegister(RegisterResp jo, MdeUser userInfo) {
		// 第三方注册（0 微信/1 领英）
		String type = jo.getType();
		if (StringsUtils.isNotEmpty(type)) {
			LoginResp loginResp = jo.getResult();
			if (loginResp == null) {
				throw new CustomException(InfoMsg.ERROR_PARAMS_ERROR);
			}
			if (StringsUtils.isEqual(type, "0")) {
				userInfo.setOpenId(StringsUtils.isEmpty(loginResp.getOpenId()) ? "" : loginResp.getOpenId());
				userInfo.setUnionId(loginResp.getUnionId());
				// userInfo.setAddrCountry(loginResp.getCountry());
				// userInfo.setAddrProvince(loginResp.getProvince());
				// userInfo.setAddrCity(loginResp.getCity());
				// userInfo.setHeadPortrait(loginResp.getHeadPortrait());
			} else if (StringsUtils.isEqual(type, "1")) {
				userInfo.setLinkedinId(loginResp.getLinkedInId());
			}
		}
		return userInfo;
	}

}
