package com.zhongzheng.modules.activity.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.zhongzheng.common.utils.DateUtils;
import com.zhongzheng.modules.activity.domain.ActivityTaskTime;
import com.zhongzheng.modules.activity.domain.ActivityTaskUser;
import com.zhongzheng.modules.activity.service.IActivityTaskTimeService;
import com.zhongzheng.modules.activity.service.IActivityTaskUserService;
import com.zhongzheng.modules.activity.vo.ActivityTaskTimeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.zhongzheng.modules.activity.bo.ActivityTaskAddBo;
import com.zhongzheng.modules.activity.bo.ActivityTaskQueryBo;
import com.zhongzheng.modules.activity.bo.ActivityTaskEditBo;
import com.zhongzheng.modules.activity.domain.ActivityTask;
import com.zhongzheng.modules.activity.mapper.ActivityTaskMapper;
import com.zhongzheng.modules.activity.vo.ActivityTaskVo;
import com.zhongzheng.modules.activity.service.IActivityTaskService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务存储Service业务层处理
 *
 * @author change
 * @date 2021-05-19
 */
@Service
public class ActivityTaskServiceImpl extends ServiceImpl<ActivityTaskMapper, ActivityTask> implements IActivityTaskService {

    @Autowired
    private IActivityTaskTimeService activityTaskTimeService;

    @Autowired
    private IActivityTaskUserService activityTaskUserService;

    @Autowired
    private IActivityTaskService iActivityTaskService;

    @Override
    public ActivityTaskVo queryById(Long id){
        ActivityTask db = this.baseMapper.selectById(id);

        ActivityTaskVo activityTaskTimeMove = activityTaskTimeMove(db);

        return activityTaskTimeMove;
    }

