package com.wechat.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.wechat.common.Constants;
import com.wechat.common.utils.DateUtils;
import com.wechat.common.utils.MessageUtils;
import com.wechat.common.utils.StringsUtils;
import com.wechat.dao.MdeInterviewDao;
import com.wechat.dao.MdeIntvContactsMapper;
import com.wechat.dao.MdeIntvTimeDao;
import com.wechat.dao.MdeJobAdvertisedDao;
import com.wechat.dao.MdeUserDao;
import com.wechat.dao.MdeVideoUseHisMapper;
import com.wechat.global.CustomException;
import com.wechat.global.base.BaseService;
import com.wechat.global.message.InfoMsg;
import com.wechat.model.dbEntity.MdeInterview;
import com.wechat.model.dbEntity.MdeIntvContacts;
import com.wechat.model.dbEntity.MdeIntvTime;
import com.wechat.model.dbEntity.MdeJobAdvertised;
import com.wechat.model.dbEntity.MdeUser;
import com.wechat.model.dbEntity.MdeVideoUseHis;
import com.wechat.model.dto.InterviewDetailDto;
import com.wechat.model.dto.IntvContactsDto;
import com.wechat.model.dto.IntvTimeDto;
import com.wechat.model.dto.WxMiniTMsgMpDto;
import com.wechat.model.dto.WxMiniTMsgProgramDto;
import com.wechat.model.dto.WxMiniTMsgSendDto;
import com.wechat.model.requestDto.InterviewConfirmReq;
import com.wechat.model.requestDto.InterviewCreateReq;
import com.wechat.model.requestDto.InterviewHisReq;
import com.wechat.model.requestDto.InterviewRefuseReq;
import com.wechat.model.requestDto.InterviewUpdateReq;
import com.wechat.model.requestDto.TMsg3ParamsDto;
import com.wechat.model.requestDto.TMsg4ParamsDto;
import com.wechat.model.requestDto.TMsg5ParamsDto;
import com.wechat.model.requestDto.TMsgValueReq;
import com.wechat.model.requestDto.UpdUserCvReq;


/**
* @author jadyn
* @version 创建时间：2020年6月28日 下午4:43:49
*  类说明
*/
@Service
@Transactional
public class InterviewService extends BaseService{
	
	@Autowired
	private MdeInterviewDao interviewDao;

	@Autowired
	private MdeIntvTimeDao intvTimeDao;
	
	@Autowired
	private MdeUserDao mdeUserDao;
	
	@Autowired
	private MdeIntvContactsMapper intvContactsDao;
	
	@Autowired
	private EnterpriseService enterpriseService;
	
	@Autowired
	private MdeVideoUseHisMapper videoUseHis;
	
	@Autowired
	private MdeJobAdvertisedDao mdeJobAdvertisedDao;

	@Autowired
	private WeiXinProgService wxMinService;
	
    @Autowired
    private VerificationCodeService verificationCodeService;
    
    @Autowired
    private CommonService comService;
    
    // 邀请面试 推送模板Id
	@Value("#{configProperties['interview_invitation_template_id']}")
	private String interviewInvitationTemplateId; 
	
    // 邀请面试 跳转地址
	@Value("#{configProperties['interview_invitation_url']}")
	private String interviewInvitationUrl; 
	
    // 邀请面试 跳转地址-小程序
	@Value("#{configProperties['interview.invitation.minp.url']}")
	private String intvInvitationMinpUrl; 
	
    // 修改面试时间 推送模板Id
	@Value("#{configProperties['interview.change.time.template.id']}")
	private String intvChangeTimeTemplateId; 
	
    // 修改面试时间 跳转地址-小程序
	@Value("#{configProperties['interview.change.time.minp.url']}")
	private String intvChangeTimeMinpUrl;

    // 确认面试时间 推送模板Id
	@Value("#{configProperties['interview.confirm.time.template.id']}")
	private String intvConfirmTimeTemplateId; 
	
    // 确认面试时间 跳转地址-小程序
	@Value("#{configProperties['interview.confirm.time.minp.url']}")
	private String intvConfirmTimeMinpUrl;
	
    // 拒绝面试 推送模板Id
	@Value("#{configProperties['interview.refuse.time.template.id']}")
	private String intvRefuseTimeTemplateId; 
	
