/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.guosen.activity.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.guosen.ActivityUv.entity.ActivityUv;
import org.springblade.modules.guosen.ActivityUv.service.IActivityUvService;
import org.springblade.modules.guosen.activity.dto.ActivityDTO;
import org.springblade.modules.guosen.activity.entity.Activity;
import org.springblade.modules.guosen.activity.mapper.ActivityMapper;
import org.springblade.modules.guosen.activity.service.IActivityService;
import org.springblade.modules.guosen.activity.vo.ActivityVO;
import org.springblade.modules.guosen.activity.vo.HitPersonVo;
import org.springblade.modules.guosen.activityPresent.entity.ActivityPresent;
import org.springblade.modules.guosen.activityPresent.service.IActivityPresentService;
import org.springblade.modules.guosen.activityTag.entity.ActivityTag;
import org.springblade.modules.guosen.activityTag.service.IActivityTagService;
import org.springblade.modules.guosen.helpRecord.service.IHelpRecordService;
import org.springblade.modules.guosen.loginUser.entity.LoginUser;
import org.springblade.modules.guosen.loginUser.service.ILoginUserService;
import org.springblade.modules.guosen.loginUser.vo.LoginWebVO;
import org.springblade.modules.guosen.present.entity.Present;
import org.springblade.modules.guosen.present.vo.PresentVO;
import org.springblade.modules.guosen.rank.service.RankService;
import org.springblade.modules.guosen.userActivityStatistical.service.IUserActivityStatisticalService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 *  服务实现类
 *
 * @author BladeX
 * @since 2021-06-09
 */
@Service
public class ActivityServiceImpl extends BaseServiceImpl<ActivityMapper, Activity> implements IActivityService {

	@Resource
	private IActivityTagService activityTagService;
	@Resource
	private IActivityPresentService activityPresentService;
	@Resource
	private ILoginUserService loginUserService;
	@Resource @Lazy
	private IHelpRecordService helpRecordService;
	@Resource
	private RankService rankService;
	@Resource
	private IActivityUvService activityUvService;

	@Override
	public IPage<ActivityVO> selectActivityPage(IPage<ActivityVO> page, ActivityVO activity) {
		return page.setRecords(baseMapper.selectActivityPage(page, activity));
	}

