package com.pingcap.community.blogserver.service;

import com.pingcap.community.blogserver.entity.Like;
import com.pingcap.community.blogserver.entity.Post;
import com.pingcap.community.blogserver.entity.User;
import com.pingcap.community.blogserver.enums.PostStatus;
import com.pingcap.community.blogserver.exception.post.PostHasBeenLiked;
import com.pingcap.community.blogserver.exception.post.PostHasNotBeenLiked;
import com.pingcap.community.blogserver.exception.post.PostNotPublished;
import com.pingcap.community.blogserver.repository.LikeRepository;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.Date;
import java.util.Optional;

@AllArgsConstructor
@Service
public class LikeService {

  private final LikeRepository likeRepository;

  public Page<Like> getUserLikes(Long userID, Pageable pageable) {
    return likeRepository.findAllByKey_UserID(userID, pageable);
  }

  public Page<Like> getUserLikesByUsername(String username, Pageable pageable) {
    return likeRepository.findLikedPostsByUsername(username, pageable);
  }

  @Transactional
  public Like likePost(Post post, User operator) throws PostNotPublished, PostHasBeenLiked {
    if (post.getStatus() != PostStatus.PUBLISHED) {
      throw new PostNotPublished();
    }

    Like.LikeKey key = new Like.LikeKey(post.getId(), operator.getId());
    boolean liked = likeRepository.existsById(key);
    if (liked) {
      throw new PostHasBeenLiked();
    }

    Like like = new Like(key);
    like.setLikedAt(new Date());
    return likeRepository.save(like);
  }

  @Transactional
  public void unlikePost(Post post, User operator) throws PostNotPublished, PostHasNotBeenLiked {
    if (post.getStatus() != PostStatus.PUBLISHED) {
      throw new PostNotPublished();
    }

    Like.LikeKey key = new Like.LikeKey(post.getId(), operator.getId());
    boolean liked = likeRepository.existsById(key);
    if (!liked) {
      throw new PostHasNotBeenLiked();
    }

    likeRepository.deleteById(key);
  }

}