    // 拒绝面试 跳转地址-小程序
	@Value("#{configProperties['interview.refuse.time.minp.url']}")
	private String intvRefuseTimeMinpUrl;
	
	//公众号appid
	@Value("#{configProperties['weixin.appid']}")
	private String wxAppid; 
	
	// 视频小程序-用户唯一凭证
	@Value("#{configProperties['wx.miniprog.video.appid']}")
	private String videoAppId;
	
	// 视频小程序-跳转小程序类型：developer为开发版；trial为体验版；formal为正式版；默认为正式版
	@Value("#{configProperties['wx.miniprog.video.state']}")
	private String videoMpState;
	
	// 视频小程序-主页链接
	@Value("#{configProperties['wx.miniprog.video.tmsg.invite.url']}")
	private String videoTmsgInviteUrl;
	
	// 预约时间修改通知-短信
	@Value("#{configProperties['sms.intv.time.upd']}")
	private int smsIntvTimeUpd;
	// 预约时间确认通知-短信
	@Value("#{configProperties['sms.intv.time.ok']}")
	private int smsIntvTimeOk;
	// 拒绝面试-短信
	@Value("#{configProperties['sms.intv.refuse']}")
	private int smsIntvRefuse;
	
	/**
	 * 创建面试邀请
	 * @return
	 */
	public int createIntv(HttpServletRequest request,InterviewCreateReq intvReq, String publisher){
		int count = 0;
		//验证地址数据
		intvReq.cleanAddr();
		//将entity和入参相同属性复制至entity中
		MdeInterview intvEntity = new MdeInterview();
		BeanUtils.copyProperties(intvReq, intvEntity);
		//面试邀请参数赋值
		intvEntity.preInsert(publisher);
		intvEntity.setPublisher(publisher);
		//默认状态 1：待求职者确认
		intvEntity.setStatus("1");
		//主表数据插入
		count = interviewDao.insert(intvEntity);
		
		if(count > 0)
		{
			List<IntvTimeDto> intvTimeList = intvReq.getIntvTimeList();
			//附表插入
			int dtlNum = saveIntvTimes(intvTimeList, intvEntity.getIntvId(),publisher,intvEntity.getInterviewee());
			if(dtlNum != intvTimeList.size())
			{
				log.error("*******************面试邀请时间数据存储异常*******************");
				count = 0;
			}
		}
		
    	//更新投递信息状态
		UpdUserCvReq updCvReq = new UpdUserCvReq();
		updCvReq.setJobId(intvReq.getJobId().toString());
		updCvReq.setUserCode(intvReq.getInterviewee());
		// 简历状态 （0-新投递；1-已查看；2-已下载；3-邀请面试；4-录取；5-淘汰；6-储备）
		updCvReq.setType("3");
		enterpriseService.updateUserCvStatus(request, updCvReq,intvReq);
		
		//信息推送
		intvReq.setIntvId(intvEntity.getIntvId());
		sendIntvMsg(publisher, intvReq);
		
		
		return count;
	}

	
	/**
	 *  保存面试预约时间
	 * @return
	 */
	public int saveIntvTimes(List<IntvTimeDto> intvTimeList, Integer intvId, String updateUser, String confirmedBy){
		int count = 0;
		
		for(IntvTimeDto timeDto: intvTimeList)
		{
			//将entity和入参相同属性复制至entity中
			MdeIntvTime entity = new MdeIntvTime();
			BeanUtils.copyProperties(timeDto, entity);
			//面试邀请参数赋值
			entity.preInsert(updateUser);
			//面试邀请时间参数赋值
			entity.setIntvTimeId(null);
			entity.setIntvId(intvId);
			entity.setConfirmedBy(confirmedBy);
			//状态[0-待确认；1-已作废]
			entity.setStatus("0");
			//数据插入
			count = count + intvTimeDao.insert(entity);
		}

		return count;
	}
	
