package com.ssj.service.weixin.library.service.impl;


import com.alibaba.dubbo.config.annotation.Service;
import com.ssj.bean.weixin.libmy.domain.LibVip;
import com.ssj.bean.weixin.libmy.domain.TbLibJoin;
import com.ssj.bean.weixin.libmy.domain.TbLibManager;
import com.ssj.bean.weixin.libmy.domain.TbLibSubscribe;
import com.ssj.bean.weixin.push.domain.SendTemplateShort;
import com.ssj.bean.weixin.sales.domain.LibVipService;
import com.ssj.bean.weixin.user.domain.User;
import com.ssj.bean.weixin.zyb.domain.ZuoybStudentPush;
import com.ssj.dao.weixin.library.dao.ILibJoinQueryDao;
import com.ssj.dao.weixin.library.dao.ISubscribeDao;
import com.ssj.dao.weixin.library.dao.ISubscribeQueryDao;
import com.ssj.framework.basic.utils.DateHelper;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.security.manager.TokenManager;
import com.ssj.framework.core.util.Constant;
import com.ssj.framework.core.util.ResponseEntity;
import com.ssj.framework.weixin.util.DateUtil;
import com.ssj.service.sys.imlibuser.service.TbClassStudentService;
import com.ssj.service.sys.push.service.SconXingeService;
import com.ssj.service.weixin.library.service.IBookManagerService;
import com.ssj.service.weixin.library.service.ILibJoinService;
import com.ssj.service.weixin.library.service.ILibSubscribeService;
import com.ssj.service.weixin.library.service.ILibVipService;
import com.ssj.service.weixin.push.service.PushTemplateService;
import com.ssj.service.weixin.sales.service.LibVipServiceService;
import com.ssj.service.weixin.user.service.UserService;
import com.ssj.service.weixin.zuoyb.service.ZuoybStudentPushSerivce;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;

import java.text.SimpleDateFormat;
import java.util.*;

@Service(version="1.0")
public class LibSubscribeServiceImpl extends BaseServiceImpl<TbLibSubscribe, String> implements ILibSubscribeService {

	private static Logger logger = LoggerFactory.getLogger(LibSubscribeServiceImpl.class);

	@Autowired
	private ISubscribeDao dao;
	@Autowired
	private ILibJoinQueryDao  libJoinQueryDao;
	@Autowired
	private  ISubscribeQueryDao queryDao;
	 @Autowired
    private  PushTemplateService pushTemplateService;
	@Autowired
	private ILibVipService libVipService;
	@Autowired
	private UserService userService;
	@Autowired
	private ILibJoinService libJoinService;
	@Autowired
	private ZuoybStudentPushSerivce zuoybStudentPushSerivce;
	@Autowired
	private LibVipServiceService libVipServiceService;
	@Autowired
	private TokenManager tokenManager;
	@Autowired
	private SconXingeService sconXingeService;
	@Autowired
	private IBookManagerService managerService;

	@Override
	public PagingAndSortingRepository<TbLibSubscribe, String> getDao() {
		
		return dao;
	}

	@Override
	public TbLibSubscribe findByUserId(String userId) {
		
		return dao.findByUserId(userId);
	}

	@Override
	public TbLibSubscribe findByUserIdAndStat(String userId, String stat) {
		
		return dao.findByUserIdAndStat(userId,stat);
	}

	@Override
	public TbLibSubscribe findByVipIdAndStat(String vipId, String stat) {
		
		return dao.findByVipIdAndStat(vipId,stat);
	}

	@Override
	public List<Map<String, Object>> countLibSubscribeNum() {
		return libJoinQueryDao.countLibSubscribeNum();
	}



	@Override
	public Map<String, Object> findSubCount(String libId,TbLibSubscribe subsccribe) {
		
		return libJoinQueryDao.findSubCount(libId,subsccribe);
	}

	@Override
	public Map<String, Object> findInAndBorrow(String vipId) {
		
		return libJoinQueryDao.findInAndBorrow(vipId);
	}

	@Override
	public Map<String, Object> findOneManager(String libId) {
		
		return libJoinQueryDao.findOneManager(libId);
	}
	@Override
	public List<Map<String, Object>> countCurOpenCard(boolean iscount) {
		return libJoinQueryDao.countCurOpenCard(iscount);
	}

