package gov.va.med.esr.voa.validator;

import gov.va.med.esr.common.model.lookup.Country;
import gov.va.med.esr.common.model.lookup.EmploymentStatus;
import gov.va.med.esr.voa.common.ErrorCode;
import gov.va.med.esr.voa.util.ServiceUtils;
import gov.va.med.esr.voa.webservice.AddressInfo;
import gov.va.med.esr.voa.webservice.EmploymentInfo;
import gov.va.med.fw.util.StringUtils;

import org.springframework.validation.Errors;

/**
 * Validate Employment Information
 */
public class EmploymentInfoValidator extends AbstractValidator {

	@SuppressWarnings("rawtypes")
	@Override
	public boolean supports(Class clazz) {
		return EmploymentInfo.class.equals(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		logger.debug("EmploymentInfo validation...");

		if (target != null) {
			EmploymentInfo employmentInfo = (EmploymentInfo) target;

			String employmentStatus = employmentInfo.getEmploymentStatus();
			if (StringUtils.isBlank(employmentStatus)) {
				if(!this.isNewOMBApprovedForm){
					errors.reject(ErrorCode.VOA_0076,
						"Missing Required Field:  Veteran's employment status.");
				}	
			} else {
				// check reference values VOA_0077
				try {
					getLookupService().getEmploymentStatusByCode(
							employmentStatus);
				} catch (Exception e) {
					errors.reject(ErrorCode.VOA_0077,
							"Invalid employment status.");
					logger.debug("Invalid employment status. status = "
							+ employmentStatus + "\n" + e.getMessage());
				}
			}

			// retired
			if (EmploymentStatus.CODE_RETIRED.getCode().equalsIgnoreCase(
					employmentStatus)) {
				String retirementDate = employmentInfo.getRetirementDate();
				if (StringUtils.isBlank(retirementDate)) {
					errors.reject(ErrorCode.VOA_0078,
							"Missing required field: Veteran date of retirement.");
				} else {
					boolean isValidDate = ServiceUtils
							.validateDate(retirementDate);
					boolean isValidYear = ServiceUtils
							.isValidYear(retirementDate);
					if (isValidDate || isValidYear) {
						boolean isFutureDate = false;
						if (isValidDate) {
							isFutureDate = ServiceUtils
									.isFutureDate(retirementDate);
						} else if (isValidYear) {
							isFutureDate = ServiceUtils
									.isFutureYear(retirementDate);
						}
						if (isFutureDate) {
							errors.reject(ErrorCode.VOA_0079,
									"Invalid date of retirement for Veteran.");
							logger.debug("Invalid date of retirement for Veteran.");
						}
					} else {
						errors.reject(ErrorCode.VOA_0079,
								"Invalid date of retirement for Veteran.");
						logger.debug("Invalid date of retirement for Veteran.");
					}
				}
			} else if (EmploymentStatus.CODE_FULL_TIME.getCode()
					.equalsIgnoreCase(employmentStatus)
					|| EmploymentStatus.CODE_PART_TIME.getCode()
							.equalsIgnoreCase(employmentStatus)) {
				// employed
				String employerName = employmentInfo.getEmployerName();
				if (StringUtils.isBlank(employerName)) {
					errors.reject(ErrorCode.VOA_0080,
							"Missing required field: Name of Veteran's employer.");
				}

				AddressInfo addressInfo = employmentInfo.getEmployerAddress();

				if (addressInfo == null) {
					errors.reject(ErrorCode.VOA_0081,
							"Missing required field: Address of Veteran's employer.");
				} else {
					String line1 = addressInfo.getLine1();
					if (StringUtils.isBlank(line1)) {
						errors.reject(ErrorCode.VOA_0081,
								"Missing required field: Address of Veteran's employer");
					} else if (line1.length() > ServiceUtils.LIMIT_LESS_THAN_30_CHARS) {
						errors.reject(ErrorCode.VOA_0082,
								"Invalid street address for Veteran’s employer");
					}

					String city = addressInfo.getCity();
					if (StringUtils.isBlank(city)) {
						errors.reject(ErrorCode.VOA_0083,
								"Missing required field: City of Veteran's employer.");
					}

					String country = addressInfo.getCountry();
					if (StringUtils.isBlank(country)) {
						errors.reject(ErrorCode.VOA_0244,
								"Missing required field: Country for Veteran's employer.");
						logger.debug("Missing required field: Country for Veteran's employer.");
					} else {
						try {
							getLookupService().getCountryByCode(country);
						} catch (Exception e) {
							errors.reject(ErrorCode.VOA_0228,
									"Invalid country for Veteran's employer.");
							logger.debug("Invalid country for Veteran's employer. "
									+ country + "\n" + e.getMessage());
						}

						String stateProvince = null;
						if (Country.CODE_USA.getCode()
								.equalsIgnoreCase(country)) {
							stateProvince = addressInfo.getState();

							String zipCode = addressInfo.getZipCode();
							if (StringUtils.isBlank(zipCode)) {
								errors.reject(ErrorCode.VOA_0086,
										"Missing required field: Zip Code of Veteran's employer.");
							} else {
								boolean isValid = ServiceUtils
										.validateZip(zipCode);
								if (!isValid) {
									errors.reject(ErrorCode.VOA_0087,
											"Invalid zip code for Veteran's employer.");
								}
							}

							String zipPlus = addressInfo.getZipPlus4();
							if (StringUtils.isNotBlank(zipPlus)) {
								boolean isValid = ServiceUtils
										.validateZipPlus(zipPlus);
								if (!isValid) {
									errors.reject(ErrorCode.VOA_0234,
											"Invalid zip code plus 4 for Veteran's employer.");
								}
							}
						} else if (Country.CODE_CAN.getCode().equalsIgnoreCase(
								country)
								|| Country.CODE_MEX.getCode().equalsIgnoreCase(
										country)) {
							stateProvince = addressInfo.getProvinceCode();
						}

						// only check state of USA or province of CAN & MEX
						if (Country.CODE_USA.getCode()
								.equalsIgnoreCase(country)
								|| Country.CODE_CAN.getCode().equalsIgnoreCase(
										country)
								|| Country.CODE_MEX.getCode().equalsIgnoreCase(
										country)) {
							if (StringUtils.isBlank(stateProvince)) {
								errors.reject(ErrorCode.VOA_0084,
										"Missing required field: State or province for Veteran's employer.");
								logger.debug("Missing required field: State or province for Veteran's employer. ");
							} else {
								// check state is valid from reference data.
								// VOA_0085
								try {
									getLookupService().getStateByCode(
											stateProvince);
								} catch (Exception e) {
									errors.reject(ErrorCode.VOA_0085,
											"Invalid state or province for Veteran's employer.");
									logger.debug("Invalid state or province for Veteran's employer. "
											+ e.getMessage());
								}
							}
						}
					}
				}

				String phoneNumber = employmentInfo.getEmployerPhone();
				if (StringUtils.isNotBlank(phoneNumber)) {
					boolean isValid = ServiceUtils
							.validatePhoneWithExtension(phoneNumber);
					if (!isValid) {
						errors.reject(ErrorCode.VOA_0088,
								"Invalid phone number for  Veteran's employer.");
					}
				}
			}
		}

		logger.debug("EmploymentInfo validation - Done.");
	}
}