	/**
	 *  保存面试联系人信息
	 * @return
	 */
	public int updateContacts(MdeIntvContacts reqEntity, String userCode){
		int count = 0;
		
		//默认标识[0-非默认；1-默认]											
		if("1".equals(reqEntity.getDefaultFlg()))
		{
			//修改默认地址的时候，先将所有地址重置为非默认
			MdeIntvContacts ent = new MdeIntvContacts();
			ent.preUpdate(userCode);
			ent.setUserCode(userCode);
			intvContactsDao.updateNondefault(ent);
		}
		
		reqEntity.setUserCode(userCode);
		if(reqEntity.getContId() == null || reqEntity.getContId()== 0){
			reqEntity.preInsert(userCode);
			//id为空时是新增
			count= intvContactsDao.insert(reqEntity);
		} else {
			//id不为空时是修改
			reqEntity.preUpdate(userCode);
			count= intvContactsDao.update(reqEntity);
		}

		return count;
	}
	
	
	/**
	 * 获取邀请面试详细信息
	 * @param userCode 
	 * @return
	 */
	public InterviewDetailDto getIntvDetail(String publisher, String interviewee, String intvid) {
		Map<String,String> map = new HashMap<String, String>();
		map.put("publisher", publisher);
		map.put("interviewee", interviewee);
		map.put("intvId", intvid);
    	//获取面试邀请详情
		InterviewDetailDto intDtl = interviewDao.getIntvDetail(map);

		return intDtl;
	}
	
	
	/**
	 * 删除联系人
	 * @param userCode 
	 * @return
	 */
	public int delContact(Integer contId,String userCode) {
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("contId", contId);
		map.put("userCode", userCode);
    	//删除联系人
		int count = intvContactsDao.delContact(map);

		return count;
	}
	
	
	/**
	 *  获取面试联系人信息
	 * @return
	 */
	public List<IntvContactsDto> getContacts(String userCode){
		List<IntvContactsDto> list = intvContactsDao.getContacts(userCode);
		return list;
	}
	
	
	/**
	 *  修改面试预约时间
	 * @return
	 */
	public void updateIntvTimes(InterviewUpdateReq intvUpdReq, String updateUser, String identityFlag){

    	String confirmedBy = null;
    	if(Constants.IDENTITY_P.equals(identityFlag))
    	{
    		//个人用户修改-待企业确认
    		confirmedBy = intvUpdReq.getPublisher();
    		intvUpdReq.setStatus("2");
    		intvUpdReq.setInterviewee(updateUser);
    	} else {
    		//企业用户修改-待个人确认
    		confirmedBy = intvUpdReq.getInterviewee();
    		intvUpdReq.setStatus("1");
    		intvUpdReq.setPublisher(updateUser);
    	}
    	
    	//获取邀请id
    	Integer intvId = intvUpdReq.getIntvId();
		//原有的面试时间作废
		int count = cancelIntvTime(intvId,updateUser,updateUser);
		if(count > 0) {
			//新时间插入
			count = saveIntvTimes(intvUpdReq.getIntvTimeList(),intvId,updateUser,confirmedBy);
		} 
		if(count > 0) {
			//修改主表状态
			MdeInterview entity = new MdeInterview();
			entity.setInterviewee(intvUpdReq.getInterviewee());
			entity.setPublisher(intvUpdReq.getPublisher());
			entity.preUpdate(updateUser);
			entity.setIntvId(intvId);
			entity.setStatus(intvUpdReq.getStatus());
			count = interviewDao.updateIntvStatus(entity);
		}

		if(count < 1) {
    		throw new CustomException(InfoMsg.ERROR_DATA_UPDATE);
    	}
	}
	
	
	/**
	 *  作废面试预约时间
	 * @return
	 */
	public int cancelIntvTime(Integer intvId, String confirmedBy, String updateUser){
		//原有的面试时间作废
		MdeIntvTime entity = new MdeIntvTime();
		entity.setConfirmedBy(confirmedBy);
		entity.preUpdate(updateUser);
		entity.setIntvId(intvId);
		return intvTimeDao.cancelIntvTime(entity);
	}
	
	
	/**
	 *  确认面试预约时间
	 * @return
	 */
	public void confirmIntvTime(InterviewConfirmReq confirmReq, String confirmedBy){
		//原有的面试时间作废
		int count = cancelIntvTime(confirmReq.getIntvId(),confirmedBy,confirmedBy);
		if(count > 0) {
			//将entity和入参相同属性复制至entity中
			MdeInterview entity = new MdeInterview();
			BeanUtils.copyProperties(confirmReq, entity);
			entity.preUpdate(confirmedBy);
			//状态[1-待求职者确认；2-待企业确认；3-等待面试；4-已拒绝；5-面试结束]
			entity.setStatus("3");
			//生成roomid
			entity.setRoomId(getRoomId(entity.getIntvTime(),entity.getIntvId()));
			count = interviewDao.confirmIntvTime(entity);
		}
		if(count < 1) {
			log.error("*********越权修改面试预约时间 IntvId:【"+confirmReq.getIntvId()+"】 修改者：【"+confirmedBy+"】*************");
    		throw new CustomException(InfoMsg.ERROR_DATA_UPDATE);
    	}
	}
	
	
	/**
	 *  拒绝面试
	 * @return
	 */
	public int refuseIntv(InterviewRefuseReq refuseReq, String userCode){
		//原有的面试时间作废
		cancelIntvTime(refuseReq.getIntvId(),userCode,"");
		//初始化entity
		MdeInterview entity = new MdeInterview();
		entity.preUpdate(userCode);
		entity.setIntvId(refuseReq.getIntvId());
		entity.setInterviewee(userCode);
		//状态[1-待求职者确认；2-待企业确认；3-等待面试；4-已拒绝；5-面试结束]
		entity.setStatus("4");
		//拒绝理由
		entity.setRemarks(refuseReq.getRefuseReason());
		int count = interviewDao.updateIntvStatus(entity);
		return count;
	}
	
	
	
