package com.tangguo.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tangguo.common.exception.ServiceException;
import com.tangguo.common.mauth.MobileTokenHelper;
import com.tangguo.domain.BbsMoment;
import com.tangguo.domain.bo.CreateMomentBO;
import com.tangguo.domain.dto.BbsMomentListDTO;
import com.tangguo.domain.vo.BbsMomentListVO;
import com.tangguo.domain.vo.BbsUserMomentCountVO;
import com.tangguo.enums.EnableStatus;
import com.tangguo.enums.MomentType;
import com.tangguo.enums.VoteOptionType;
import com.tangguo.mapper.BbsMomentMapper;
import com.tangguo.service.IBbsMomentAttachmentService;
import com.tangguo.service.IBbsMomentService;
import com.tangguo.service.IBbsMomentVoteOptionService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 动态Service业务层处理
 *
 * @author ruoyi
 * @date 2025-09-01
 */
@Service
public class BbsMomentServiceImpl extends ServiceImpl<BbsMomentMapper, BbsMoment> implements IBbsMomentService {

    @Resource
    private BbsMomentMapper bbsMomentMapper;

    @Resource
    private IBbsMomentAttachmentService attachmentsService;

    @Resource
    private IBbsMomentVoteOptionService voteOptionService;


    /**
     * 查询动态列表
     *
     * @param moment 动态
     * @return 动态
     */
    @Override
    public List<BbsMoment> selectBbsMomentList(BbsMoment moment) {
	    return this.baseMapper.selectBbsMomentList(moment);
    }


    /**
     * 删除动态
     *
     * @param id 动态Id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteMoment(Long id) {
        this.removeById(id);
    }


    /**
     * 查询用户动态统计
     *
     * @return 动态统计
     */
    @Override
    public BbsUserMomentCountVO getUserMomentCount(String userName) {
        return this.baseMapper.selectUserMomentCount(userName);
    }


    /**
     * 查询动态列表
     *
     * @param userName 用户名
     * @param content  动态内容
     * @return 动态列表
     */
    @Override
    public List<BbsMomentListVO> getUserMoments(String userName, String content) {
        List<BbsMomentListDTO> dbMoments = this.baseMapper.selectUserMoments(userName, content);
        return this.buildMomentListVO(dbMoments);
    }


    /**
     * 查询动态列表
     *
     * @param userName 用户名
     * @param content  动态内容
     * @return 动态列表
     */
    @Override
    public List<BbsMomentListVO> getMoments(String userName, String content) {
        List<BbsMomentListDTO> dbMoments = this.baseMapper.selectMoments(userName, content);
        return this.buildMomentListVO(dbMoments);
    }