	@Override
	public Page<Map<String, Object>> findByPage(
			Map<String, Object> searchParams, Pageable pageable) {
		
		return queryDao.findByPage(searchParams, pageable);
	}
	
	
	//图书馆下的所有有效的会员列表查询
	@Override
	public Page<Map<String, Object>> findLibByVipPage(Map<String, Object> searchParams, Pageable pageable){
    	return queryDao.findLibByVipPage(searchParams, pageable);
    }
	
	@Override
	public Page<Map<String, Object>> findLibByRykeAndLeavePage(Map<String, Object> searchParams, Pageable pageable){
		return queryDao.findLibByRykeAndLeavePage(searchParams, pageable);
	}

	@Override
	public Page<Map<String, Object>> findByConfirmPage(Map<String, Object> searchParams, Pageable pageable) {
		
		return queryDao.findByConfirmPage(searchParams, pageable);
	}

	@Override
	public List<Map<String, Object>> findByRykeList(String libId,String date) {
		
		return queryDao.findByRykeList(libId,date);
	}
	
	@Override
	public List<Map<String, Object>> querySalesUserCounter(String libId){
		return queryDao.querySalesUserCounter(libId);
	}
	
	@Override
	public  Integer queryTyperCounter(String libId,String type){
		return queryDao.queryTyperCounter(libId,type);
	}
	@Override
	public Integer queryPriceTypeCounter(String libId,String priceType){
		return queryDao.queryPriceTypeCounter(libId,priceType);
	}

	@Override
	public Map<String, Object> countWeeklyRead(String vipId, String startTime,
			String endTime) {
		return queryDao.countWeeklyRead(vipId, startTime, endTime);
	}

	@Override
	public Map<String, Object> queryRankingByVip(String vipId,
			String startTime, String endTime) {
		return queryDao.queryRankingByVip(vipId, startTime, endTime);
	}

	@Override
	public List<Map<String, Object>> queryCompanionByVip(String vipId,
			String startTime, String endTime) {
		return queryDao.queryCompanionByVip(vipId, startTime, endTime);
	}

	@Override
	public Map<String, Object> queryBookTagByVip(String vipId,
			String startTime, String endTime) {
		return queryDao.queryBookTagByVip(vipId, startTime, endTime);
	}

	@Override
	public List<Map<String, Object>> queryBorrowByVip(String startTime,
			String endTime) {
		return queryDao.queryBorrowByVip(startTime, endTime);
	}

	@Override
	public Map<String, Object> queryEffectiveByVip(String vipId) {
		
		return queryDao.queryEffectiveByVip(vipId);
	}

	@Override
	public Long countBorrowByVip(String vipId, String startTime,
			String endTime) {
		
		return queryDao.countBorrowByVip(vipId, startTime, endTime);
	}

	@Override
	public List<Map<String, Object>> countLivelyByVip(String vipId,
			String startTime, String endTime) {
		
		return queryDao.countLivelyByVip(vipId, startTime, endTime);
	}

	@Override
	public Long countSubscribeByVip(String vipId, String startTime,
			String endTime) {
		
		return queryDao.countSubscribeByVip(vipId, startTime, endTime);
	}

	@Override
	public Map<String, Object> findComeLibInfo(String vipId) {
		
		return queryDao.findComeLibInfo(vipId);
	}

	@Override
	public Map<String, Object> findWeekReadInfo(String vipId) {
		
		return queryDao.findWeekReadInfo(vipId);
	}

	@Override
	public Map<String, Object> findworkInfo(String vipId,String libId) {
		
		return queryDao.findworkInfo(vipId,libId);
	}

	@Override
	public Map<String, Object> findWorkSug(String pushId) {
		
		return queryDao.findWorkSug(pushId);
	}


	@Override
	public Map<String, Object> findTheMonthCountAndTime(String vipId, String beginTime, String endTime) {
		return queryDao.findTheMonthCountAndTime(vipId, beginTime, endTime);
	}

