package eu.eudat.logic.services.operations.authentication;

import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.UserInfo;
import eu.eudat.data.entities.UserRole;
import eu.eudat.data.entities.UserToken;
import eu.eudat.logic.builders.model.models.PrincipalBuilder;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.models.data.security.Principal;
import eu.eudat.types.Authorities;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

@Service("nonVerifiedUserAuthenticationService")
public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthenticationService {

	public NonVerifiedUserEmailAuthenticationService(ApiContext apiContext, Environment environment) {
		super(apiContext, environment);
	}

	public Principal Touch(UserToken token) {
		if (token == null || token.getExpiresAt().before(new Date())) return null;

		UserInfo user = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(token.getUser().getId());
		if (user == null) return null;
		String avatarUrl;
		try {
			avatarUrl = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("avatarUrl").asText() : "";
		} catch (Exception e) {
			avatarUrl = "";
		}
		String zenodoToken;
		try {
			zenodoToken = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoToken").asText() : "";
		} catch (Exception e) {
			zenodoToken = "";
		}
		Instant zenodoDuration;
		try {
			zenodoDuration = user.getAdditionalinfo() != null ? Instant.ofEpochMilli(new ObjectMapper().readTree(user.getAdditionalinfo()).get("expirationDate").asLong()) : Instant.now();
		} catch (Exception e) {
			zenodoDuration = Instant.now();
		}
		String zenodoEmail;
		try {
			zenodoEmail = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoEmail").asText() : "";
		} catch (Exception e) {
			zenodoEmail = "";
		}
		String zenodoRefresh;
		try {
			zenodoRefresh = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoRefresh").asText() : "";
		} catch (Exception e) {
			zenodoRefresh = "";
		}
		String culture;
		try {
			culture = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("culture").get("name").asText() : "";
		} catch (Exception e) {
			culture = "";
		}
		String language;
		try {
			language = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("language").get("value").asText() : "";
		} catch (Exception e) {
			language = "";
		}
		String timezone;
		try {
			timezone = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("timezone").asText() : "";
		} catch (Exception e) {
			timezone = "";
		}
		Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class)
				.id(user.getId()).token(token.getToken())
				.expiresAt(token.getExpiresAt())
				.name(user.getName())
				.email(user.getEmail())
				.avatarUrl(avatarUrl)
				.culture(culture)
				.language(language)
				.timezone(timezone)
				.zenodoToken(zenodoToken)
				.zenodoDuration(zenodoDuration)
				.zenodoEmail(zenodoEmail)
				.zenodoRefresh(zenodoRefresh)
				.build();

		List<UserRole> userRoles = apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user);
		for (UserRole item : userRoles) {
			if (principal.getAuthz() == null) principal.setAuthorities(new HashSet<>());
			principal.getAuthz().add(Authorities.fromInteger(item.getRole()));
		}
		return principal;
	}
}