    private ActivityTaskVo activityTaskTimeMove(ActivityTask db) {
        ActivityTaskVo activityTaskVo = BeanUtil.toBean(db, ActivityTaskVo.class);
        if (activityTaskVo.getId() != null && activityTaskVo.getTaskType() == 5) {
            LambdaQueryWrapper<ActivityTaskTime> lqwTime = Wrappers.lambdaQuery();
            lqwTime.eq(db.getId() != null,ActivityTaskTime::getTaskId,db.getId());
            List<ActivityTaskTimeVo> activityTaskTimeVo = entity2TimeActivityVo(activityTaskTimeService.list(lqwTime));
            activityTaskVo.setActivityTaskTimeVo(activityTaskTimeVo);
        }
        return activityTaskVo;
    }
    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<ActivityTaskTimeVo> entity2TimeActivityVo(Collection<ActivityTaskTime> collection) {
        List<ActivityTaskTimeVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, ActivityTaskTimeVo.class))
                .collect(Collectors.toList());
        return voList;
    }
    @Override
    public List<ActivityTaskVo> queryList(ActivityTaskQueryBo bo) {
        LambdaQueryWrapper<ActivityTask> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getTaskType() != null, ActivityTask::getTaskType, bo.getTaskType());
        lqw.eq(bo.getStartIntegral() != null, ActivityTask::getStartIntegral, bo.getStartIntegral());
        lqw.eq(bo.getEndIntegral() != null, ActivityTask::getEndIntegral, bo.getEndIntegral());
        lqw.eq(StrUtil.isNotBlank(bo.getRemarks()), ActivityTask::getRemarks, bo.getRemarks());
        lqw.eq(StrUtil.isNotBlank(bo.getDescription()), ActivityTask::getDescription, bo.getDescription());
        lqw.eq(bo.getAccIntegral() != null, ActivityTask::getAccIntegral, bo.getAccIntegral());
        lqw.eq(bo.getLongTime() != null, ActivityTask::getLongTime, bo.getLongTime());
        lqw.eq(bo.getCountDay() != null, ActivityTask::getCountDay, bo.getCountDay());
        lqw.eq(bo.getStatus() != null, ActivityTask::getStatus, bo.getStatus());
        List<ActivityTaskVo> activityTaskVos = entity2Vo(this.list(lqw));
        activityTaskVos.stream().forEach(l -> {
            if (l.getId() != null && l.getTaskType() == 5) {
                LambdaQueryWrapper<ActivityTaskTime> lqwTime = Wrappers.lambdaQuery();
                lqwTime.eq(l.getId() != null,ActivityTaskTime::getTaskId,l.getId());
                List<ActivityTaskTimeVo> activityTaskTimeVo = entity2TimeActivityVo(activityTaskTimeService.list(lqwTime));
                l.setActivityTaskTimeVo(activityTaskTimeVo);
            }
        });
        return activityTaskVos;
    }


    /**
    * 实体类转化成视图对象
    *
    * @param collection 实体类集合
    * @return
    */
    private List<ActivityTaskVo> entity2Vo(Collection<ActivityTask> collection) {
        List<ActivityTaskVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, ActivityTaskVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<ActivityTask> page = (Page<ActivityTask>)collection;
            Page<ActivityTaskVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page,pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByAddBo(ActivityTaskAddBo bo) {
        ActivityTask add = BeanUtil.toBean(bo, ActivityTask.class);
        validEntityBeforeSave(add);
        add.setCreateTime(DateUtils.getNowTime());
        add.setUpdateTime(DateUtils.getNowTime());
        boolean save = iActivityTaskService.save(add);
        if (bo.getTaskType() != null && bo.getTaskType() == 5){
            bo.getActivityTaskTimeAddBo().stream().forEach(t -> activityTaskTimeService.inserTaskTime(BeanUtil.toBean(t,ActivityTaskTime.class).setTaskId(add.getId())));
        }
        return save;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByEditBo(ActivityTaskEditBo bo) {
        ActivityTask update = BeanUtil.toBean(bo, ActivityTask.class);
        update.setUpdateTime(DateUtils.getNowTime());
        validEntityBeforeSave(update);
        //活动为考试时有分数区域得到等级分数
        if (bo.getTaskType() != null && bo.getTaskType() == 5){
            activityTaskTimeService.removeById(bo.getId());
            bo.getActivityTaskTimeEditBoList().stream().forEach(t -> activityTaskTimeService.inserTaskTime(BeanUtil.toBean(t,ActivityTaskTime.class).setTaskId(bo.getId())));
        }
        return iActivityTaskService.updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(ActivityTask entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return iActivityTaskService.removeByIds(ids);
    }

    @Override
    public ActivityTaskVo queryByTaskId(Long taskId) {
        ActivityTask db = baseMapper.queryByTaskId(taskId);
        return BeanUtil.toBean(db,ActivityTaskVo.class);
    }

    @Override
    public List<ActivityTaskVo> querylistUser(ActivityTaskQueryBo bo) {
        LambdaQueryWrapper<ActivityTask> lqwActivity = Wrappers.lambdaQuery();
        lqwActivity.eq(ActivityTask::getStatus, 1);
        List<ActivityTaskVo> activityTaskVos = entity2Vo(this.list(lqwActivity));
        activityTaskVos.stream().forEach(l -> {
            if (l.getId() != null && l.getTaskType() == 5) {
                LambdaQueryWrapper<ActivityTaskTime> lqwTime = Wrappers.lambdaQuery();
                lqwTime.eq(l.getId() != null,ActivityTaskTime::getTaskId,l.getId());
                List<ActivityTaskTimeVo> activityTaskTimeVo = entity2TimeActivityVo(activityTaskTimeService.list(lqwTime));
                l.setActivityTaskTimeVo(activityTaskTimeVo);
            }
            ActivityTaskVo activityTaskVo = queryByTaskId(Convert.toLong(l.getTaskType()));
            l.setUserStatus(0);
            switch (l.getTaskType()){
                //每日签到逻辑，当日有领取即无法签到
                case 0:
                    LambdaQueryWrapper<ActivityTaskUser> lqw = Wrappers.lambdaQuery();
                    lqw.eq(bo.getTaskType() !=null,ActivityTaskUser::getTaskType,bo.getTaskType());
                    lqw.eq(bo.getUserId() !=null,ActivityTaskUser::getUserId,bo.getUserId());
                    lqw.between(ActivityTaskUser::getCreateTime,getTimesmorning(),getTimesnight());
                    List<ActivityTaskUser> list = activityTaskUserService.list(lqw);
                    if (!CollectionUtils.isEmpty(list) && list.size() > 0){
                        l.setUserStatus(1);
                    }
                    break;
                //完善信息  按照百分比求得乘以分数得到奖励分数
                case 1:
                    LambdaQueryWrapper<ActivityTaskUser> useWan = Wrappers.lambdaQuery();
                    useWan.eq(bo.getTaskType() !=null,ActivityTaskUser::getTaskType,bo.getTaskType());
                    useWan.eq(bo.getUserId() !=null,ActivityTaskUser::getUserId,bo.getUserId());
                    List<ActivityTaskUser> listWan = activityTaskUserService.list(useWan);
                    BigDecimal bigDecimal = new BigDecimal("0");
                    for (ActivityTaskUser activityTaskUser : listWan) {
                        bigDecimal = bigDecimal.add(new BigDecimal(activityTaskUser.getScore()));
                    }
                    if (bigDecimal.compareTo(new BigDecimal(activityTaskVo.getStartIntegral())) == 0){
                        l.setUserStatus(1);
                    }
                    break;
                case 2:
                    l.setUserStatus(0);
                    break;
                case 3:
                    //每日分享，大于三次达到上线
                    LambdaQueryWrapper<ActivityTaskUser> useMei = Wrappers.lambdaQuery();
                    useMei.eq(bo.getTaskType() !=null,ActivityTaskUser::getTaskType,bo.getTaskType());
                    useMei.eq(bo.getUserId() !=null,ActivityTaskUser::getUserId,bo.getUserId());
                    useMei.between(ActivityTaskUser::getCreateTime,getTimesmorning(),getTimesnight());
                    List<ActivityTaskUser> listMei = activityTaskUserService.list(useMei);
                    if (!CollectionUtils.isEmpty(listMei) && listMei.size() == 3){
                        l.setUserStatus(1);
                    }
                    break;
                case 4:
                    //连续学习，大于三次达到上线
                    LambdaQueryWrapper<ActivityTaskUser> study = Wrappers.lambdaQuery();
                    study.eq(bo.getTaskType() !=null,ActivityTaskUser::getTaskType,bo.getTaskType());
                    study.eq(bo.getUserId() !=null,ActivityTaskUser::getUserId,bo.getUserId());
                    study.between(ActivityTaskUser::getCreateTime,getTimesmorning(),getTimesnight());
                    List<ActivityTaskUser> listStudy = activityTaskUserService.list(study);
                    Integer score = 0;
                    for (ActivityTaskUser activityTaskUser : listStudy) {
                        score = score+ Convert.toInt(activityTaskUser.getScore());
                    }
                    if (!CollectionUtils.isEmpty(listStudy) && activityTaskVo.getEndIntegral().equals(score)){
                        l.setUserStatus(1);
                    }
                    break;
                case 5:
                    LambdaQueryWrapper<ActivityTaskUser> practice = Wrappers.lambdaQuery();
                    practice.eq(bo.getTaskType() !=null,ActivityTaskUser::getTaskType,bo.getTaskType());
                    practice.eq(bo.getUserId() !=null,ActivityTaskUser::getUserId,bo.getUserId());
                    practice.between(ActivityTaskUser::getCreateTime,getTimesmorning(),getTimesnight());
                    List<ActivityTaskUser> listPractice = activityTaskUserService.list(practice);
                    if (!CollectionUtils.isEmpty(listPractice) && listPractice.size() > 0){
                        l.setUserStatus(1);
                    }
                    break;

            }
        });

        return activityTaskVos;

    }

    //获得今天时间的0点
    public static int getTimesmorning(){
        Calendar cal = Calendar.getInstance();

        cal.set(Calendar.HOUR_OF_DAY, 0);

        cal.set(Calendar.SECOND, 0);

        cal.set(Calendar.MINUTE, 0);

        cal.set(Calendar.MILLISECOND, 0);

        return (int) (cal.getTimeInMillis()/1000);

    }

    //获得当天24点时间
    public static int getTimesnight(){
        Calendar cal = Calendar.getInstance();

        cal.set(Calendar.HOUR_OF_DAY, 24);

        cal.set(Calendar.SECOND, 0);

        cal.set(Calendar.MINUTE, 0);

        cal.set(Calendar.MILLISECOND, 0);

        return (int) (cal.getTimeInMillis()/1000);

    }

}