	/**
	 * 根据用户code和roomid获取待面试的面试邀请信息
	 */
	public MdeInterview getIntvInfoByKey(String roomId, String userCode, String identityFlg) {
		MdeInterview intv = new MdeInterview();
		intv.setRoomId(roomId);
		
		//根据用户身份进行区分验证
		switch (identityFlg) {
			case Constants.IDENTITY_P:
				//个人用户的情况下
				intv.setInterviewee(userCode);
				break;
			case Constants.IDENTITY_C:
				//企业用户的情况下
				intv.setPublisher(userCode);
				break;
		}

		MdeInterview result = interviewDao.getIntvByRoomId(intv);
		
		return result;
	}
	
	/**
	 *  生成 ROOM_ID
	 *  面试时间的时间戳4-8位（5）+面试信息ID后2位（0补足）+2位随机
	 * @return
	 */
	public String getRoomId(Date intvTime, Integer intvId){
		String roomId = String.valueOf(intvTime.getTime()).substring(3, 8);
		roomId = roomId + StringsUtils.addPreZeroE(intvId.toString(),2) + StringsUtils.getRandomNum(2);
		return roomId;
	}
	
	
	/**
	 * 记录使用记录
	 * @param userCode 
	 * @return 
	 * @return
	 */
	public String setInterviewHis(InterviewHisReq req, String userCode, String identityFlag) {
		int count = 0;
		MdeVideoUseHis his = new MdeVideoUseHis();

    	//获取面试邀请信息
		MdeInterview intvInfo = getIntvInfoByKey(req.getRoomId(), userCode, identityFlag);
		if(intvInfo != null)
		{
			//面试记录
			his.preInsert(userCode);
			his.setRoomId(req.getRoomId());
			his.setHotelCode(intvInfo.getPublisher());
			his.setParticipant(intvInfo.getInterviewee());
			his.setType("1");
			his.setStartTime(req.getStartTime());
			his.setStopTime(req.getStopTime());
			his.setUsedTime(DateUtils.getMinuteSubUp(req.getStartTime(), req.getStopTime()));
			count = videoUseHis.insert(his);
		}

		if(count < 1) {
    		throw new CustomException(InfoMsg.ERROR_DATA_UPDATE);
    	}  else {
    		return his.getUsedId();
    	}
	}
	
	
	/**
	 * 发送面试邀请信息
	 * @return
	 */
	public void sendIntvMsg(String publisher, InterviewCreateReq intvReq)
	{
		
		// 邀请面试发送微信消息给用户
		MdeUser personUser = mdeUserDao.getFullInfo(intvReq.getInterviewee());
		
		if(StringsUtils.isNotEmpty(personUser.getOpenId()) || StringsUtils.isNotEmpty(personUser.getOpenIdMini())) {
			//有小程序openid或者微信openid的时候发送模板消息
			MdeUser enterpriseUser = mdeUserDao.getFullInfo(publisher);
			MdeJobAdvertised job = mdeJobAdvertisedDao.getInfoById(intvReq.getJobId(),Constants.LANG_CN);
			WxMiniTMsgSendDto re = organizationIntvParam(personUser,enterpriseUser,job.getJobName(),intvReq);
			wxMinService.sendUniformMessage(re); // 小程序消息推送
		}else{
		    //发送短信
		    String phoneNo = personUser.getUserName();
		    String phoneCode = personUser.getPhoneCode();
            // 判断是否是大陆手机号 (手机号 如+8612345)
            if ("86".equals(phoneCode)) {
                // 邀请面试 发送短信 （大陆）
                verificationCodeService.sendInterviewCn(phoneNo, personUser.getName());
            } else {
                // 国际
                phoneNo = phoneNo.substring(phoneCode.length() + 1, phoneNo.length()); // 截取手机号
                // 手机号 开头为0 去掉
                if (phoneNo.startsWith("0")) {
                    phoneNo = phoneNo.substring(1, phoneNo.length());
                }
                verificationCodeService.sendInterviewEn(phoneCode, phoneNo, personUser.getName());
            }
		}
	}

