package com.cyksj.service.market.task.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.constant.PointsRecordConst;
import com.cyksj.common.constant.TaskTypeEnum;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper;
import com.cyksj.mapper.market.task.TaskFollowPlatVerifyMapper;
import com.cyksj.mapper.market.task.TaskMapper;
import com.cyksj.mapper.market.task.TaskTypeMapper;
import com.cyksj.mapper.market.task.TaskUserCompleteRecordMapper;
import com.cyksj.model.entity.*;
import com.cyksj.model.views.TaskView;
import com.cyksj.service.coin.UserGalaxyCoinService;
import com.cyksj.service.market.task.TaskService;
import com.cyksj.service.user.UserBenefitsService;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/*
 *项目名: netflix
 *文件名: TaskServiceImpl
 *创建者: JavaZou
 *创建时间:2022/12/27 15:17
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TaskServiceImpl implements TaskService {

	public static List<String> times = List.of("添加企业微信", "绑定手机号", "关注引导");

	private final TaskTypeMapper taskTypeMapper;

	private final TaskMapper taskMapper;

	private final TaskUserCompleteRecordMapper taskUserCompleteRecordMapper;

	private final UserDistributeSharedMapper userDistributeSharedMapper;

	private final TaskFollowPlatVerifyMapper taskFollowPlatVerifyMapper;

	private final UserGalaxyCoinService userGalaxyCoinService;

	private final BeanSearcher beanSearcher;

	private final UserBenefitsService userBenefitsService;

	@Override
	public void saveTask(Task task) {
		checkTask(task);
		taskMapper.insert(task);
	}

	@Override
	public void updateTask(Task task) {
		Task db = taskMapper.selectById(task.getId());
		if (db == null || !db.getDeleted()) {
			throw BusinessRuntimeException.getInstance("该任务已不存在");
		}
		if (task.getPoints() == null || task.getPoints() <= 0) {
			throw BusinessRuntimeException.getInstance("积分不小于0");
		}
		BeanUtil.copyProperties(task, db);
		checkTask(db);
		taskMapper.updateById(db);
	}

	@Override
	public void completeTask(TaskType type, Long userId) {
		DateTime now = DateTime.now();
		DateTime beginOfDay = DateUtil.beginOfDay(now);
		DateTime endOfDay = DateUtil.endOfDay(now);
		DateTime beginOfWeek = DateUtil.beginOfWeek(now);
		DateTime endOfWeek = DateUtil.endOfWeek(now);
		LambdaQueryWrapper<TaskUserCompleteRecord> wrapper = Wrappers.lambdaQuery(TaskUserCompleteRecord.class)
				.eq(TaskUserCompleteRecord::getUserId, userId)
				.last("limit 1");
		List<Task> tasks = taskMapper.selectList(Wrappers.lambdaQuery(Task.class)
				.eq(Task::getTypeId, type.getId())
				.eq(Task::getStatus, true)
				.eq(Task::getDeleted, true));
		tasks.forEach(task -> {
			if ("time".equals(task.getTaskLimit())) {
				TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(Wrappers.lambdaQuery(TaskUserCompleteRecord.class)
						.eq(TaskUserCompleteRecord::getTaskId, task.getId())
						.eq(TaskUserCompleteRecord::getUserId, userId).last("limit 1"));
				if (record == null) {
					saveCompleteTask(task.getId(), userId, task.getPoints());
				}
			} else if ("day".equals(task.getTaskLimit())) {
				handleSpecialTask(type, task, userId, wrapper, beginOfDay, endOfDay);

			} else if ("week".equals(task.getTaskLimit())) {
				handleSpecialTask(type, task, userId, wrapper, beginOfWeek, endOfWeek);
			}
		});
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void batchVerifyFollow(List<TaskFollowPlatVerify> taskFollowPlatVerifyList) {
		TaskFollowPlatVerify.Status success = TaskFollowPlatVerify.Status.success;
		TaskFollowPlatVerify.Status fail = TaskFollowPlatVerify.Status.fail;
		TaskFollowPlatVerify.Status verifying = TaskFollowPlatVerify.Status.verifying;
		taskFollowPlatVerifyList.forEach(taskVerify -> {
			if (taskVerify.getId() != null) {
				TaskFollowPlatVerify dbPlatVerify = taskFollowPlatVerifyMapper.selectById(taskVerify.getId());
				TaskFollowPlatVerify.Status verifyStatus = taskVerify.getStatus();
				TaskFollowPlatVerify.Status dbStatus = dbPlatVerify.getStatus();
				Boolean isFlag = false;
				if (dbPlatVerify != null && dbStatus != success) {
					if (dbStatus == fail && verifyStatus == success) {
						dbPlatVerify.setStatus(success);
						dbPlatVerify.setErrorReason("");
						isFlag = true;
					} else if (dbStatus == verifying) {
						if (verifyStatus == fail) {
							dbPlatVerify.setStatus(fail);
							dbPlatVerify.setErrorReason(taskVerify.getErrorReason());
							isFlag = true;
						} else if (verifyStatus == success) {
							dbPlatVerify.setStatus(success);
							isFlag = true;
						}
					}
				}
				if (isFlag) {
					dbPlatVerify.setVerifyTime(DateTime.now());
					taskFollowPlatVerifyMapper.updateById(dbPlatVerify);
					TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(Wrappers.lambdaQuery(TaskUserCompleteRecord.class)
							.eq(TaskUserCompleteRecord::getUserId, taskVerify.getUserId())
							.eq(TaskUserCompleteRecord::getTaskId, taskVerify.getTaskId())
							.last("limit 1"));
					if (record == null) {
						return;
					}
					if (verifyStatus == success) {
						record.setStatus(TaskUserCompleteRecord.Status.received);
						userGalaxyCoinService.sendGalaxyCoinRecord(record.getUserId(), record.getPoints(), PointsRecordConst.TASK, false);
						TaskView taskView = beanSearcher.searchFirst(TaskView.class, MapUtils.builder().field(TaskView::getId, dbPlatVerify.getTaskId()).build());
						if (taskView != null) {
							if ("关注引导".equals(taskView.getTypeName()) && taskView.getBalance().compareTo(BigDecimal.ZERO) > 0) {
								//发送余额
								userBenefitsService.addUserBalance(dbPlatVerify.getUserId(), taskView.getBalance(), UserBalanceSourceRecord.Source.follow_task, 0l, null, taskView.getName(), true);
								record.setBalance(taskView.getBalance());
							}
						}
					} else if (verifyStatus == fail) {
						record.setStatus(TaskUserCompleteRecord.Status.fail);
					}
					taskUserCompleteRecordMapper.updateById(record);
				}
			}
		});
	}

	public void checkTask(Task task) {
		Long typeId = task.getTypeId();
		TaskType taskType = taskTypeMapper.selectById(typeId);
		if (times.contains(taskType.getName())) {
			if (!"time".equals(task.getTaskLimit())) {
				throw BusinessRuntimeException.getInstance("该任务类型只能为一次性");
			}
		}
		if ("邀请好友".equals(taskType.getName())) {
			if (task.getInviteNum() == null || task.getInviteNum() < 1) {
				throw BusinessRuntimeException.getInstance("邀请人数错误");
			}
		}
		LambdaQueryWrapper<Task> wrapper = Wrappers.lambdaQuery(Task.class)
				.eq(Task::getTypeId, typeId)
				.eq(Task::getDeleted, true).last("limit 1");
		if (task.getId() != null) {
			wrapper.ne(Task::getId, task.getId());
		}
		if (!"关注引导".equals(taskType.getName())) {
			Task selectOne = taskMapper.selectOne(wrapper);
			if (selectOne != null) {
				throw BusinessRuntimeException.getInstance("已新增对应的任务");
			}
			//关注引导 才配置奖励余额
			task.setBalance(BigDecimal.ZERO);
			task.setLink(StrUtil.EMPTY);
		}
		if (task.getBalance() != null && task.getBalance().compareTo(BigDecimal.ZERO) < 0) {
			throw BusinessRuntimeException.getInstance("请输入正确的奖励余额");
		}
	}

	public void saveCompleteTask(Long taskId, Long userId, Integer points) {
		TaskUserCompleteRecord record = new TaskUserCompleteRecord();
		record.setTaskId(taskId);
		record.setStatus(TaskUserCompleteRecord.Status.complete);
		record.setUserId(userId);
		record.setPoints(points);
		taskUserCompleteRecordMapper.insert(record);
	}

	public void handleSpecialTask(TaskType type, Task task, Long userId, LambdaQueryWrapper<TaskUserCompleteRecord> wrapper, DateTime beginTime, DateTime endTime) {
		wrapper.eq(TaskUserCompleteRecord::getTaskId, task.getId());
		if (!TaskTypeEnum.share.getDesc().equals(type.getName())) {
			wrapper.between(TaskUserCompleteRecord::getCreatedTime, beginTime, endTime);
			TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(wrapper);
			if (record == null) {
				saveCompleteTask(task.getId(), userId, task.getPoints());
			}
		} else if (TaskTypeEnum.share.getDesc().equals(type.getName())) {
			//邀请人数是否达标
			Integer count = userDistributeSharedMapper.selectCount(Wrappers.lambdaQuery(UserDistributeShared.class)
					.eq(UserDistributeShared::getSharedId, userId)
					.between(UserDistributeShared::getCreatedTime, beginTime, endTime));
			if (count >= task.getInviteNum()) {
				wrapper.between(TaskUserCompleteRecord::getCreatedTime, beginTime, endTime);
				TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(wrapper);
				if (record == null) {
					saveCompleteTask(task.getId(), userId, task.getPoints());
				}
			}
		}
	}
}
