package info.bukova.isspst.data;

import info.bukova.isspst.StringUtils;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
@Table(name="USER")
@Indexed
public class User extends Member implements UserDetails, DataModel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5421234421833765433L;
	
	@Column(name="USERNAME", unique=true)
	private String username;
	@Column(name="PASSWORD")
	private String password;
	@Column(name="ENABLED")
	private boolean enabled;
	@Column(name="FIRST_NAME")
	@Field(index = Index.YES, analyze = Analyze.YES)
	private String firstName;
	@Column(name="LAST_NAME")
	@Field(index = Index.YES, analyze = Analyze.YES)
	private String lastName;
	@Column(name="PERSONAL_NUMBER")
	private String personalNumber;
	@Column(name="EMAIL")
	private String email;
	@Column(name="NOTIFY")
	private boolean notify;
	@ManyToMany(fetch=FetchType.EAGER) 
	@JoinTable(name="USER_ROLE", joinColumns={@JoinColumn(name="USER_ID")}, inverseJoinColumns={@JoinColumn(name="ROLE_ID")})
	private List<Role> authorities;
	@Column(name="SETTINGS", length=1048576)
	private String settings;
	@Embedded
	private UsersAddress address;
		
	public User() {
		authorities = new ArrayList<Role>();
		setParents(new ArrayList<Workgroup>());
		address = new UsersAddress();
	}

	@Override
	public List<Role> getAuthorities() {
		List<Role> roles = new ArrayList<Role>();
		int i = 10000000;
		for (Role r : authorities) {
			roles.add(r);
			for (Permission p : r.getPermissions()) {
				Role role = new Role();
				boolean addRole = true;
				role.setAuthority(p.getAuthority() + "_" + p.getModule());
				role.setId(i);
				++i;
				
				for (Role chRole : roles) {
					if (chRole.getAuthority().equals(role.getAuthority())) {
						addRole = false;
					}
				}
				
				if (addRole) {
					roles.add(role);
				}
			}
		}
		return roles;
	}

	@Override
	public String getPassword() {
		return password;
	}

	@Override
	public String getUsername() {
		return username;
	}

	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Override
	public boolean isEnabled() {
		return enabled;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public void setAuthorities(List<Role> authorities) {
		this.authorities = authorities;
	}
	
	public void addAuthority(Role role) {
		this.authorities.add(role);
	}
	
	public void removeAuthority(Role role) {
		this.authorities.remove(role);
	}

	public String getFullName()
	{
		List<String> list = new ArrayList<String>();

		if (this.lastName != null)
		{
			list.add(this.lastName);
		}

		if (this.firstName != null)
		{
			list.add(this.firstName);
		}

		String result = StringUtils.join(list, " ");
		return result;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getPersonalNumber() {
		return personalNumber;
	}

	public void setPersonalNumber(String personalNumber) {
		this.personalNumber = personalNumber;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public boolean isNotify() {
		return notify;
	}

	public void setNotify(boolean notify) {
		this.notify = notify;
	}
	
	@Override
	public boolean equals(Object o) {
		if ((o instanceof User) && (((User)o).getId() == this.getId())) {
			return true;
		} else {
			return false;
		}
	}
	
	public static boolean isEqualByUserForFilter(User value, User search)
	{
		if ((search == null) || search.getFullName().isEmpty())
		{
			return true;
		}
		else if (value != null)
		{
			String valueS = value.getFullName();
			String searchS = search.getFullName();
			return (valueS.compareTo(searchS) == 0);
		}

		return false;
	}

	@Override
	public String toString() {
		return getFullName();
	}

	@Override
	public boolean isPerson() {
		return true;
	}

	public String getSettings() {
		return settings;
	}

	public void setSettings(String settings) {
		this.settings = settings;
	}

	public UsersAddress getAddress() {
		if (address == null) {
			address = new UsersAddress();
		}
		
		return address;
	}

	public void setAddress(UsersAddress address) {
		this.address = address;
	}

}