	private WxMiniTMsgSendDto organizationIntvParam(MdeUser user,MdeUser publisher,String jobName,InterviewCreateReq intvReq) {
		WxMiniTMsgSendDto invited = new WxMiniTMsgSendDto();
		//设置发送给谁
		if(StringsUtils.isEmpty(user.getOpenIdMini())) {
			invited.setTouser(user.getOpenId());
		} else {
			invited.setTouser(user.getOpenIdMini());
		}

		//小程序信息
		WxMiniTMsgProgramDto miniprogram = new WxMiniTMsgProgramDto(videoAppId);
		miniprogram.setAppid(videoAppId);
		miniprogram.setPagepath(MessageUtils.getText(intvInvitationMinpUrl, intvReq.getIntvId().toString(), jobName));

		//信息参数设置
		TMsg5ParamsDto dto = new TMsg5ParamsDto();
		dto.setFirst(user.getName()+"，你好。有企业HR向您发出了面试邀请。","#173177");
		dto.setKeyword1(publisher.getName());
		dto.setKeyword2(jobName);
		dto.setKeyword3("点击查看并确认面试时间" );
		//面试方式[0-现场面试 1-视频面试]
		if("0".equals(intvReq.getType()))
		{
			List<String> codeList = new ArrayList<String>();
			codeList.add(intvReq.getAddrProvince());
			codeList.add(intvReq.getAddrCity());
			codeList.add(intvReq.getAddrArea());
			dto.setKeyword4(comService.getNameStrByCodes(codeList, Constants.LANG_CN)+" "+intvReq.getAddDetail());
		} else {
			dto.setKeyword4("线上视频面试");
		}
		//负责HR
		dto.setKeyword5(intvReq.getEntContacts()+""+intvReq.getEntContactInfo());
		dto.setRemark(intvReq.getIntvTimeList().get(0).getContent(),"#173177");
		
		//公众号模板消息实装
		WxMiniTMsgMpDto tmsgMpDto = new WxMiniTMsgMpDto();
		tmsgMpDto.setAppid(wxAppid);
		tmsgMpDto.setTemplate_id(interviewInvitationTemplateId);
		tmsgMpDto.setMiniprogram(miniprogram);
		tmsgMpDto.setData(dto);
		//小程序状态
		tmsgMpDto.setMiniprogram_state(videoMpState);
		
		invited.setMp_template_msg(tmsgMpDto);
		return invited;
	}
	
