import {AbstractControl, FormControl, ValidatorFn} from '@angular/forms';

export class CustomValidators {
	static isNullOrUndefined<T>(obj: T | null | undefined): obj is null | undefined {
		return typeof obj === 'undefined' || obj === null;
	}

	static email2(control: FormControl): any {
		const exp: any = /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'email': true, 'currentValue': control.value};
		}
		return null;
	}

	static password(control: FormControl): any {
		const exp: any = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*)[A-Za-z0-9\d$]{8,16}$/;
		if (!(typeof control.value === 'undefined' || control.value === null) && control.value !== "" && !exp.test(control.value)) {
			return {'password': true, 'currentValue': control.value};
		}
		return null;
	}

	static fechamx(control: FormControl): any {
		// let exp: any = /^(d{1,2})[/](d{1,2})[/](d{2}|d{4})$/; // Basic validation
		const exp: any = /^(?:(0[1-9]|[12][0-9]|3[01])[\/.](0[1-9]|1[012])[\/.](19|20)[0-9]{2})$/;
		return exp.test(control.value) ? null : {
			fechamx: {
				valid: true
			}
		};
	}

	static fechaus(control: FormControl): any {
		// let exp: any = /^(d{1,2})[/](d{1,2})[/](d{2}|d{4})$/; // Basic validation
		const exp: any = /^(?:(19|20)[0-9]{2}[\-.](0[1-9]|1[012])[\-.](0[1-9]|[12][0-9]|3[01]))$/;
		return exp.test(control.value) ? null : {
			fechaus: {
				valid: true
			}
		};
	}

	static telefono2(control: FormControl): any {
		const exp: any = /^\+\d{2,3}\s\d{10}$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'telefono': true, 'currentValue': control.value};
		}
		return null;
	}

	static formatoNumero(control: FormControl): any {
		const exp: any = /^[0-9]+$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'formatoNumero': true, 'currentValue': control.value};
		}
		return null;
	}

	static formatoDecimal(control: FormControl): any {
		const exp: any = /^(\d+\.?\d{0,9}|\.\d{1,9})$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'formatoDecimal': true, 'currentValue': control.value};
		}
		return null;
	}

	static formatoHora(control: FormControl): any {
		const exp: any = /^(?:[01]\d|2[0123]):(?:[012345]\d):(?:[012345]\d)$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'formatoHora': true, 'currentValue': control.value};
		}
		return null;
	}

	static email(control: FormControl): any {
		const exp: any = /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'email': true, 'currentValue': control.value};
		}
		return null;
	}

	static urlYoutube(control: FormControl): any {
		const exp: any = /^(https:\/\/(www.)?youtube.com\/embed\/)/;

		if (control.value && !exp.test(control.value)) {
			return {'deUrl': true, 'currentValue': control.value};
		}
		return null;
	}

	static urlSpotify(control: FormControl): any {
		const exp: any = /^(https:\/\/open.spotify.com\/embed\/)/;

		if (control.value && !exp.test(control.value)) {
			return {'deUrl': true, 'currentValue': control.value};
		}
		return null;
	}

	static telefono(control: FormControl): any {
		const exp: any = /^\+\d{2,3}\s\d{10}$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'telefono': true, 'currentValue': control.value};
		}
		return null;
	}

	static numeric(control: FormControl): any {
		const exp: any = /^[0-9]+$/;
		if (control.value && !exp.test(control.value)) {
			return {'numeric': true, 'currentValue': control.value};
		}
		return null;
	}

	static deUrl(control: FormControl): any {
		const exp: any = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'deUrl': true, 'currentValue': control.value};
		}
		return null;
	}

	static deUrlImagen(control: FormControl): any {
		const exp: any = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'deUrlImagen': true, 'currentValue': control.value};
		}
		return null;
	}

	// VALIDA QUE LA CONTRASEÑA NO CONTENGA ESPACIOS
	static noWhiteSpace(control: FormControl): any {
		const exp: any = /^\S+$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'nowhitespace': true, 'currentValue': control.value};
		}
		return null;
	}

	// VALIDA QUE EL USUARIO NO CONTENGA ESPACIOS
	static nbUsuario(control: FormControl): any {
		const exp: any = /^\S+$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'nbUsuario': true, 'currentValue': control.value};
		}
		return null;
	}

	// VALIDA QUE LA CONTRASEÑA NO CONTENGA ESPACIOS
	static dePassword(control: FormControl): any {
		const exp: any = /^\S+$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'dePassword': true, 'currentValue': control.value};
		}
		return null;
	}

	static precio(control: FormControl): any {
		const exp: any = /^([0-9])*[.]?[0-9]*$/;
		if (control.value !== undefined && !exp.test(control.value)) {
			return {'precio': true, 'currentValue': control.value};
		}
		return null;
	}


	static preciomayor0(control: FormControl): any {
		const exp: any = /^([0-9])*[.]?[0-9]*$/;
		if (parseInt(control.value) == 0) {
			return {'precio': true, 'currentValue': control.value};
		}
		if (control.value !== undefined && !exp.test(control.value) && parseInt(control.value) == 0) {
			return {'precio': true, 'currentValue': control.value};
		}
		return null;
	}

	static minValue(min: Number): ValidatorFn {
		return (control: AbstractControl): { [key: string]: any } => {
			const input = control.value,
				isValid = input < min;
			if (isValid) {
				return {'minValue': {min}};
			} else {
				return null;
			}
		};
	}
}
