package sg.ncl.service.user.logic;

import org.springframework.stereotype.Service;
import sg.ncl.service.user.data.jpa.AddressEntity;
import sg.ncl.service.user.data.jpa.UserDetailsEntity;
import sg.ncl.service.user.data.jpa.UserEntity;
import sg.ncl.service.user.data.jpa.UserRepository;
import sg.ncl.service.user.domain.Address;
import sg.ncl.service.user.domain.User;
import sg.ncl.service.user.domain.UserDetails;
import sg.ncl.service.user.exceptions.UserIdNullException;
import sg.ncl.service.user.exceptions.UserNotFoundException;

import javax.inject.Inject;
import javax.transaction.Transactional;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Christopher Zhong
 */
@Service
public class UserService {

    private final UserRepository userRepository;

    @Inject
    protected UserService(final UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public User createUser(User user) {
        final UserEntity userEntity = new UserEntity();
        userEntity.setApplicationDate(user.getApplicationDate());
        userEntity.setProcessedDate(user.getProcessedDate());
        userEntity.setUserDetails((UserDetailsEntity) user.getUserDetails());

        UserEntity savedUserEntity = userRepository.save(userEntity);
        return savedUserEntity;
    }

    @Transactional
    public List<User> getAll() {
        final List<User> result = new ArrayList<>();
        for (UserEntity user : userRepository.findAll()) {
            result.add(user);
        }

        return result;
    }

    @Transactional
    public UserEntity find(final String id) {
        if (id == null || id.isEmpty()) {
            throw new UserIdNullException();
        }

        final UserEntity one = userRepository.findOne(id);
        if (one == null) {
            throw new UserNotFoundException();
        }
        return one;
    }

    @Transactional
    public void update(final String id, final UserDetails user) {
        if (id == null || id.isEmpty()) {
            throw new UserIdNullException();
        }

        final UserEntity one = userRepository.findOne(id);
        if (one == null) {
            throw new UserNotFoundException();
        }

//        final UserDetails user = user.getUserDetails();

        if (user.getFirstName() != null) {
            one.getUserDetails().setFirstName(user.getFirstName());
        }

        if (user.getLastName() != null) {
            one.getUserDetails().setLastName(user.getLastName());
        }

        if (user.getJobTitle() != null) {
            one.getUserDetails().setJobTitle(user.getJobTitle());
        }

        if (user.getEmail() != null) {
            one.getUserDetails().setEmail(user.getEmail());
        }

        if (user.getPhone() != null) {
            one.getUserDetails().setPhone(user.getPhone());
        }

        if (user.getInstitution() != null) {
            one.getUserDetails().setInstitution(user.getInstitution());
        }

        if (user.getInstitutionAbbreviation() != null) {
            one.getUserDetails().setInstitutionAbbreviation(user.getInstitutionAbbreviation());
        }

        if (user.getInstitutionWeb() != null) {
            one.getUserDetails().setInstitutionWeb(user.getInstitutionWeb());
        }

        final Address userAddress = user.getAddress();

        if (userAddress != null) {

            if (userAddress.getAddress1() != null) {
                one.getUserDetails().getAddress().setAddress1(userAddress.getAddress1());
            }

            if (userAddress.getAddress2() != null) {
                one.getUserDetails().getAddress().setAddress2(userAddress.getAddress2());
            }

            if (userAddress.getCountry() != null) {
                one.getUserDetails().getAddress().setCountry(userAddress.getCountry());
            }

            if (userAddress.getCity() != null) {
                one.getUserDetails().getAddress().setCity(userAddress.getCity());
            }

            if (userAddress.getRegion() != null) {
                one.getUserDetails().getAddress().setRegion(userAddress.getRegion());
            }

            if (userAddress.getZipCode() != null) {
                one.getUserDetails().getAddress().setZipCode((userAddress.getZipCode()));
            }
        }

        userRepository.save(one);
    }

    @Transactional
    public void addUserToTeam(final String userId, final String teamId) {

        UserEntity userEntity = find(userId);
        userEntity.addTeamId(teamId);
        userRepository.save(userEntity);
    }
}

@@ -80,59 +80,8 @@
 ce;%0A
-import sg.ncl.service.user.data.jpa.AddressEntity;%0A
 impo
@@ -554,40 +554,8 @@
 al;%0A
-import java.time.ZonedDateTime;%0A
 impo
@@ -1567,16 +1567,20 @@
 ity find
+User
 (final S
@@ -4412,25 +4412,24 @@
 g teamId) %7B%0A
-%0A
         User
@@ -4456,95 +4456,469 @@
 find
-(userId);%0A        userEntity.addTeamId(teamId);%0A        userRepository.save(userEntity)
+AndAddTeam(userId, teamId);%0A        userRepository.save(userEntity);%0A    %7D%0A%0A    private UserEntity findAndAddTeam(final String userId, final String teamId) %7B%0A        if (userId == null %7C%7C userId.isEmpty()) %7B%0A            throw new UserIdNullException();%0A        %7D%0A%0A        final UserEntity one = userRepository.findOne(userId);%0A        if (one == null) %7B%0A            throw new UserNotFoundException();%0A        %7D%0A%0A        one.addTeamId(teamId);%0A        return one
 ;%0A  

refactor addUserToTeam to invoke a private method to get the UserEntity for adding team id