	/**
	 * 发送面试修改提醒信息
	 * @return
	 */
	public void sendIntvChangeTimeMsg(InterviewUpdateReq intvUpdReq, String identityFlag)
	{
		// 个人用户信息
		MdeUser personUser = mdeUserDao.getFullInfo(intvUpdReq.getInterviewee());
		// 企业用户信息
		MdeUser enterpriseUser = mdeUserDao.getFullInfo(intvUpdReq.getPublisher());
		
		// 获取面试邀请详情
		InterviewDetailDto intvDetai = getIntvDetail(intvUpdReq.getPublisher(), intvUpdReq.getInterviewee(), intvUpdReq.getIntvId().toString());
		
	    //发送短信
	    String phoneNo = "";
	    String phoneCode = "";
		
		// 被发信者
		MdeUser sendToUser = null;
		//信息参数设置
		TMsg5ParamsDto dto = new TMsg5ParamsDto();
		if(Constants.IDENTITY_P.equals(identityFlag))
    	{
    		//个人用户修改-发给企业确认
			sendToUser = enterpriseUser;
			//联系人
			dto.setKeyword4(enterpriseUser.getName());
			dto.setKeyword5(enterpriseUser.getUserName());
		    //发送短信
		    phoneNo = enterpriseUser.getEntPhone();
    	} else {
    		//企业用户修改-发给个人确认
    		sendToUser = personUser;
    		//联系人
			dto.setKeyword4(intvDetai.getEntContacts());
			dto.setKeyword5(intvDetai.getEntContactInfo());
			//发送短信
		    phoneNo = personUser.getUserName();
		    phoneCode = personUser.getPhoneCode();
    	}
		if(StringsUtils.isNotEmpty(sendToUser.getOpenId()) || StringsUtils.isNotEmpty(sendToUser.getOpenIdMini())) {
			//有小程序openid或者微信openid的时候发送模板消息
			
			MdeJobAdvertised job = mdeJobAdvertisedDao.getInfoById(intvDetai.getJobId(),Constants.LANG_CN);
			WxMiniTMsgSendDto re = orgIntvChangeTimeParam(sendToUser, job.getJobName(), enterpriseUser.getName(), dto, intvDetai);
			wxMinService.sendUniformMessage(re); // 小程序消息推送
		}else{
            //更改面试时间 
            verificationCodeService.sendSms1Pam(phoneCode, phoneNo, smsIntvTimeUpd, sendToUser.getName());
		}
	}
	
	private WxMiniTMsgSendDto orgIntvChangeTimeParam(MdeUser sendToUser,String jobName, String coName, TMsg5ParamsDto paramsDto, InterviewDetailDto intvDetai) {
		WxMiniTMsgSendDto invited = new WxMiniTMsgSendDto();
		//设置发送给谁
		if(StringsUtils.isEmpty(sendToUser.getOpenIdMini())) {
			invited.setTouser(sendToUser.getOpenId());
		} else {
			invited.setTouser(sendToUser.getOpenIdMini());
		}

		//小程序信息
		WxMiniTMsgProgramDto miniprogram = new WxMiniTMsgProgramDto(videoAppId);
		miniprogram.setAppid(videoAppId);
		miniprogram.setPagepath(MessageUtils.getText(intvInvitationMinpUrl, intvDetai.getIntvId().toString(), jobName));

		//信息参数设置
		paramsDto.setFirst(sendToUser.getName()+"，您提出的面试时间对方觉得不太合适并已修改，请尽快确认！","#173177");
		paramsDto.setKeyword2(coName);
		paramsDto.setKeyword1(jobName);
		//面试方式[0-现场面试 1-视频面试]
		if("0".equals(intvDetai.getType()))
		{
			paramsDto.setKeyword3(intvDetai.getAddrProvinceName()+intvDetai.getAddrCityName()+intvDetai.getAddrAreaName()+" "+intvDetai.getAddDetail());
		} else {
			paramsDto.setKeyword3("线上视频面试");
		}
		paramsDto.setRemark("戳开后，立即修改或确认面试时间","#173177");
		
		//公众号模板消息实装
		WxMiniTMsgMpDto tmsgMpDto = new WxMiniTMsgMpDto();
		tmsgMpDto.setAppid(wxAppid);
		tmsgMpDto.setTemplate_id(intvChangeTimeTemplateId);
		tmsgMpDto.setMiniprogram(miniprogram);
		tmsgMpDto.setData(paramsDto);
		//小程序状态
		tmsgMpDto.setMiniprogram_state(videoMpState);
		
		invited.setMp_template_msg(tmsgMpDto);
		return invited;
	}
	
	/**
	 * 创建新线程用于异步调用
	 * 创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程
	 *
	 * @return
	 */
	private ExecutorService cachedThreadPool = Executors.newCachedThreadPool() ;
	
