package cz.muni.fi.pa165.core.user;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.regex.Pattern;

import static org.assertj.core.api.Assertions.assertThat;

@ExtendWith(SpringExtension.class)
@DataJpaTest
public class UserRepositoryTest {
	@Autowired
	private TestEntityManager entityManager;
	@Autowired
	private UserRepository userRepository;


	@Test
	void createTesting() {
		String user = entityManager.persistAndGetId(User.builder().username("usr01").build()).toString();
		// Regular expression to match UUID format
		Pattern uuidPattern = Pattern.compile(
				"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
				Pattern.CASE_INSENSITIVE);
		// Check if the string matches the UUID format
		boolean isUUID = uuidPattern.matcher(user).matches();
		assertThat(isUUID).isTrue();
	}

	@Test
	public void shouldFindNoneIfRepositoryIsEmpty() {
		Iterable<User> users = userRepository.findAll();
		assertThat(users).isEmpty();
	}

	@Test
	public void shouldStore() {
		User user = helperRegister();

		assertThat(user).hasFieldOrPropertyWithValue("username", "xuser1");
	}

	@Test
	void shouldFindAll() {
		User user = User.builder().username("usr01").build();
		entityManager.persist(user);

		User user1 = User.builder().username("usr02").build();
		entityManager.persist(user1);

		assertThat(userRepository.findAll()).hasSize(2).contains(user, user1);
	}

	@Test
	void shouldFindById() {
		User user = User.builder().username("usr01").build();
		entityManager.persist(user);

		User user1 = User.builder().username("usr02").build();
		entityManager.persist(user1);

		User found = userRepository.findById(user.getId()).get();

		assertThat(found).isEqualTo(user);

		found = userRepository.findById(user1.getId()).get();

		assertThat(found).isEqualTo(user1);
	}

	@Test
	void shouldUpdateById() {
		User user = User.builder().username("usr01").build();
		entityManager.persist(user);

		User user1 = User.builder().username("usr02").build();
		entityManager.persist(user1);

		User update = userRepository.findById(user.getId()).get();
		update.setUsername("xfazlag");
		userRepository.save(update);

		User check = userRepository.findById(user.getId()).get();

		assertThat(check.getId()).isEqualTo(user.getId());
		assertThat(check.getUsername()).isEqualTo(user.getUsername());
	}

	@Test
	void shouldDeleteById() {
		User user = User.builder().username("usr01").build();
		entityManager.persist(user);

		User user1 = User.builder().username("usr02").build();
		entityManager.persist(user1);

		userRepository.deleteById(user1.getId());

		assertThat(userRepository.findAll()).hasSize(1).contains(user);
		assertThat(userRepository.findAll()).hasSize(1).doesNotContain(user1);
	}

	@Test
	void shouldDeleteAll() {
		entityManager.persist(helperRegister());

		userRepository.deleteAll();

		assertThat(userRepository.findAll()).isEmpty();
	}

	private User helperRegister() {
		User m = User.builder().username("usr").build();
		userRepository.save(m);
		return userRepository.save(new User("xuser1", UserType.NORMAL, "password", "abc@gmail.com", "Anesa", "Fazlagic", null));
	}
}


