package cn.meowrain.aioj.backend.blogservice.service.impl;

import cn.meowrain.aioj.backend.blogservice.dao.entity.Follow;
import cn.meowrain.aioj.backend.blogservice.dto.req.FollowRequestDTO;
import cn.meowrain.aioj.backend.blogservice.service.FollowService;
import cn.meowrain.aioj.backend.framework.core.exception.ClientException;
import cn.meowrain.aioj.backend.framework.core.utils.ContextHolderUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * 用户关注服务实现类
 *
 * @author AIOJ
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FollowServiceImpl extends ServiceImpl<Follow, Follow> implements FollowService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean followUser(FollowRequestDTO request) {
        Long currentUserId = ContextHolderUtils.getCurrentUserId();

        if (currentUserId.equals(request.getFollowingId())) {
            throw new ClientException("不能关注自己");
        }

        // 检查是否已关注
        Follow existingFollow = this.lambdaQuery()
                .eq(Follow::getFollowerId, currentUserId)
                .eq(Follow::getFollowingId, request.getFollowingId())
                .eq(Follow::getIsCancelled, 0)
                .one();

        if (existingFollow != null) {
            throw new ClientException("已经关注过了");
        }

        // 创建关注记录
        Follow follow = new Follow()
                .setFollowerId(currentUserId)
                .setFollowingId(request.getFollowingId())
                .setIsCancelled(0);
        this.save(follow);

        // TODO: 更新用户统计中的关注数和粉丝数

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean unfollowUser(Long followingId) {
        Long currentUserId = ContextHolderUtils.getCurrentUserId();

        Follow follow = this.lambdaQuery()
                .eq(Follow::getFollowerId, currentUserId)
                .eq(Follow::getFollowingId, followingId)
                .eq(Follow::getIsCancelled, 0)
                .one();

        if (follow == null) {
            throw new ClientException("未关注过该用户");
        }

        follow.setIsCancelled(1);
        follow.setUpdateTime(new Date());
        this.updateById(follow);

        // TODO: 更新用户统计中的关注数和粉丝数

        return true;
    }

    @Override
    public Boolean isFollowing(Long followerId, Long followingId) {
        Follow follow = this.lambdaQuery()
                .eq(Follow::getFollowerId, followerId)
                .eq(Follow::getFollowingId, followingId)
                .eq(Follow::getIsCancelled, 0)
                .one();
        return follow != null;
    }

    @Override
    public IPage<Long> getFollowingList(Long userId, Integer current, Integer size) {
        Page<Follow> page = new Page<>(current, size);
        IPage<Follow> followPage = this.lambdaQuery()
                .eq(Follow::getFollowerId, userId)
                .eq(Follow::getIsCancelled, 0)
                .orderByDesc(Follow::getCreateTime)
                .page(page);

        Page<Long> resultPage = new Page<>(followPage.getCurrent(), followPage.getSize(), followPage.getTotal());
        resultPage.setRecords(followPage.getRecords().stream()
                .map(Follow::getFollowingId)
                .collect(java.util.stream.Collectors.toList()));

        return resultPage;
    }

    @Override
    public IPage<Long> getFollowerList(Long userId, Integer current, Integer size) {
        Page<Follow> page = new Page<>(current, size);
        IPage<Follow> followPage = this.lambdaQuery()
                .eq(Follow::getFollowingId, userId)
                .eq(Follow::getIsCancelled, 0)
                .orderByDesc(Follow::getCreateTime)
                .page(page);

        Page<Long> resultPage = new Page<>(followPage.getCurrent(), followPage.getSize(), followPage.getTotal());
        resultPage.setRecords(followPage.getRecords().stream()
                .map(Follow::getFollowerId)
                .collect(java.util.stream.Collectors.toList()));

        return resultPage;
    }

    @Override
    public Long getFollowingCount(Long userId) {
        return this.lambdaQuery()
                .eq(Follow::getFollowerId, userId)
                .eq(Follow::getIsCancelled, 0)
                .count();
    }

    @Override
    public Long getFollowerCount(Long userId) {
        return this.lambdaQuery()
                .eq(Follow::getFollowingId, userId)
                .eq(Follow::getIsCancelled, 0)
                .count();
    }
}