	@Override
	public  void pushBorrowTask() {
		//推雅居乐GZ200
		String libId = "149a7b0b-6bcd-45e0-8e99-845193396759";
		String template_id_short="OPENTM408917121";
		List<Map<String, Object>> vipList = queryDao.pushBorrowTask(libId,getLastMaxMonthDate());
		Map<String, String> data = new HashMap<String, String>();
		if(vipList!=null && vipList.size()>0){
			for (Map<String, Object> map : vipList) {
				data.put("first","馆长，您好。此用户上月共借阅书籍"+map.get("borrow_num")+"本");
				data.put("keyword3",map.get("child_name")+"(小孩姓名)");
				data.put("keyword1",map.get("flow_id")+"(卡号)");
				data.put("keyword2", DateHelper.format(new Date(), "yyyy年MM月dd日  HH时mm分 "));
				data.put("remark", "");
				SendTemplateShort templateShort2 = new SendTemplateShort("otguNv2whq68iBYfiYtIkNF7ba3M", template_id_short, null, data);
				pushTemplateService.saveAndSendPushWxTemplate(templateShort2);
			}
			
		}
		
	}

    @Override
    public ResponseEntity signIn(Set<String> vipIdSet, String libId, String confirmUserId) {
		ResponseEntity responseEntity = new ResponseEntity();
		List<TbLibSubscribe> libSubscribeList = new ArrayList<>();
		List<SendTemplateShort> wxTemplateMessageNeed2PushList = new ArrayList<>();
		List<Map<String, String>> parentAppMessageNeedPushList = new LinkedList<>();
		Map<String, String> tempParentAppMessageNeedPush;

		//遍历学生id，校验是否可签到，并准备生成签到记录
		TbLibJoin libJoin = null;
		Date now = new Date();
		//用于时间累加
		Map<String, Date> dateMap = new HashMap<>(16);
		dateMap.put("now", now);
		for (String vipId : vipIdSet) {
			if (!tokenManager.addLock(Constant.SIGN_LOCK_PREFIX + vipId, Thread.currentThread().getName(), 10)) {
				//尝试加锁，若失败则跳过此学生
				continue;
			}
			//检验是否是有效的孩子
			LibVip libVip = libVipService.getById(vipId);
			if (libVip==null) {
				logger.info("家长id（userId）为空，此为废弃记录，无法签到，vipI=" + vipId);
				responseEntity.failure("无效孩子，无法签到");
				return responseEntity;
			}
			String userId = libVip.getUserId();
			if (StringUtils.isBlank(userId)) {
				logger.info("家长id（userId）为空，此为废弃记录，无法签到，vipI=" + vipId);
				responseEntity.failure("无效孩子，无法签到");
				return responseEntity;
			}
			//校验是否拥有有效的作业吧服务（根据最新逻辑，此处校验可能有问题！因为家长购买的平台服务不与馆进行绑定，但是小孩仍可以绑定到该馆进行签到）
			//LibVipService zybService = libVipServiceService.getVipIdZXService5days(libVip, libId);
			/*if (zybService == null) {
				logger.info("需要先购买作业吧服务，才可以到馆签到，vipId=" + vipId);
				responseEntity.failure("未购买作业吧服务，无法签到");
				return responseEntity;
			}*/

			//获取当前有效服务
			int serviceType = libVipServiceService.getCurrentCorrectService(vipId);
			if (serviceType == 0) {
				logger.info("需要先购买服务，才可以到馆签到，vipId=" + vipId);
				responseEntity.failure("当前无有效服务，无法签到");
				return responseEntity;
			}
			//校验是否已经签到过
			TbLibSubscribe libSubscribe = dao.findTodaySignedHistoryByVipId(vipId);
			if (libSubscribe != null) {//已经签到过了，不可重复签到
				logger.info("重复签到操作，vipId=" + vipId);
				responseEntity.failure("已经签到过了，不可重复签到");
				return responseEntity;
			}



			//准备需要保存的签到记录
			libSubscribe = new TbLibSubscribe();
			libSubscribe.setVipId(vipId);
			libSubscribe.setStat("1");
			libSubscribe.setFlowStat("3");
			libSubscribe.setCreateTime(now);
			libSubscribe.setLibId(libId);
			libSubscribe.setUserId(userId);
			libSubscribe.setRykeTime(now);
			libSubscribe.setRykeConfirmUser(confirmUserId);

			libSubscribeList.add(libSubscribe);

			//签到就添加push记录
			this.signInCreatePush(vipId, libId, dateMap);

			//准备需要推送的消息
			Map<String,String> data = new HashMap<>();
			User user = userService.getById(userId);
			if (libJoin == null) {
				libJoin = libJoinService.getById(libId);
				if (libJoin == null) {
					return responseEntity.failure("馆不存在");
				}
			}
			String shortTemplateId = "OPENTM207941156";
			data.put("first", libVip.getChildName()+"妈妈/爸爸，您好！您的孩子已安全到达"+libJoin.getLeagueName()+"\n");
			data.put("keyword1", libVip.getChildName());
			data.put("keyword2", libJoin.getLeagueName());
			data.put("keyword3",DateHelper.format(now,"yyyy年MM月dd日  HH时mm分"));
			data.put("remark", "\n状态：已到馆");
			SendTemplateShort templateShort = new SendTemplateShort(user.getAccount(), shortTemplateId, null, data);
			wxTemplateMessageNeed2PushList.add(templateShort);

			tempParentAppMessageNeedPush = new HashMap<>();
			tempParentAppMessageNeedPush.put("pushUserId", libVip.getUserId());
			tempParentAppMessageNeedPush.put("vipId", vipId);
			tempParentAppMessageNeedPush.put("content", String.format("%s妈妈/爸爸，您好！您的孩子已安全到达%s", libVip.getChildName(), libJoin.getLeagueName()));
			parentAppMessageNeedPushList.add(tempParentAppMessageNeedPush);
		}

		//保存到数据库
		dao.save(libSubscribeList);

		//推送微信模板消息
		if (!wxTemplateMessageNeed2PushList.isEmpty()) {
			wxTemplateMessageNeed2PushList.forEach(it -> pushTemplateService.savePushWxTemplate(it));
		}

		//推送家长端app消息提醒
		if (!parentAppMessageNeedPushList.isEmpty()) {
			parentAppMessageNeedPushList.forEach(it -> sconXingeService.asynPushThreadTask(it.get("pushUserId"), it.get("vipId"), 2, it.get("content"), "PUSH_OTHER"));
		}

		responseEntity.success();

		return responseEntity;
    }