	/**
	 * 发送面试确认提醒信息(异步)
	 * 
	 * @param list
	 * @return
	 */
	public void sendIntvConfirmMsgAsync(final InterviewConfirmReq confirmReq, final MdeUser personUser, final MdeUser enterpriseUser) {
		// 模板消息基类装配
		WxMiniTMsgSendDto makeIntvConfirmTimeDto = makeIntvConfirmTimeDto(personUser, enterpriseUser, confirmReq);

		try {
			//发送消息-个人
			sendIntvConfirmTimeMsg(personUser,makeIntvConfirmTimeDto);
		} catch (Exception e) {
			log.error("***********发送 个人面试确认提醒信息异常:"+personUser.getName()+"*******", e);
		}
		
		try {
			//发送消息-企业
			sendIntvConfirmTimeMsg(enterpriseUser,makeIntvConfirmTimeDto);
		} catch (Exception e) {
			log.error("***********发送企业面试确认提醒信息异常:"+enterpriseUser.getName()+"*******", e);
		}	
	}
	
	
	/**
	 * 发送面试确认提醒信息
	 * @return
	 */
	public void sendIntvConfirmTimeMsg(final MdeUser sendToUser, final WxMiniTMsgSendDto tmsgSendIn)
	{
		WxMiniTMsgSendDto tmsgSendDto = new WxMiniTMsgSendDto();
		// 同名属性赋值
		BeanUtils.copyProperties(tmsgSendIn, tmsgSendDto);
	    //发送短信
	    String phoneNo = "";
	    String phoneCode = "";
		
		if(Constants.IDENTITY_C.equals(sendToUser.getIdentityFlag()))
    	{
			//发给企业确认
		    phoneNo = sendToUser.getEntPhone();
    	} else {
    		//发给个人确认
		    phoneNo = sendToUser.getUserName();
		    phoneCode = sendToUser.getPhoneCode();
    	}
		if(StringsUtils.isNotEmpty(sendToUser.getOpenId())) {
			//有微信openid的时候发送模板消息
			tmsgSendDto.setTouser(sendToUser.getOpenId());
			wxMinService.sendUniformMessage(tmsgSendDto); // 小程序消息推送
		} else if(StringsUtils.isNotEmpty(sendToUser.getOpenIdMini())) {
			//有小程序openid时候发送模板消息
			tmsgSendDto.setTouser(sendToUser.getOpenIdMini());
			wxMinService.sendUniformMessage(tmsgSendDto); // 小程序消息推送
		}else{
            //确认面试时间 
            verificationCodeService.sendSms1Pam(phoneCode, phoneNo, smsIntvTimeOk, sendToUser.getName());
		}
	}
	
	/**
	 *  实装发送面试确认提醒信息的模板消息基类
	 * @return
	 */
	public WxMiniTMsgSendDto makeIntvConfirmTimeDto(MdeUser personUser, MdeUser enterpriseUser,InterviewConfirmReq confirmReq)
	{
		// 获取面试邀请详情
		InterviewDetailDto intvDetai = getIntvDetail(confirmReq.getPublisher(), confirmReq.getInterviewee(), confirmReq.getIntvId().toString());

		//信息参数设置
		TMsg4ParamsDto dto = new TMsg4ParamsDto();
		//面试人选
		dto.setKeyword2(personUser.getName());
		
		//获取职位信息
		MdeJobAdvertised job = mdeJobAdvertisedDao.getInfoById(intvDetai.getJobId(),Constants.LANG_CN);
		// 微信模板消息发送基类实装
		WxMiniTMsgSendDto tmsgSendDto = orgIntvConfirmTimeParam(job.getJobName(), enterpriseUser.getName(), dto, intvDetai);
		
		return tmsgSendDto;
	}
	
