package br.com.rayankonecny.userserviceapi.service;

import java.util.List;

import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;

import br.com.rayankonecny.userserviceapi.entity.User;
import br.com.rayankonecny.userserviceapi.mapper.UserMapper;
import br.com.rayankonecny.userserviceapi.repository.UserRepository;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import models.responses.UserResponse;
import models.exceptions.ResourceNotFoundException;
import models.requests.CreateUserRequest;
import models.requests.UpdateUserRequest;

@Service
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;
    private final UserMapper userMapper;

    public UserResponse findById(final String id) {
        return userMapper.fromEntity(find(id));
    }

    public void save(CreateUserRequest createUserRequest) {
        verifyIfEmailAlreadyEexists(createUserRequest.email(), null);
        userRepository.save(userMapper.fromRequest(createUserRequest));
    }

    private void verifyIfEmailAlreadyEexists(final String email, final String id) {
        userRepository.findByEmail(email).filter(user -> !user.getId().equals(id)).ifPresent(user -> {
            throw new DataIntegrityViolationException("Email [" + email + "] already exists");
        });
    }

    public List<UserResponse> findAll() {
        return userRepository.findAll().stream().map(user -> userMapper.fromEntity(user)).toList();
    }

    public UserResponse update(final String id, @Valid final UpdateUserRequest updateUserRequest) {
        User entity = find(id);
        verifyIfEmailAlreadyEexists(updateUserRequest.email(), id);
        return userMapper.fromEntity(userRepository.save(userMapper.update(updateUserRequest, entity)));
    }

    private User find(final String id) {
        return userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(
                "Object not found! Id: " + id + ", Type: " + UserResponse.class.getSimpleName()));

    }
}