    /**
     * 创建动态
     *
     * @param bo 动态
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void userCreateMoment(CreateMomentBO bo) {
        // 添加动态
        String username = MobileTokenHelper.getUsername();
        BbsMoment newMoment = this.buildMoment(bo);
        newMoment.setUserName(username);
        this.save(newMoment);

        // 添加动态投票选项
        if (EnableStatus.QY.getStatus() == bo.getIsEnableVote()) {
            List<CreateMomentBO.VoteOption> voteOptions = bo.getVoteOptions();
            this.voteOptionService.addVoteOptions(newMoment.getId(), voteOptions);
        }
    }


    /**
     * 删除动态
     *
     * @param momentId 动态Id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void userDeleteMoment(Long momentId) {
        String username = MobileTokenHelper.getUsername();
        BbsMoment dbMoment = this.getOne(
            Wrappers.lambdaQuery(BbsMoment.class)
                .select(BbsMoment::getId).eq(BbsMoment::getUserName, username).eq(BbsMoment::getId, momentId)
        );
        if (Objects.isNull(dbMoment)) {
            throw new ServiceException("删除失败，未查询到当前动态数据。");
        }

        this.removeById(dbMoment.getId());
    }


    /**
     * 构建动态实体
     *
     * @param bo 动态
     * @return 动态实体
     */
    private BbsMoment buildMoment(CreateMomentBO bo) {
        final String separator = "|";

        // 动态类型
        MomentType momentType = MomentType.getMomentType(bo.getType());
        if (Objects.isNull(momentType)) {
            throw new ServiceException("发布失败，动态类型错误。");
        }

        // 动态附件
        List<String> attachmentUrls = bo.getAttachmentUrls();
        String linkUrl = bo.getLinkUrl();
        if (MomentType.IMAGE == momentType || MomentType.VIDEO == momentType) {
            if (CollUtil.isEmpty(attachmentUrls)) {
                throw new ServiceException("发布失败，动态附件不能为空。");
            }
        }
        else if (MomentType.URL == momentType) {
            if (StrUtil.isBlank(linkUrl)) {
                throw new ServiceException("发布失败，动态链接不能为空。");
            }
        }

        BbsMoment newMoment = new BbsMoment();
        newMoment.setType(momentType.name());
        newMoment.setContent(bo.getContent());
        newMoment.setLinkUrl(linkUrl);
        newMoment.setAttachmentUrls(String.join(separator, attachmentUrls));
        newMoment.setIsEnableComment(bo.getIsEnableComment());
        newMoment.setIsEnableFeaturedComment(bo.getIsEnableFeaturedComment());

        // 动态主题
        List<String> topicNames = bo.getTopicNames();
        List<String> topicIds = bo.getTopicIds();
        if (CollUtil.isNotEmpty(topicNames) && CollUtil.isNotEmpty(topicIds)) {
            newMoment.setTopicIds(String.join(separator, topicIds));
            newMoment.setTopicNames(String.join(separator, topicNames));
        }

        // 动态投票
        Integer isEnableVote = bo.getIsEnableVote();
        newMoment.setIsEnableVote(isEnableVote);
        if (EnableStatus.QY.getStatus() == isEnableVote) {
            VoteOptionType optionType = VoteOptionType.getVoteOptionType(bo.getVoteOptionType());
            if (Objects.isNull(optionType)) {
                throw new ServiceException("发布失败，动态投票选项类型错误。");
            }

            List<CreateMomentBO.VoteOption> options = bo.getVoteOptions();
            if (CollUtil.isEmpty(options)) {
                throw new ServiceException("发布失败，动态投票选项不能为空。");
            }

            for (int i = 0; i < options.size(); i++) {
                CreateMomentBO.VoteOption option = options.get(i);
                long optionCount = options.stream().filter(o -> o.getName().equals(option.getName())).count();
                if (optionCount > 1) {
                    throw new ServiceException("发布失败，动态投票选项重复。");
                }
                int optionIndex = i + 1;
                option.setType(optionType.name());
                option.setCode(String.valueOf(optionIndex));
                option.setSort(optionIndex);
            }

            newMoment.setVoteTitle(bo.getVoteTitle());
            newMoment.setVoteOptionType(optionType.name());
            newMoment.setVoteOptions(JSONUtil.toJsonStr(options));
        }
        return newMoment;
    }


    /**
     * 构建动态列表
     *
     * @param dbMoments 动态
     * @return 动态列表
     */
    private List<BbsMomentListVO> buildMomentListVO(List<BbsMomentListDTO> dbMoments) {
        List<BbsMomentListVO> moments = new ArrayList<>(dbMoments.size());
        for (BbsMomentListDTO dbMoment : dbMoments) {
            BbsMomentListVO moment = new BbsMomentListVO();
            moment.setCreateTime(dbMoment.getCreateTime());
            moment.setId(dbMoment.getId());
            moment.setUserName(dbMoment.getUserName());
            moment.setContent(dbMoment.getContent());
            moment.setType(dbMoment.getType());

            String topicNames = dbMoment.getTopicNames();
            if (StrUtil.isNotBlank(topicNames)) {
                moment.setTopicNames(Arrays.asList(topicNames.split("\\|")));
            }
            String topicIds = dbMoment.getTopicIds();
            if (StrUtil.isNotBlank(topicNames)) {
                moment.setTopicIds(Arrays.asList(topicIds.split("\\|")));
            }

            String attachmentUrls = dbMoment.getAttachmentUrls();
            if (StrUtil.isNotBlank(attachmentUrls)) {
                moment.setAttachmentUrls(Arrays.asList(attachmentUrls.split("\\|")));
            }

            moment.setLinkUrl(dbMoment.getLinkUrl());
            moment.setIsEnableComment(dbMoment.getIsEnableComment());
            moment.setIsEnableFeaturedComment(dbMoment.getIsEnableFeaturedComment());
            moment.setIsEnableVote(dbMoment.getIsEnableVote());
            moment.setVoteTitle(dbMoment.getVoteTitle());
            moment.setVoteOptionType(dbMoment.getVoteOptionType());
            moment.setVoteOptions(dbMoment.getVoteOptions());
            moment.setLikeCount(dbMoment.getLikeCount());
            moment.setCommentCount(dbMoment.getCommentCount());
            moment.setVoteCount(dbMoment.getVoteCount());
            moment.setIsLike(dbMoment.getIsLike());
            moment.setIsVote(dbMoment.getIsVote());
            moment.setIsSelf(dbMoment.getIsSelf());
            moments.add(moment);
        }
        return moments;
    }

}
