package com.iformall.schedule;

import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Multimaps;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.domain.po.WxMall;
import com.iformall.domain.po.invest.*;
import com.iformall.domain.po.msg.WxMsgRecord;
import com.iformall.domain.vo.invest.InvestCustomerVo;
import com.iformall.enums.*;
import com.iformall.mapper.WxMallMapper;
import com.iformall.mq.MqBaseProducer;
import com.iformall.service.MallUserInfoService;
import com.iformall.service.invest.*;
import com.iformall.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;


@Slf4j
@Component
public class InvestSchedule {

	public static final String[] ENV_STR = {"dev", "test"};
	@Autowired
	InvestBizService bizService;
	@Autowired
	InvestTaskService taskService;
	@Autowired
	InvestMessageService messageService;
	@Autowired
	InvestDemandService demandService;
	@Autowired
	InvestCustomerService customerService;
	@Autowired
	InvestFollowRecordService followRecordService;
	@Autowired
	InvestRemindService remindService;
	@Resource
	WxMallMapper mallMapper;
	@Autowired
	MallUserInfoService userInfoService;
	@Autowired
	private MqBaseProducer mqBaseProducer;

	@Autowired
	Environment environment;

	private static final String TAG_MESSAGE = "招商定时任务-消息";
	private static final String TAG_REMIND = "招商定时任务-提醒";


	@Scheduled(cron = "0 0 14 * * ?") // 每天下午两点执行定时任务
	//@Scheduled(cron = "0 */30 * * * *?") // 测试，每30分钟执行
	public void messageSchedule() {
		log.info("{}: 开始", TAG_MESSAGE);
		//一个月内未完成提醒
		taskMonthMessage();
		//一周内未跟踪提醒
		demandWeekMessage();
		log.info("{}: 结束", TAG_MESSAGE);
	}

	@Scheduled(cron = "0 */5 * * * *?")
	public void remindSchedule() {
		log.info("{}: 开始", TAG_REMIND);
		// 提醒新
		List<InvestRemindEntity> reminds = remindService.findUnRemindList();
		log.info("{}：提醒数 ：{}", TAG_REMIND, reminds.size());
		if (CollectionUtils.isEmpty(reminds)) {
			return;
		}

		// mall 信息
		List<WxMall> mallList = mallMapper.findList(new WxMall());
		if (mallList.size() == 0) {
			log.info("{}: No Mall info found", TAG_REMIND);
			return;
		}
		Map<String, WxMall> mallMap = InvestHelper.getMap(mallList, WxMall::getTenantId);
		// 用户信息
		List<MallUserInfo> userList = userInfoService.findList(new MallUserInfo());
		if (userList.size() == 0) {
			log.info("{}: No user info found", TAG_REMIND);
			return;
		}
		Map<Long, MallUserInfo> userMap = InvestHelper.getMap(userList, MallUserInfo::getId);

		Collection<InvestCustomerEntity> customs = customerService.listByIds(InvestHelper.getIds(reminds, InvestRemindEntity::getCustomerId));
		Map<Long, InvestCustomerEntity> customerMap = InvestHelper.getMap(customs, InvestCustomerEntity::getId);

		Calendar now = Calendar.getInstance();
		for (InvestRemindEntity remind : reminds) {
			if (Objects.equals(remind.getMinute(), 0L)) {
				log.warn("{}：remindID:{} 不提醒, 跳过", TAG_REMIND, remind.getId());
				continue;
			}

			Calendar begin = Calendar.getInstance();
			begin.setTime(remind.getBeginDate());
			if (getRemindMinute(now, begin) > remind.getMinute()) {
				boolean sended = sendSMS(userMap.get(remind.getOwner()), mallMap.get(remind.getTenantId()), remind, customerMap.get(remind.getCustomerId()));
				if (sended) {
					remind.setStatus(EnumInvestRemindStatus.REMINDED);
					remindService.updateById(remind);
				}
			}
		}
		log.info("{}: 结束", TAG_REMIND);
	}

