package com.devjob.service;

import com.devjob.domain.Member;
import com.devjob.domain.Role;
import com.devjob.dto.MemberJoinRequest;
import com.devjob.dto.MemberResponse;
import com.devjob.exception.BusinessException;
import com.devjob.exception.ErrorCode;
import com.devjob.repository.MemberRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * EP10: MemberRepository를 사용하는 서비스 계층.
 * 클래스 레벨 @Transactional(readOnly = true)로 조회 성능을 최적화하고,
 * 쓰기 메서드에는 별도로 @Transactional을 붙인다.
 *
 * 회원가입 API(이메일 중복 체크 + BCrypt 암호화)는 EP15에서 구현한다.
 */
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberService {

    private final MemberRepository memberRepository;
    private final PasswordEncoder passwordEncoder;

    public Member findById(Long id) {
        return memberRepository.findById(id)
                .orElseThrow(() -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND));
    }

    public List<Member> findByRole(Role role) {
        return memberRepository.findByRoleOrderByCreatedAtDesc(role);
    }

    @Transactional
    public Member register(Member member) {
        if (memberRepository.existsByEmail(member.getEmail())) {
            throw new BusinessException(ErrorCode.DUPLICATE_EMAIL);
        }
        return memberRepository.save(member);
    }

    /**
     * EP15: 이메일 중복 체크 + BCrypt 비밀번호 암호화 후 회원가입.
     */
    @Transactional
    public MemberResponse join(MemberJoinRequest req) {
        if (memberRepository.existsByEmail(req.email())) {
            throw new BusinessException(ErrorCode.DUPLICATE_EMAIL);
        }

        Member member = Member.builder()
                .email(req.email())
                .password(passwordEncoder.encode(req.password()))
                .role(Role.USER)
                .build();

        return MemberResponse.from(memberRepository.save(member));
    }
}
