package com.ruoyi.frequency.vote.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.code.DictConstant;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.controller.req.VoteReq;
import com.ruoyi.controller.resp.VoteDetailResp;
import com.ruoyi.controller.resp.VotePageResp;
import com.ruoyi.frequency.vote.entity.Vote;
import com.ruoyi.frequency.vote.mapper.VoteMapper;
import com.ruoyi.frequency.vote.model.result.VoteCount;
import com.ruoyi.frequency.vote.service.VoteService;
import com.ruoyi.frequency.voteoption.entity.VoteOption;
import com.ruoyi.frequency.voteoption.service.VoteOptionService;
import com.ruoyi.frequency.voterecord.entity.VoteRecord;
import com.ruoyi.frequency.voterecord.service.VoteRecordService;
import com.ruoyi.frequency.works.entity.Works;
import com.ruoyi.post.frequency.post.mapper.PostMapper;
import com.ruoyi.response.ResponseData;
import com.ruoyi.utils.BusinessUtil;
import com.ruoyi.utils.SnowIdUtils;
import com.ruoyi.vo.PageBasic;
import com.ruoyi.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 投票活动Service业务层处理
 *
 * @author liwenlong
 * @date 2023-10-12
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class VoteServiceImpl extends ServiceImpl<VoteMapper, Vote>  implements VoteService
{
    @Autowired
    private VoteMapper voteMapper;

    /**
     * 查询投票活动
     *
     * @param id 投票活动主键
     * @return 投票活动
     */
    @Override
    public Vote selectVoteById(Long id)
    {

        Vote vote = voteMapper.selectVoteById(id);

        //投票选项
        List<VoteOption> voteOptions = voteOptionService.getList(CollectionUtil.toList(id),null);

        Map<Long, List<VoteOption>> map = voteOptions.stream().collect(Collectors.groupingBy(VoteOption::getVoteId));

        vote.setVoteOptionList(map.get(vote.getId()));

        return vote;
    }

    /**
     * 查询投票活动列表
     *
     * @param vote 投票活动
     * @return 投票活动
     */
    @Override
    public List<Vote> selectVoteList(Vote vote)
    {

        List<Vote> votes = voteList(vote);

        if (votes != null && votes.size() > 0){

            List<Long> voteIds = votes.stream().map(Vote::getId).collect(Collectors.toList());

            //投票选项
            List<VoteOption> voteOptions = voteOptionService.getList(voteIds,null);

            Map<Long, List<VoteOption>> map = voteOptions.stream().collect(Collectors.groupingBy(VoteOption::getVoteId));

            votes.stream().forEach(s->{
                s.setVoteOptionList(map.get(s.getId()));
            });
        }


        return votes;
    }

    private List<Vote> voteList(Vote vote){
        List<Vote> votes = voteMapper.selectVoteList(vote);
        return votes;
    }

    @Override
    public VoteCount statistics(Vote vote) {
        List<Vote> votes = voteList(vote);
        List<Long> voteIdList = votes.stream().map(x -> x.getId()).collect(Collectors.toList());
        voteIdList.add(-1L);
        return voteMapper.statistics(voteIdList);
    }

    /**
     * 新增投票活动
     *
     * @param vote 投票活动
     * @return 结果
     */
    @Override
    public int insertVote(Vote vote)
    {

        this.save(vote);

        if (vote.getVoteOptionList() != null && vote.getVoteOptionList().size() > 0) {

            vote.getVoteOptionList().stream().forEach(s->{
                s.setVoteId(vote.getId());
                s.setSort(vote.getVoteOptionList().indexOf(s) + 1);
            });
            //关联选项
            voteOptionService.saveBatch(vote.getVoteOptionList());
        }

        return 1;
    }

    /**
     * 修改投票活动
     *
     * @param vote 投票活动
     * @return 结果
     */
    @Override
    public int updateVote(Vote vote)
    {

        int i = voteMapper.updateVote(vote);

        voteOptionService.remove(new QueryWrapper<VoteOption>().lambda().eq(VoteOption::getVoteId, vote.getId()));

        if (vote.getVoteOptionList() != null && vote.getVoteOptionList().size() > 0) {

            vote.getVoteOptionList().stream().forEach(s->{
                s.setVoteId(vote.getId());
                s.setSort(vote.getVoteOptionList().indexOf(s) + 1);
            });
            //关联选项
            voteOptionService.saveBatch(vote.getVoteOptionList());
        }

        return 1;
    }

    /**
     * 批量删除投票活动
     *
     * @param ids 需要删除的投票活动主键
     * @return 结果
     */
    @Override
    public int deleteVoteByIds(Long[] ids ,Integer delFlag)
    {
        this.lambdaUpdate().set(Vote::getDelFlag,delFlag).in(Vote::getId,ids).update();
        return ids.length;
    }

    /**
     * 删除投票活动信息
     *
     * @param id 投票活动主键
     * @return 结果
     */
    @Override
    public int deleteVoteById(Long id)
    {
        this.lambdaUpdate().set(Vote::getDelFlag,PublicCommon.删除).eq(Vote::getId,id).update();
        return 1;
    }

    @Autowired
    private VoteOptionService voteOptionService;

    @Autowired
    private BusinessUtil businessUtil;

    @Override
    public ResponseData votePage(PageBasic req, UserVo userVo,boolean isSelf) {
        //查询官方头像
        String avatar = businessUtil.getDict(DictConstant.官方头像).getImages();
        Page<VotePageResp> page = voteMapper.votePage(new Page<>(req.getPageNo(),req.getPageSize()),userVo,isSelf);

        if (!page.getRecords().isEmpty()){

            //投票活动ids
            List<Long> voteIds = page.getRecords().stream().map(VotePageResp::getId).collect(Collectors.toList());

            //投票选项
            List<VoteOption> voteOptions = voteOptionService.getList(voteIds,userVo);

            Map<Long, List<VoteOption>> map = voteOptions.stream().collect(Collectors.groupingBy(VoteOption::getVoteId));

            page.getRecords().stream().forEach(vote ->{
                vote.setAvatar(avatar);
                vote.setVoteOptionList(map.get(vote.getId()));
            });
        }

        return ResponseData.success(new PageResult<>(page));
    }

    @Autowired
    private VoteRecordService voteRecordService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData vote(VoteReq req, UserVo userVo) {
        Vote vote = voteMapper.selectById(req.getVoteId());
        //判断投票时间是否在有效期内
        if (vote == null || ObjectUtil.notEqual(PublicCommon.启用,vote.getDelFlag()) || DateUtil.endOfDay(vote.getCutoffDate()).getTime() < System.currentTimeMillis()){
            throw new ServiceException("投票活动已截止");
        }

        //判断用户是否已经投票
        int count = voteRecordService.count(new QueryWrapper<VoteRecord>().lambda()
                .eq(VoteRecord::getDelFlag,PublicCommon.启用)
                .eq(VoteRecord::getVoteId, req.getVoteId())
                .eq(VoteRecord::getUserType,userVo.getUserType())
                .eq(VoteRecord::getUserId, userVo.getUserId()));
        if (count > 0){
            throw new ServiceException("您已经投过票了");
        }

        //生成投票记录
        voteRecordService.addVoteRecord(req.getVoteId(),req.getVoteOptionIds(),userVo);

        return ResponseData.success();
    }

    @Autowired
    private PostMapper postMapper;

    @Override
    public ResponseData voteDetail(Long voteId,Integer isAddBrowseNum, UserVo userVo) {

        //查询官方头像
        String avatar = businessUtil.getDict(DictConstant.官方头像).getImages();

        VoteDetailResp voteDetailResp = voteMapper.voteDetail(voteId,userVo);

        if (voteDetailResp != null){
            //投票选项
            List<VoteOption> voteOptions = voteOptionService.getList(CollectionUtil.toList(voteId),userVo);

            Map<Long, List<VoteOption>> map = voteOptions.stream().collect(Collectors.groupingBy(VoteOption::getVoteId));

            voteDetailResp.setAvatar(avatar);
            voteDetailResp.setVoteOptionList(map.get(voteId));

            //是否增加浏览数 1不增加 2 加
            if (ObjectUtil.equal(2,isAddBrowseNum)) {
                //增加浏览数
                this.baseMapper.updateVote(new Vote().setId(voteId).setBrowseNum(1));

                //type: 类型 1作品 2 帖子 3投票
                postMapper.updateBrowseRecord(SnowIdUtils.uniqueLong(), 3, new Date(), voteId, userVo);
            }
        }

        return ResponseData.success(voteDetailResp);
    }
}
