package com.springbootaws.book.springboot.service.posts;

import com.springbootaws.book.springboot.domain.posts.PostRepository;
import com.springbootaws.book.springboot.domain.posts.Posts;
import com.springbootaws.book.springboot.web.dto.PostResponseDto;
import com.springbootaws.book.springboot.web.dto.PostSaveRequestDto;
import com.springbootaws.book.springboot.web.dto.PostUpdateRequestDto;
import com.springbootaws.book.springboot.web.dto.PostsListResponseDto;
import javafx.geometry.Pos;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
@RequiredArgsConstructor
public class PostsService {
    // 생성자로 PostRepository를 DI받을 수 있도록 해서 확장성을 높임.
    private final PostRepository postRepository;

    @Transactional
    public Long save(PostSaveRequestDto postSaveRequestDto){
        // 결국 요청으로 받는 데이터는 Posts가 아닌 PostSaveRequestDto 형태이다.
            // --> Posts 테이블 정보가 수정되면 PostSaveRequestDto만을 수정하면 됨.
        // postRepository.save()가 저장된 객체를 반환함.
        return postRepository.save(postSaveRequestDto.toEntity()).getId();
    }

    @Transactional
    public Long update(Long id, PostUpdateRequestDto postUpdateRequestDto){
        // jpa의 영속성 컨텍스트 덕분에 entity를 수정하는 것만으로 @Transactional이 종료된 후 변경된 entity값을 반영한다.
        Posts posts = postRepository.findById(id).orElseThrow(()-> new IllegalArgumentException("해당 데이터가 없습니다 id=" + id));
        posts.update(postUpdateRequestDto.getTitle(), postUpdateRequestDto.getContent());
        return id;
    }

    public PostResponseDto findById(Long id){
        Posts posts = postRepository.findById(id).orElseThrow(()->new IllegalArgumentException("해당 데이터 없음 id=" + id));
        return new PostResponseDto(posts);
    }

    @Transactional
    public List<PostsListResponseDto> findAllDesc(){
        return postRepository.findAllDesc().stream()
                .map(PostsListResponseDto::new)// .map(posts -> new PostsListResponseDto(posts))
                .collect(Collectors.toList());
    }

    @Transactional
    public void delete(Long id){
        Posts posts = postRepository.findById(id).orElseThrow(()->new IllegalArgumentException("해당 게시글이 없음 id=" + id));
        postRepository.delete(posts);
    }
}

트랜잭션 주의 사항

FetchType.LAZY
FetchType.EAGER