/*
 *      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.production.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
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.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.modules.guosen.activity.entity.Activity;
import org.springblade.modules.guosen.activity.service.IActivityService;
import org.springblade.modules.guosen.activityPresent.service.IActivityPresentService;
import org.springblade.modules.guosen.helpRecord.service.IHelpRecordService;
import org.springblade.modules.guosen.helpRecord.vo.HelpRecordVO;
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.service.IPresentService;
import org.springblade.modules.guosen.production.entity.Production;
import org.springblade.modules.guosen.production.mapper.ProductionMapper;
import org.springblade.modules.guosen.production.service.IProductionService;
import org.springblade.modules.guosen.production.vo.ProductionVO;
import org.springblade.modules.guosen.rank.service.RankService;
import org.springblade.modules.guosen.userActivityStatistical.entity.UserActivityStatistical;
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.util.List;

/**
 *  服务实现类
 *
 * @author BladeX
 * @since 2021-06-16
 */
@Service
public class ProductionServiceImpl extends BaseServiceImpl<ProductionMapper, Production> implements IProductionService {

	@Resource @Lazy
	private ILoginUserService loginUserService;
	@Resource @Lazy
	private IHelpRecordService helpRecordService;
	@Resource @Lazy
	private IActivityService activityService;
	@Resource
	private IActivityPresentService activityPresentService;
	@Resource
	private IUserActivityStatisticalService userActivityStatisticalService;
	@Resource
	private RankService rankService;

	@Override
	public IPage<ProductionVO> selectProductionPage(IPage<ProductionVO> page, ProductionVO production) {
		return page.setRecords(baseMapper.selectProductionPage(page, production));
	}

	/**
	 * 查询作品详情
	 * @param id 作品id
	 * @param userId 查询人的id，用于查询剩余打榜次数
	 * @return
	 */
	@Override
	public ProductionVO getProductDetail(Long id, Long userId) {
		ProductionVO productionVO = new ProductionVO();
		Production production = this.getById(id);
		if (production == null) {
			return null;
		}
		BeanUtil.copyProperties(production,productionVO);
		//用户头像
		productionVO.setAvatar(loginUserService.getById(productionVO.getUserId()).getAvatar());
		//查询作品排名
		LoginWebVO loginWebVO = rankService.rank(productionVO.getActivityId().toString(), id.toString(), 1);
		productionVO.setRank(loginWebVO.getRank());
//		List<Production> productionList = this.list(Condition.getQueryWrapper(new Production()).lambda()
//			.eq(Production::getActivityId, productionVO.getActivityId())
//			.orderByDesc(Production::getHotValue));
//		int rank = productionList.indexOf(production) + 1;
//		productionVO.setRank(rank);
		//获取作品对应的活动
		Activity activity = activityService.getById(production.getActivityId());
		//获取活动一票等于多少积分
		productionVO.setTicketHotValue(activity.getTicketHotValue());
		//获取该用户当天还可以打榜多少次
		Long hitCount = helpRecordService.getUserDayHitCount(userId, productionVO.getActivityId());
		Integer ticketDays = activity.getTicketDays();
		long num = ticketDays - hitCount;
		long allowHitNum = num < 0 ? 0 : num;
		productionVO.setAllowHitNum(allowHitNum);
		//获取该作品的助力列表
//		Query query = new Query();
//		query.setCurrent(1);
//		query.setSize(500);
//		HelpRecordVO helpRecordVO = new HelpRecordVO();
//		helpRecordVO.setProductId(production.getId());
//		IPage<HelpRecordVO> helpRecordVOIPage = helpRecordService.selectHelpRecordVoPage(Condition.getPage(query), helpRecordVO);
//		List<HelpRecordVO> helpRecordVOS = helpRecordVOIPage.getRecords();
//		productionVO.setHelpRecordList(helpRecordVOS);
		//获取该活动的礼物列表
		List<Present> presentList = activityPresentService.getPresents(activity.getId());
		productionVO.setPresentList(presentList);
		return productionVO;
	}

	@Override
	@Transactional
	public R create(Production production) {
		Assert.notNull(production.getUserId(), "参赛者id不能为空");
		Assert.notNull(production.getActivityId(), "活动id不能为空");
		//更改该用户的身份为参赛用户
		Long userId = production.getUserId();
		LoginUser loginUser = loginUserService.getById(userId);
		Assert.notNull(loginUser, "报名失败，该用户不存在");
		loginUser.setUserType(1);
		loginUserService.updateById(loginUser);
		//活动参赛人数+1
		Activity activity = activityService.getById(production.getActivityId());
		Integer applyNum = activity.getApplyNum();
		Integer num = applyNum == null ? 1 : (applyNum + 1);
		activity.setApplyNum(num);
		activityService.updateById(activity);

		//插入用户活动可用积分中
		UserActivityStatistical statisticalServiceOne = userActivityStatisticalService.getOne(Condition.getQueryWrapper(new UserActivityStatistical()).lambda()
			.eq(UserActivityStatistical::getUserId, userId)
			.eq(UserActivityStatistical::getActivityId, production.getActivityId()));
		if (statisticalServiceOne == null) {
			UserActivityStatistical userActivityStatistical = new UserActivityStatistical();
			userActivityStatistical.setActivityId(production.getActivityId());
			userActivityStatistical.setUserId(userId);
			userActivityStatistical.setUsableHotValue(BigDecimal.ZERO);
			userActivityStatistical.setTotalHotValue(BigDecimal.ZERO);
			userActivityStatistical.setUsablePointsValue(BigDecimal.ZERO);
			userActivityStatistical.setTotalPointsValue(BigDecimal.ZERO);
			//选手排名
			rankService.addScore(activity.getId().toString(), userId.toString(), Double.valueOf("0"), 0);
			userActivityStatisticalService.save(userActivityStatistical);
		}
		//作品排名
		this.save(production);
		rankService.addScore(activity.getId().toString(), production.getId().toString(), Double.valueOf("0"), 1);

		return R.data(production);
	}

	@Override
	public Boolean delete(List<Long> idList) {
		//从缓存中移除
		for (Long id : idList) {
			Production production = this.getById(id);
			Long activityId = production.getActivityId();
			this.deleteLogic(idList);
			rankService.zSetRemove(activityId.toString(),id.toString(),1);

			//如果该用户没有作品了，就将用户类型改回普通用户
			Long userId = production.getUserId();
			List<Production> list = this.list(Condition.getQueryWrapper(new Production()).lambda().eq(Production::getUserId, userId));
			if (CollUtil.isEmpty(list)) {
				LoginUser user = loginUserService.getById(userId);
				user.setUserType(0);
				loginUserService.updateById(user);
			}
		}
		return true;
	}

}