	private long getRemindMinute(Calendar c1, Calendar c2) {
		long beginTime = c1.getTime().getTime();
		long endTime = c2.getTime().getTime();
		return (endTime - beginTime) / (1000 * 60);
	}

	private void taskMonthMessage() {
		//已经存在的提醒
		List<InvestMessageEntity> taskMessages = messageService.listByTypeAndTag(EnumFollowType.TASK, EnumInvestMessageTag.TASK_MONTH);
		ImmutableListMultimap<Long, InvestMessageEntity> taskMessageUserIdMap = Multimaps.index(taskMessages, InvestMessageEntity::getOwner);

		//初始化时间条件
		Calendar start = Calendar.getInstance();
		Calendar end = Calendar.getInstance();
		if (environment.acceptsProfiles(ENV_STR)) {
			end.add(Calendar.DAY_OF_YEAR, 1); //测试
		} else {
			end.add(Calendar.MONTH, 1);
		}
		//查询满足条件
		List<InvestTaskEntity> tasks = taskService.listByStatusAndTime(Arrays.asList(EnumTaskStatus.INTENTION, EnumTaskStatus.NEGOTIATING), start.getTime(), end.getTime());
		log.info("{}：{} - {} 的任务数 ：{}", TAG_MESSAGE, start, end, tasks.size());
		if (tasks.isEmpty()) {
			return;
		}
		for (InvestTaskEntity task : tasks) {
			String owner = task.getOwner();
			if (StringUtils.isEmpty(owner)) {
				log.warn("{}：taskID:{} owner不存在：{}, 跳过", TAG_MESSAGE, task.getId(), task.getOwner());
				continue;
			}
			List<Long> ownerArray = JSONArray.parseArray(owner, Long.class);
			for (Long ownerId : ownerArray) {
				List<InvestMessageEntity> messageList = taskMessageUserIdMap.get(ownerId);
				if (CollectionUtils.isNotEmpty(messageList)) {
					for (InvestMessageEntity messageEntity : messageList) {
						if (messageEntity.getTid().equals(task.getId())) {
							log.info("{}：taskID:{} 提醒已存在：{}, 跳过", TAG_MESSAGE, task.getId(), messageEntity.getId());
							continue;
						}
						addTaskMessage(task, ownerArray);
					}
				} else {
					addTaskMessage(task, ownerArray);
				}
			}
		}
	}

	private void addTaskMessage(InvestTaskEntity task, List<Long> ownerArray) {
		String message = String.format(EnumInvestMessageType.TASK_REMIND.getInfo(), task.getId(), DateUtils.format(task.getLastTime()));
		messageService.saveBatchMessage(ownerArray, message, EnumInvestMessageTag.TASK_MONTH, EnumFollowType.TASK, task.getId(),task);
		log.info("{}：taskID:{} 为用户{}创建消息提醒", TAG_MESSAGE, task.getId(), task.getOwner());
	}

