package gov.va.vss.model.volunteer;

import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;

import java.time.LocalDate;

import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonView;

import gov.va.shared.model.lookup.sds.Gender;
import gov.va.shared.model.lookup.sds.State;
import gov.va.vss.model.volunteer.Volunteer.VolunteerView;

@MappedSuperclass
@JsonAutoDetect(fieldVisibility = NONE, getterVisibility = PUBLIC_ONLY, isGetterVisibility = PUBLIC_ONLY)
public abstract class AbstractVolunteer<T extends AbstractVolunteer<T>> extends AbstractSimpleVolunteer<T> {
	private static final long serialVersionUID = 3222064615857480112L;

	// -------------------------------------- Fields

	@NotNull(message = "Please enter a gender.")
	private Gender gender;

	@NotNull(message = "Please select a state.")
	private State state;

	// -------------------------------------- Constructors

	protected AbstractVolunteer() {
	}

	protected AbstractVolunteer(Long id, String lastName, String firstName, String middleName, String nameSuffix) {
		super(id, lastName, firstName, middleName, nameSuffix);
	}

	protected AbstractVolunteer(Long id, String identifyingCode, String lastName, String firstName, String middleName,
			String nameSuffix, LocalDate dateOfBirth, int age, boolean youth, String nickname, Gender gender,
			String addressLine1, String addressLine2, String city, State state, String zip, String phone,
			String phoneAlt, String phoneAlt2, String email, String emergencyContactName,
			String emergencyContactRelationship, String emergencyContactPhone, String emergencyContactPhoneAlt) {
		super(id, identifyingCode, lastName, firstName, middleName, nameSuffix, dateOfBirth, age, youth, nickname,
				addressLine1, addressLine2, city, zip, phone, phoneAlt, phoneAlt2, email, emergencyContactName,
				emergencyContactRelationship, emergencyContactPhone, emergencyContactPhoneAlt);
		this.state = state;
		this.gender = gender;
	}

	// -------------------------------------- Business Methods

	@Override
	@Transient
	protected String getStateString() {
		return getState() == null ? null : getState().getPostalName();
	}

	@Override
	@Transient
	protected Long getStateId() {
		return nullSafeGetId(getState());
	}

	// -------------------------------------- Common Methods

	// -------------------------------------- Accessor Methods

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "STD_GenderFK")
	@JsonView(VolunteerView.Search.class)
	public Gender getGender() {
		return gender;
	}

	public void setGender(Gender gender) {
		this.gender = gender;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "STD_StateFK", nullable = false)
	@JsonView(VolunteerView.Extended.class)
	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

}
