package org.lym.pom.service.impl;

import org.lym.pom.notify.publisher.EventPublisher;
import org.lym.pom.repository.mongo.Follow;
import org.lym.pom.service.FollowService;
import org.shoulder.core.dto.request.BasePageQuery;
import org.shoulder.core.dto.response.PageResult;
import org.shoulder.core.exception.CommonErrorCodeEnum;
import org.shoulder.core.util.AssertUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * 订阅推送服务
 *
 * @author lym
 */
@Service
public class FollowServiceImpl implements FollowService {

    private final EventPublisher eventPublisher;

    private final MongoTemplate mongoTemplate;

    public FollowServiceImpl(EventPublisher eventPublisher, MongoTemplate mongoTemplate) {
        this.eventPublisher = eventPublisher;
        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public boolean isFollow(String fansUserId, String followeeUserId) {
        Query query = Query.query(Criteria.where("userId").is(fansUserId)
                .and("followeeUserId").is(followeeUserId));
        return mongoTemplate.exists(query, Follow.class);
    }

    @Override
    public void follow(String fansUserId, String followeeUserId) {
        // todo 检查用户存在

        Follow follow = new Follow();
        follow.setUserId(fansUserId);
        follow.setFolloweeUserId(followeeUserId);
        follow.setCreateTime(System.currentTimeMillis());
        mongoTemplate.save(follow);
    }

    @Override
    public void unfollow(String fansUserId, String followeeUserId) {
        Query query = Query.query(Criteria.where("userId").is(fansUserId)
                .and("followeeUserId").is(followeeUserId));
        mongoTemplate.remove(query, Follow.class);
    }

    @Override
    public PageResult<Follow> pageQueryFollows(BasePageQuery<Follow> pageQuery) {
        AssertUtils.notNull(pageQuery.getCondition(), CommonErrorCodeEnum.ILLEGAL_PARAM);
        AssertUtils.notBlank(pageQuery.getCondition().getUserId(), CommonErrorCodeEnum.ILLEGAL_PARAM);
        return pageQuery(pageQuery, Criteria.where("userId").is(pageQuery.getCondition().getUserId()));
    }

    private PageResult<Follow> pageQuery(BasePageQuery<Follow> pageQuery, Criteria criteria) {

        Query query = new Query(criteria)
                .skip((long) (pageQuery.getPageNo() - 1) * pageQuery.getPageSize())
                .limit(pageQuery.getPageSize())
                .with(Sort.by(Order.asc("createTime")));
        List<Follow> list = mongoTemplate.find(query, Follow.class);
        if (CollectionUtils.isEmpty(list)) {
            return PageResult.empty(pageQuery.getPageNo(), pageQuery.getPageSize());
        }
        long total = mongoTemplate.count(new Query(criteria), Follow.class);

        return PageResult.build(list, pageQuery.getPageNo(), pageQuery.getPageSize(), total);
    }

    @Override
    public PageResult<Follow> pageQueryFollowed(BasePageQuery<Follow> pageQuery) {
        AssertUtils.notNull(pageQuery.getCondition(), CommonErrorCodeEnum.ILLEGAL_PARAM);
        AssertUtils.notBlank(pageQuery.getCondition().getFolloweeUserId(), CommonErrorCodeEnum.ILLEGAL_PARAM);
        return pageQuery(pageQuery, Criteria.where("followeeUserId").is(pageQuery.getCondition().getFolloweeUserId()));
    }

    @Override
    public long countFollowNumber(String fansUserId) {
        return mongoTemplate.count(new Query(Criteria.where("userId").is(fansUserId)), Follow.class);
    }

    @Override
    public long countFansNumber(String followeeUserId) {
        return mongoTemplate.count(new Query(Criteria.where("followeeUserId").is(followeeUserId)), Follow.class);
    }
}