	@Override
	public IPage<ActivityVO> selectPageWithTag(IPage<ActivityVO> page, ActivityVO activityVO) {
		List<ActivityVO> activityVOS = baseMapper.selectPageWithTag(page, activityVO);
		//判断活动是否结束
		activityVOS.forEach(item->{
			//当前时间
			LocalDateTime now = LocalDateTime.now();
			//开始时间
			LocalDateTime beginTime = item.getBeginTime();
			//结束时间
			LocalDateTime endTime = item.getEndTime();
			if (now.isBefore(beginTime)) {
				//未开始
				item.setActivityStatus(0);
			} else if (now.isAfter(beginTime) && now.isBefore(endTime)) {
				//进行中
				item.setActivityStatus(1);
			} else if (now.isAfter(endTime)) {
				//已结束
				item.setActivityStatus(2);
			}
		});
		return page.setRecords(activityVOS);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean createOrUpdate(ActivityDTO activityDTO) {
		//创建或修改活动
		this.saveOrUpdate(activityDTO);
		//标签
		//先删除活动标签中间表的相关活动标签
		activityTagService.remove(Condition.getQueryWrapper(new ActivityTag()).lambda()
			.eq(ActivityTag::getActivityId, activityDTO.getId()));
		//再保存新的标签
		List<ActivityTag> activityTags = new ArrayList<>();
		activityDTO.getTagIds().forEach(item->{
			ActivityTag activityTag = new ActivityTag();
			activityTag.setActivityId(activityDTO.getId());
			activityTag.setTagId(item);
			activityTags.add(activityTag);
		});
		activityTagService.saveBatch(activityTags);

		//礼物
		//先删除礼物中间表的相关礼物记录
		activityPresentService.remove(Condition.getQueryWrapper(new ActivityPresent()).lambda()
			.eq(ActivityPresent::getActivityId, activityDTO.getId()));
		List<ActivityPresent> activityPresents = new ArrayList<>();
		activityDTO.getPresentIds().forEach(item->{
			ActivityPresent activityPresent = new ActivityPresent();
			activityPresent.setActivityId(activityDTO.getId());
			activityPresent.setPresentId(item);
			activityPresents.add(activityPresent);
		});
		return activityPresentService.saveBatch(activityPresents);
	}

	@Override
	@Transactional
	public Boolean removeActivity(String ids) {
		List<Long> activityIds = Func.toLongList(ids);
		//删除中间表记录
		for (Long id : activityIds) {
			activityTagService.remove(Condition.getQueryWrapper(new ActivityTag()).lambda().eq(ActivityTag::getActivityId, id));
			activityPresentService.remove(Condition.getQueryWrapper(new ActivityPresent()).lambda().eq(ActivityPresent::getActivityId, id));
		}
		int i = baseMapper.deleteBatchIds(activityIds);
		return i>0?true:false;
	}
	@Override
	public HitPersonVo getHitPersonDetail(Long activityId, Long senderId, Long receiverId) {
		HitPersonVo hitPersonVo = new HitPersonVo();
		LoginUser receiverUser = loginUserService.getById(receiverId);
		//基础用户信息
		hitPersonVo.setUserId(receiverId);
		hitPersonVo.setCover(receiverUser.getCover());
		hitPersonVo.setAvatar(receiverUser.getAvatar());
		hitPersonVo.setNickName(receiverUser.getNickName());
		hitPersonVo.setVideo(receiverUser.getVideo());
		//排名
		LoginWebVO loginWebVO = rankService.rank(activityId.toString(), receiverId.toString(), 0);
		hitPersonVo.setSequence(loginWebVO.getRank());
		hitPersonVo.setHotValue(BigDecimal.valueOf(Double.parseDouble(loginWebVO.getScore())));
		//已打榜次数
		Long hitCount = Long.valueOf("0");
		if (senderId != null) {
			hitCount = helpRecordService.getUserDayHitCount(senderId, activityId);
		}
		//可打榜次数
		Activity activity = baseMapper.selectById(activityId);
		Integer ticketDays = activity.getTicketDays();
		long num = ticketDays - hitCount;
		long allowHitNum= num< 0 ? 0 : num;
		hitPersonVo.setAllowHitCount(allowHitNum);
		//活动的一票等于多少热力值
		hitPersonVo.setActivityHotValue(activity.getTicketHotValue());
		//作者的打榜列表
//		HelpRecordVO helpRecordVO = new HelpRecordVO();
//		helpRecordVO.setType(3);
//		helpRecordVO.setReceiverId(receiverId);
//		HelpRecordVO helpRecordVO1 = new HelpRecordVO();
//		helpRecordVO1.setType(2);
//		helpRecordVO1.setReceiverId(receiverId);
//		Query query = new Query();
//		query.setCurrent(1);
//		query.setSize(500);
//		List<HelpRecordVO> helpRecordVOS = helpRecordService.selectHelpRecordVoPage(Condition.getPage(query), helpRecordVO).getRecords();
//		List<HelpRecordVO> helpRecordVOS1 = helpRecordService.selectHelpRecordVoPage(Condition.getPage(query), helpRecordVO1).getRecords();
//		helpRecordVOS.addAll(helpRecordVOS1);
//		hitPersonVo.setHelpRecordVOS(helpRecordVOS);
		//该活动的礼物列表
		List<Present> presentList = activityPresentService.getPresents(activityId);
		hitPersonVo.setPresentList(presentList);
		return hitPersonVo;
	}

	@Override
	public void visit(Long id, Long userId) {
		//更新活动pv
		Activity activity = this.getById(id);
		Integer visitBase = activity.getVisitBase();//基础浏览量
		visitBase = visitBase == null ? 0 : visitBase;
		Integer visitTotal = activity.getTotalVisit();//总浏览量
		Integer num= visitTotal == null || visitTotal==0 ? (visitBase+1) : (visitTotal + 1);
		activity.setTotalVisit(num);
		this.updateById(activity);
		//更新活动uv
		if (userId == null) {
			return;
		}
		List<ActivityUv> activityUvs = activityUvService.list(Condition.getQueryWrapper(new ActivityUv()).lambda().eq(ActivityUv::getUserId, userId).eq(ActivityUv::getActivityId, id));
		if ( CollUtil.isNotEmpty(activityUvs)) {
			return;
		}
		ActivityUv activityUv = new ActivityUv();
		activityUv.setUserId(userId);
		activityUv.setActivityId(id);
		activityUvService.save(activityUv);
	}
}