	private WxMiniTMsgSendDto orgIntvConfirmTimeParam(String jobName, String coName,TMsg4ParamsDto paramsDto, InterviewDetailDto intvDetai) {
		WxMiniTMsgSendDto invited = new WxMiniTMsgSendDto();
		
		//小程序信息
		WxMiniTMsgProgramDto miniprogram = new WxMiniTMsgProgramDto(videoAppId);
		miniprogram.setAppid(videoAppId);
		miniprogram.setPagepath(MessageUtils.getText(intvConfirmTimeMinpUrl, intvDetai.getIntvId().toString(), jobName));

		//信息参数设置
		paramsDto.setFirst("面试时间已确认，请查阅并按时参加哦！","#173177");
		paramsDto.setKeyword1(coName + " " + jobName);
		//面试方式[0-现场面试 1-视频面试]
		if("0".equals(intvDetai.getType()))
		{
			paramsDto.setKeyword3(intvDetai.getAddrProvinceName()+intvDetai.getAddrCityName()+intvDetai.getAddrAreaName()+" "+intvDetai.getAddDetail());
		} else {
			paramsDto.setKeyword3(new TMsgValueReq("视频面试 面试房间号："+intvDetai.getRoomId(),"#CE0000"));
		}
		paramsDto.setKeyword4(DateUtils.formatString(intvDetai.getIntvTime(), DateUtils.PATTEN_HM));
		paramsDto.setRemark("点击查看详情！","#173177");
		
		//公众号模板消息实装
		WxMiniTMsgMpDto tmsgMpDto = new WxMiniTMsgMpDto();
		tmsgMpDto.setAppid(wxAppid);
		tmsgMpDto.setTemplate_id(intvConfirmTimeTemplateId);
		tmsgMpDto.setMiniprogram(miniprogram);
		tmsgMpDto.setData(paramsDto);
		//小程序状态
		tmsgMpDto.setMiniprogram_state(videoMpState);
		
		invited.setMp_template_msg(tmsgMpDto);
		return invited;
	}
	
	
	/**
	 * 发送拒绝面试信息
	 * @return
	 */
	public void sendRefuseIntvMsg(InterviewRefuseReq refuseReq,MdeUser personUser)
	{
		// 企业用户信息
		MdeUser enterpriseUser = mdeUserDao.getFullInfo(refuseReq.getPublisher());
		// 获取面试邀请详情
		InterviewDetailDto intvDetai = getIntvDetail(refuseReq.getPublisher(), personUser.getUserCode(), refuseReq.getIntvId().toString());

		if(StringsUtils.isNotEmpty(enterpriseUser.getOpenId()) || StringsUtils.isNotEmpty(enterpriseUser.getOpenIdMini())) {
			//有小程序openid或者微信openid的时候发送模板消息
			//信息参数设置
			TMsg3ParamsDto dto = new TMsg3ParamsDto();
			//获取职位信息
			MdeJobAdvertised job = mdeJobAdvertisedDao.getInfoById(intvDetai.getJobId(),Constants.LANG_CN);
			// 微信模板消息发送基类实装
			dto.setKeyword1(job.getJobName());
			dto.setKeyword2(enterpriseUser.getName());
			dto.setRemark("拒绝理由："+refuseReq.getRefuseReason()+" 有疑问可联系 +"+personUser.getPhoneCode()+personUser.getUserName(), "#173177");
			WxMiniTMsgSendDto tmsgSendDto = orgRefuseIntvParam(dto, intvDetai.getIntvId().toString(),job.getJobName(), personUser.getName());
			if(StringsUtils.isNotEmpty(enterpriseUser.getOpenId())) {
				//有微信openid的时候发送模板消息
				tmsgSendDto.setTouser(enterpriseUser.getOpenId());
			} else if(StringsUtils.isNotEmpty(enterpriseUser.getOpenIdMini())) {
				//有小程序openid时候发送模板消息
				tmsgSendDto.setTouser(enterpriseUser.getOpenIdMini());
			}
			wxMinService.sendUniformMessage(tmsgSendDto); // 小程序消息推送
		}else{
            //拒绝面试
            verificationCodeService.sendSms2Pam("", enterpriseUser.getEntPhone(), smsIntvRefuse, enterpriseUser.getName(),personUser.getName());
		}

	}
	
	private WxMiniTMsgSendDto orgRefuseIntvParam(TMsg3ParamsDto paramsDto, String intvId, String jobName, String name) {
		WxMiniTMsgSendDto invited = new WxMiniTMsgSendDto();
		
		//小程序信息
		WxMiniTMsgProgramDto miniprogram = new WxMiniTMsgProgramDto(videoAppId);
		miniprogram.setAppid(videoAppId);
		miniprogram.setPagepath(MessageUtils.getText(intvRefuseTimeMinpUrl, intvId, jobName));

		//信息参数设置
		paramsDto.setFirst(name+ " 已拒绝您的面试邀请！","#173177");
		paramsDto.setKeyword3("登陆后查看详情");
		
		//公众号模板消息实装
		WxMiniTMsgMpDto tmsgMpDto = new WxMiniTMsgMpDto();
		tmsgMpDto.setAppid(wxAppid);
		tmsgMpDto.setTemplate_id(intvRefuseTimeTemplateId);
		tmsgMpDto.setMiniprogram(miniprogram);
		tmsgMpDto.setData(paramsDto);
		//小程序状态
		tmsgMpDto.setMiniprogram_state(videoMpState);
		
		invited.setMp_template_msg(tmsgMpDto);
		return invited;
	}
	
}
