/*
	Created by Michael Schuijff <michael@reglobe.nl>
	Copyright Lost Images, The Netherlands
	
	For more information, visit www.michaelschuijff.nl
*/

function isValidUsername (username) {
	let regex = /^[\w\-\._]{3,50}$/;
	return regex.test(username);
}

function isValidEmail (email) {
	let regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i;
	return regex.test(email);
}

function isValidURL (url) {
	try {
		let test = new URL(url);
		
		if (!(test.protocol == 'http:' || test.protocol == 'https:')) {
			return false;
		}
	} catch (e) {
		return false;
	}
	
	return true;
}

function isYouTubeVideo (url) {
	let regex = /^https?:\/\/(?:m\.|www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([A-Za-z0-9\-_]+)$/
		, match = url.match(regex);
	
	if (!match) {
		return null;
	}
	
	return match[1];
}

function isYouTubeChannel (url) {
	let regex = /^https?:\/\/(?:www\.|m\.|studio\.)?youtube\.com\/(?:user\/|channel\/|@)([^\/?#]+)(?:\/.*)?$/;
	return regex.test(url);
}

function isValidDatetime (datetime) {
	return !!formatDatetime(datetime);
}

function isValidDate (date) {
	if (typeof date == 'string' && ~date.indexOf(' ')) {
		return false;
	}
	
	return !!formatDate(date);
}

function formatNumber (number, zero) {
	number = +number || 0;
	
	if (number > 1000) {
		number = (number / 100 | 0) / 10 + 'K';
	}
	
	if (zero == undefined) {
		zero = '';
	}
	
	return number || zero;
}

function toDate (date, utc) {
	if (date instanceof Date) {
		if (utc) {
			date = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
		} else {
			date = +date;
		}
		
		return new Date(date);
	}

	if (isValidDate(date)) {
		let split = formatDate(date).split('-');
		
		if (utc) {
			return new Date(Date.UTC(+split[2], +split[1] - 1, +split[0]));
		}
		
		return new Date(+split[2], +split[1] - 1, +split[0]);
	}
	
	if (isValidDatetime(date)) {
		let split = formatDatetime(date).split(/[\-:\s]/);
		
		if (utc) {
			return new Date(Date.UTC(split[2], split[1] - 1, split[0], split[3], split[4]));
		}
		
		return new Date(split[2], split[1] - 1, split[0], split[3], split[4]);
	}

	return false;
}
 
function formatDatetime (datetime) {
	if (datetime instanceof Date) {
		return formatDate(datetime) + ' ' + formatTime(datetime);
	}
	
	if (typeof datetime != 'string') {
		return false;
	}
	
	let split = datetime.trim().split(/\s+/);

	let date = formatDate(split[0]), time = formatTime(split[1]);
		
	if (!date || !time) {
		return false;
	}
	
	return date + ' ' + time;
}

function formatDate (date) {
	if (date instanceof Date) {
		return date.getDate() + ' ' + (date.getMonth() + 1) + ' ' + date.getFullYear();
	}
	
	if (typeof date != 'string') {
		return false;
	}
	
	date = date.trim();
	
	if (~date.indexOf('.')) {
		date = date.replace(/\./g, '-');
	}
	
	let day, month, year;
	
	if (~date.indexOf('-')) {
		let split = date.split('-');
		
		if (split.length != 3) {
			return false;
		}
		
		if (split[0].length == 4) {
			split = split.reverse();
		}
		
		day = +split[0] || 0, month = +split[1] || 0, year = +split[2] || 0;
	} else {
		let split = date.split('/');
		
		if (split.length != 3) {
			return false;
		}
		
		if (split[0].length == 4) {
			year = +split[0] || 0, month = +split[1] || 0, day = +split[2] || 0;
		} else {
			month = +split[0] || 0, day = +split[1] || 0, year = +split[2] || 0;
		}
	}
	
	if (year >= 0 && year < 100) {
		year += 2000;
	}
	
	if (year < 1800 || year > 2099 || month < 1 || month > 12) {
		return false;
	}
	
	if (day > new Date(year, month, 0).getDate()) {
		return false;
	}
	
	return day + '-' + month + '-' + year;
}
	
function formatDateYMD (date) {
	date = formatDate(date);
	
	if (!date) {
		return false;
	}
	
	return date.split('-').reverse().join('-');
}
	
function formatDateUTC (date, format) {
	if (typeof date == 'string') {
		date = toDate(date);
	}
	
	if (!(date instanceof Date)) {
		return false;
	}
	
	if (format == 'date') {
		return ('' + date.getUTCFullYear()) + '-' + ('' + (date.getUTCMonth() + 1)).padStart(2, '0') + '-' + ('' + date.getUTCDate()).padStart(2, '0');
	}
	
	if (format == 'time') {
		return ('' + date.getUTCHours()).padStart(2, '0') + ':' + ('' + date.getUTCMinutes()).padStart(2, '0') + ':' + ('' + date.getUTCSeconds()).padStart(2, '0');
	}
	
	return formatDateUTC(date, 'date') + ' ' + formatDateUTC(date, 'time');
}

function formatDateLocal (date, format, suffix) {
	if (typeof date == 'string') {
		date = new Date(date);
	}
	
	if (format == 'date') {
		return date.getDate() + '-' + (date.getMonth() + 1) + '-' + date.getFullYear();
	}
	
	if (format == 'time') {
		return date.getHours() + ':' + ('' + date.getMinutes()).padStart(2, '0');
	}
	
	if (format == 'datetime') {
		return formatDateLocal(date, 'date') + ' ' + formatDateLocal(date, 'time');
	}
	
	if (format == 'readable') {
		let diff = (+new Date - +date) / 1000 | 0;
		
		if (suffix) {
			suffix = ' ' + suffix;
		} else {
			suffix = '';
		}
		
		if (diff < 15) {
			return __('Just now');
		} 
		
		if (diff < 60) {
			if (diff > 1) {
				return __('%d seconds', diff) + suffix;
			}
			
			return __('1 second') + suffix;
		}
		
		if (diff < 3600) {
			let minutes = diff / 60 | 0;
			
			if (minutes > 1) {
				return __('%d minutes', minutes) + suffix;
			}
			
			return __('1 minute') + suffix;
		}
		
		if (diff < 86400) {
			let hours = diff / 3600 | 0;
			
			if (hours > 1) {
				return __('%d hours', hours) + suffix;
			}
			
			return __('1 hour') + suffix;
		}
		
		if (diff < 604800) {
			let days = diff / 86400 | 0;
			
			if (days > 1) {
				return __('%d days', days) + suffix;
			}
			
			return __('1 day') + suffix;
		}
		
		if (diff < 2419200) {
			let weeks = diff / 604800 | 0;
			
			if (weeks > 1) {
				return __('%d weeks', weeks) + suffix;
			}
			
			return __('1 week') + suffix;
		}
	}
	
	if (format == 'readable' || format == 'readable-date') {
		let months = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.', 'Sept.', 'Oct.', 'Nov.', 'Dec.'];
		
		if (config.language == 'en') {
			let day = date.getDate();
			
			if ((day >= 4 && day <= 20) || (day >= 24 && day <= 30)) {
				day = day + 'th';
			} else if (day % 10 == 1) {
				day = day + 'st';
			} else if (day % 10 == 2) {
				day = day + 'nd';
			} else if (day % 10 == 3) {
				day = day + 'rd';
			}
			
			if (new Date().getFullYear() == date.getFullYear()) {
				return __(months[date.getMonth()]) + ' ' + day;
			}
			
			return __(months[date.getMonth()]) + ' ' + day + ' ' + date.getFullYear();	
		}
		
		if (new Date().getFullYear() == date.getFullYear()) {
			return date.getDate() + ' ' + __(months[date.getMonth()]);	
		}
		
		return date.getDate() + ' ' + __(months[date.getMonth()]) + ' ' + date.getFullYear();	
	}
	
	if (format == 'readable-datetime') {
		return formatDateLocal(date, 'readable-date') + ' ' + formatDateLocal(date, 'time');
	}
	
	return formatDateLocal(date, 'date');
}	

function formatWeekDay (date) {
	const names = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

	if (typeof date == 'string') {
		date = new Date(date);
	}
	
	if (!(date instanceof Date)) {
		return false;
	}
	
	let name = names[date.getDay()]; 
	return __(name);
}

function formatTime (time) {
	if (time instanceof Date) {
		return time.getHours() + ':' + ('' + time.getMinutes()).padStart(2, '0');
	}
	
	if (typeof time != 'string') {
		return false;
	}
	
	let regex = /^([01]?\d|2[0-3]):([0-5]?\d)(?::([0-5]?\d))?$/
		, split = time.trim().match(regex);
	
	if (!split) {
		return false;
	}
	
	return split[1] + ':' + split[2].padStart(2, '0');
}