	private void demandWeekMessage() {
		//已经存在的提醒
		List<InvestMessageEntity> demandMessages = messageService.listByTypeAndTag(EnumFollowType.DEMAND, EnumInvestMessageTag.CUSTOMER_WEEK);
		ImmutableListMultimap<Long, InvestMessageEntity> demandMessageUserIdMap = Multimaps.index(demandMessages, InvestMessageEntity::getOwner);

		//初始化时间条件
		Calendar start = Calendar.getInstance();
		if (environment.acceptsProfiles(ENV_STR)) {
			start.add(Calendar.DAY_OF_YEAR, -1); //测试
		} else {
			start.add(Calendar.DAY_OF_YEAR, -7);
		}

		//查询跟踪列表
		List<InvestFollowRecordEntity> follows = followRecordService.listByTime(EnumFollowType.DEMAND, start.getTime());

		List<InvestCustomerVo> demands = customerService.listByIds(InvestHelper.getIds(follows, InvestFollowRecordEntity::getFollowId),
				Arrays.asList(EnumCustomerType.INTENTIONAL, EnumCustomerType.POTENTIAL));

		// 已经提醒过的用户
		List<String> userDemandFlag = new ArrayList<>();
		for (InvestCustomerVo customerVo : demands) {
			Long owner = customerVo.getDemandOwner();
			if (Objects.isNull(owner)) {
				log.warn("{}：customerID:{} owner不存在：{}, 跳过", TAG_MESSAGE, customerVo.getId(), customerVo.getDemandOwner());
				continue;
			}
			List<InvestMessageEntity> messageList = demandMessageUserIdMap.get(owner);
			if (CollectionUtils.isEmpty(messageList)) {
				addCustomerMessage(customerVo, owner);
			}
			for (InvestMessageEntity messageEntity : messageList) {
				if (messageEntity.getTid().equals(messageEntity.getId())) {
					log.info("{}：taskID:{} 提醒已存在：{}, 跳过", TAG_MESSAGE, customerVo.getId(), messageEntity.getId());
					continue;
				}
				String userDemandFlagItem = StringUtils.join(messageEntity.getOwner(), messageEntity.getId());
				//已经提醒过的用户不在提醒
				if (userDemandFlag.contains(userDemandFlagItem)) {
					log.info("{}：taskID:{} 提醒已存在：{}, 跳过", TAG_MESSAGE, customerVo.getId(), userDemandFlagItem);
					continue;
				}
				addCustomerMessage(customerVo, owner);
				userDemandFlag.add(userDemandFlagItem);
			}
		}
	}

	private void addCustomerMessage(InvestCustomerVo customerVo, Long owner) {
		String message = String.format(EnumInvestMessageType.COSTOMER_REMIND.getInfo(), customerVo.getId());
		messageService.saveBatchMessage(Collections.singletonList(owner), message, EnumInvestMessageTag.CUSTOMER_WEEK, EnumFollowType.DEMAND, customerVo.getId(), customerVo);
		log.info("{}：customerID:{} 为用户{}创建消息提醒", TAG_MESSAGE, customerVo.getId(), customerVo.getDemandOwner());
	}

	private boolean sendSMS(MallUserInfo userInfo, WxMall mall, InvestRemindEntity remind, InvestCustomerEntity customer) {
		if (Objects.isNull(userInfo) || Objects.isNull(mall) || Objects.isNull(customer)) {
			log.warn("{}: 参数为空 : userInfo: {}, mall: {} ,customer:{}", TAG_REMIND, userInfo, mall, customer);
			return false;
		}
		WxMsgRecord wxMsgRecord = new WxMsgRecord();
		wxMsgRecord.setMsgType(EnumMsgRecordType.SMS.getCode());
		wxMsgRecord.setReceiver(userInfo.getPhone());
		wxMsgRecord.updateTenantInfo(userInfo);
		Map<String, String> dynamicContentMap = new HashMap<>();
		wxMsgRecord.setModelType(EnumMsgModel.INVEST_REMIND.getCode());
		dynamicContentMap.put("mallName", mall.getName());
		dynamicContentMap.put("beginDate", DateUtils.formatDateTime(remind.getBeginDate()));
		dynamicContentMap.put("negotiationType", convet(remind.getNegotiationType()));
		dynamicContentMap.put("customerName", customer.getName());
		wxMsgRecord.setDynamicContentMap(dynamicContentMap);
		mqBaseProducer.sendMessage(wxMsgRecord, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
		return true;
	}

	private String convet(EnumNegotiationType type) {
		String message = "";
		if (Objects.equals(type, EnumNegotiationType.TO_VISIT)) {
			message = "预约拜访";
		} else if (Objects.equals(type, EnumNegotiationType.COME_VISIT)) {
			message = "需接待来访";
		} else if (Objects.equals(type, EnumNegotiationType.TELEPHONE)) {
			message = "需电话联系";
		} else if (Objects.equals(type, EnumNegotiationType.MESSAGE)) {
			message = "需短信、微信或其他方式联系";
		}

		return message;
	}
}