    @Override
	public void signInCreatePush(String vipId, String libId, Map<String, Date> map) {
		ZuoybStudentPush push = zuoybStudentPushSerivce.findByVipIdToDay(vipId);
		if (push == null) {
			push = new ZuoybStudentPush();
			push.setType(0);
			push.setVipId(vipId);
			push.setLibId(libId);
			push.setPushTime(new Date());
			push.setCourseHour("A");
		} else {
			push.setLibId(libId);
			push.setUpdateTime(new Date());
		}
		//平均分配给馆里该班级的管理老师
		//查找同一班级的所有管理老师
		TbLibManager teacher = managerService.findTopClassTeacherList(vipId, null, 2);
		if (teacher != null) {
			//更新分配时间，下次分配可根据分配时间分配，达到大致平均
			//防止循环导致时间一致不能平均分配，每次时间递增一秒
			teacher.setAllotTime(map.get("now"));
			map.put("now", DateUtil.addSeconds(map.get("now"), 1));
			managerService.save(teacher);
			push.setTeacherId(teacher.getUserId());
		}
		zuoybStudentPushSerivce.save(push);
	}

	@Override
	public ResponseEntity signOff(Set<String> vipIdSet, String confirmUserId) {
		ResponseEntity responseEntity = new ResponseEntity();
		ArrayList<TbLibSubscribe> libSubscribeList = new ArrayList<>();
		List<SendTemplateShort> wxTemplateMessageNeed2PushList = new ArrayList<>();
		List<Map<String, String>> parentAppMessageNeedPushList = new LinkedList<>();
		Map<String, String> tempParentAppMessageNeedPush;

		//遍历学生id，校验是否可签离，并准备更新签到记录为签离状态
		TbLibJoin libJoin = null;
		Date now = new Date();
		for (String vipId : vipIdSet) {
			TbLibSubscribe libSubscribe = dao.findTodaySignedHistoryByVipId(vipId);
			if (libSubscribe == null) {//今日未签到，不可签离
				logger.info("今日未签到却进行签离，vipId=" + vipId);
				responseEntity.failure("今日未签到，不可签离");
				return responseEntity;
			} else if (Objects.equals(libSubscribe.getFlowStat(), "4")) {
				logger.info("重复签离操作，vipId=" + vipId);
				responseEntity.failure("已签离，请勿重复操作");
				return responseEntity;
			}

			//签离需要老师编辑完成，即对应zuoybStudentPush的type需要为2或3
//			ZuoybStudentPush zuoybStudentPush = zuoybStudentPushSerivce.findByVipIdAndDate(vipId, DateUtil.format_yyyyMMddHHmmss(libSubscribe.getCreateTime()));
//			Integer type = zuoybStudentPush.getType();
//			if (type != 2 && type != 3) {
//				logger.info("老师编辑未完成，不可签离，zuoybStudentPush=" + zuoybStudentPush);
//				responseEntity.failure("老师编辑未完成，不可签离");
//				return responseEntity;
//			}

			libSubscribe.setLeaveTime(now);
			libSubscribe.setLeaveConfirmUser(confirmUserId);
			libSubscribe.setFlowStat("4");

			libSubscribeList.add(libSubscribe);

			//准备需要推送的消息
			Map<String,String> data = new HashMap<>();
			String userId = libSubscribe.getUserId();
			if (StringUtils.isBlank(userId)) {
				logger.info("学生数据异常，userId=" + vipId);
				responseEntity.failure("无法查询学生的家长，签离失败");
				return responseEntity;
			}
			User user = userService.getById(userId);
			LibVip libVip = libVipService.getById(vipId);
			if (libJoin == null) {
				libJoin = libJoinService.getById(libSubscribe.getLibId());
			}
			String shortTemplateId = "OPENTM406027659";
			data.put("first", libVip.getChildName()+"妈妈/爸爸，您好！您的孩子已离开"+ libJoin.getLeagueName()+ ",请留意孩子是否安全到家。\n");
			data.put("keyword1", libVip.getChildName());
			data.put("keyword2", libJoin.getLeagueName());
			data.put("keyword3",DateHelper.format(now,"yyyy年MM月dd日  HH时mm分"));
			data.put("remark", "\n状态：已离馆");
			SendTemplateShort templateShort = new SendTemplateShort(user.getAccount(), shortTemplateId, null, data);
			wxTemplateMessageNeed2PushList.add(templateShort);

			tempParentAppMessageNeedPush = new HashMap<>();
			tempParentAppMessageNeedPush.put("pushUserId", libVip.getUserId());
			tempParentAppMessageNeedPush.put("vipId", vipId);
			tempParentAppMessageNeedPush.put("content", String.format("%s妈妈/爸爸，您好！您的孩子已离开%s，请留意孩子是否安全到家。", libVip.getChildName(), libJoin.getLeagueName()));
			parentAppMessageNeedPushList.add(tempParentAppMessageNeedPush);
		}

		//保存到数据库
		dao.save(libSubscribeList);

		//推送微信模板消息
		if (!wxTemplateMessageNeed2PushList.isEmpty()) {
			wxTemplateMessageNeed2PushList.forEach(it -> pushTemplateService.savePushWxTemplate(it));
		}

		//推送家长端app消息提醒
		if (!parentAppMessageNeedPushList.isEmpty()) {
			parentAppMessageNeedPushList.forEach(it -> sconXingeService.asynPushThreadTask(it.get("pushUserId"), it.get("vipId"), 2, it.get("content"), "PUSH_OTHER"));
		}

		responseEntity.success();

		return responseEntity;
	}

	@Override
	public TbLibSubscribe findTheDayByVipId(String vipId, Date date) {
		return dao.findTheDayByVipIdAndStat(vipId, date);
	}

	@Override
	public TbLibSubscribe findTodaySignedHistoryByVipId(String vipId) {
		return dao.findTodaySignedHistoryByVipId(vipId);
	}

	/**
	 * 
	 * @Title: getLastMaxMonthDate
	 * @Description: 获取上个月的月份
	 * @param @return    设定文件
	 * @return String    返回类型
	 * @author shenhao
	 * @date 2018年8月16日 上午11:25:40
	 * @throws
	 */
	public static String getLastMaxMonthDate() {
        SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return dft.format(calendar.getTime());
    }


	@Override
	public List<TbLibSubscribe> findDaysByVipId(String vipId, Date beginDate, Date endDate) {
		String beginTime = DateUtil.format_yyyyMMdd(beginDate);
		String endTime = DateUtil.format_yyyyMMdd(endDate) + " 23:59:59";
		return dao.findDaysByVipIdAndStat(vipId, beginTime, endTime);
	}
}
