class CBHeader {
	constructor(header, arrow_down, arrow_up) {
		this.header = header;
		this.logo = this.header.querySelector('a'); //Header part 1
		this.burgerBtn = this.header.querySelector('button'); //Header part 2
		this.mainMenu = this.header.querySelector('ul'); //Header part 3
		this.loginMenu = this.header.querySelector('nav'); //Header part 4
		this.arrow_down = arrow_down;
		this.arrow_up = arrow_up;
	}

	init() {
		window.addEventListener('resize', (e) => {
			this.checkResponsive();
		});
		this.checkResponsive();
		this.toggleMobileMenu();
	}

	checkResponsive() {
		const width = window.innerWidth;
		if (
			width <= 1100 && this.header.classList.contains('mobile') ||
			width > 1100 && !this.header.classList.contains('mobile')
		) {
			return;
		}

		//Remove the header content
		this.header.innerHTML = '';

		//Add the mobile menu and login menu to the mobile wrapper
		if (width <= 1100) {
			this.header.classList.add('mobile');
			let mobileWrapper = document.createElement('section');
			let mobileMenu = this.mainMenu.cloneNode(true);

			//Add arrow icons to the menu items that have children
			mobileMenu.querySelectorAll('li').forEach(el => {
				if (el.querySelector('ul') !== null) {
					el.querySelector('a').insertAdjacentHTML('afterend', `<button onclick="this.parentNode.classList.toggle('active');">${this.arrow_down}</button>`);
				}
			});

			//Add the mobile menu and login menu to the mobile wrapper
			mobileWrapper.append(mobileMenu, this.loginMenu);
			this.header.append(this.logo, this.burgerBtn, mobileWrapper);
			this.toggleMobileSubMenu();
		}

		//Add the desktop menu and login menu to the header
		if (width > 1100) {
			this.header.classList.remove('mobile');
			this.header.append(this.logo, this.mainMenu, this.loginMenu);
		}
	}

	toggleMobileMenu() {
		this.header.querySelector('button').addEventListener('click', (e) => {
			e.preventDefault();
			this.header.classList.toggle('active');

			//Close all submenus when the mobile menu is closed
			if (!this.header.classList.contains('active')) {
				this.header.querySelector('nav').querySelector('button').classList.remove('active');
				this.header.querySelectorAll('section > ul > li').forEach(el => {
					el.classList.remove('active');
				});
			}
		});
	}

	toggleMobileSubMenu() {
		// this.header.querySelectorAll('section > ul > li > a').forEach(el => {
		// 	const parent = el.parentElement;
		// 	if (parent.querySelector('ul'))
		// 		el.addEventListener('click', (e) => {
		// 			if (!parent.classList.contains('active')) {
		// 				e.preventDefault();
		// 				parent.classList.toggle('active');
		// 			}
		// 		});
		// });
	}
}

CBFooter = function () {
	//Handle scroll to anchor links with offset.
	function scrollToAnchor(elName) {
		const targetElement = document.querySelector(`a[name=${elName}]`);
		if (targetElement) {
			const headerOffset = 80;
			const elementPosition = targetElement.getBoundingClientRect().top + window.scrollY;
			const offsetPosition = elementPosition - headerOffset;
			window.scrollTo({
				top: offsetPosition,
				behavior: "smooth"
			});
		}
	}

	//Add event sto links with hash
	document.querySelectorAll('a[href^="#"]').forEach(anchor => {
		anchor.addEventListener("click", function (e) {
			e.preventDefault();
			const elName = this.getAttribute("href").substring(1);
			scrollToAnchor(elName);
		});
	});

	//Scroll to anchor if hash is present in URL
	if (window.location.hash) {
		setTimeout(() => {
			const elName = window.location.hash.substring(1);
			scrollToAnchor(elName);
		}, 100); // Small delay to ensure the page is loaded before scrolling
	}
}

function CBError(errors){
	var _errno=null;
	var _error=null;
	function errno(){return _errno;}
	function error(){return _error;}
	function reset(){_errno=null;error=null;}
	function set(errno,replaceObj,ret){
		_errno=errno;
		_error=errors[errno];
		for(let i in replaceObj){
			_error=_error.replace('{'+i+'}',replaceObj[i]);
		}
		if(typeof(ret)=='undefined'){ret=false;}
		return ret;
	}
	return {
		errno	:errno,
		error	:error,
		reset	:reset,
		set		:set
	}
}


function CBJobsDetails_Ctrl(
		listFilesTpl,
		form,dropFilesEl,listFilesEl,successEl,submitEl,
		feedbackEls,inputEls,errEls,
		maxNumFiles,maxFileSize,acceptableTypes,
		recaptchaSiteKey
){
	var filesUploaded=[];
	function init(){
		dropFilesEl.addEventListener('dragover',function(e){
			e.preventDefault();
			V.dragover();
		});
		dropFilesEl.addEventListener('dragleave',function(e){
			e.preventDefault();
			V.dragleave();
		});
		dropFilesEl.addEventListener('drop',function(e){
			e.preventDefault();
			V.dragleave();
			files(e.dataTransfer.files);
		});
		inputEls.files.addEventListener('change',function(e){
			files(e.target.files);
		});
		form.addEventListener('submit',function(e){
			e.preventDefault();
			e.stopPropagation();
			submit();
		});
		inputEls.highest_qualification.addEventListener('change',function(e){
			if(e.currentTarget.value===''){
				e.currentTarget.classList.remove('selected');
				return;
			}
			e.currentTarget.classList.add('selected');
		});
		inputEls.how_did_you_find_out.addEventListener('change',function(e){
			if(e.currentTarget.value===''){
				e.currentTarget.classList.remove('selected');
				return;
			}
			e.currentTarget.classList.add('selected');
		});
	}
	function collect_data(){
		var data={};
		for(let i in inputEls){
			if(i=='terms_and_conditions'){
				data[i]=inputEls[i].checked?'yes':'no';
				continue;
			}
			data[i]=inputEls[i].value;
		}
		data.file1=null;
		data.file2=null;
		data.file3=null;
		data.file4=null;
		data.file5=null;
		[data.file1,data.file2,data.file3,data.file4,data.file5]=Object.values(D.get_files());
		return data;
	}

	function state_change(e,V){
		if(e.target.readyState==XMLHttpRequest.OPENED			){V.textFeedback('Your request is being sent to BSP'	);	return;}
		if(e.target.readyState==XMLHttpRequest.HEADERS_RECEIVED	){V.textFeedback('BSP has received your request'		);	return;}
		if(e.target.readyState==XMLHttpRequest.LOADING			){V.textFeedback('BSP is processing your request'		);	return;}
		if(e.target.readyState!=XMLHttpRequest.DONE){
/* @todo fulvio do something */
			return;
		}
		V.hideFeedback();
		V.enableElements();
		if(e.target.status==200&&e.target.responseText.trim()=='Success'){
			V.displaySuccess();
			D.clear(inputEls);
			V.files(listFilesEl,[]);
			return;
		}
		if(e.target.status!=400){
			V.displayError('form','Could not process request. Please try again later.');
			return;
		}
		var res=JSON.parse(e.target.responseText);
		if(res===false){
			V.displayError('form','Invalid response format from the server.');
			return;
		}
		for(let field in res){
			let display=res[field];
			if(Array.isArray(display)){
				display=display.join('<br>');
			}
			V.displayError(field,display);
		}
		return;
	}
	function submit(){
		V.hideSuccess();
		V.clearErrEls();
		V.disableElements();
		V.textFeedback('');
		V.displayFeedback();
		if(!recaptchaSiteKey){
			D.send(collect_data(),window.location.href,'',function(e){
				state_change(e,V,errEls,feedbackEls);
			});
			return;
		}
		var recaptchaSK=recaptchaSiteKey;
		grecaptcha.ready(function(){
			grecaptcha.execute(recaptchaSK,{action:'submit'}).then(function(token){
				D.send(collect_data(),window.location.href,token,function(e){
					state_change(e,V,errEls,feedbackEls);
				});
			});
		});
	}
	function rem_file(e){
		var name=V.nameDec(e.currentTarget.getAttribute('rel'));
		D.rem_file(name);
		var display=[];
		for(file in D.get_files()){
			display.push(file);
		}
		V.files(listFilesEl,display,rem_file);
	}
	function displayFiles(){
		var display=[];
		for(file in D.get_files()){
			display.push(file);
		}
		V.files(listFilesEl,display,rem_file);
	}
	function files(files){
		V.displayError('files','');
		var test=D.set_files(files);

		if(test===false){
			if(D.get_errors().length==0){
				displayFiles();
				V.displayError('files',D.error().join('<br>'));
				return;
			}
			displayFiles();
			V.displayError('files',D.error());
			return;
		}
		displayFiles();
		return;
	}
	var D=CBJobsDetails_Data(new CBError({
		1:'File {file} is too large: each file can be a maximum of 5MB',
		2:'File {file} cannot be accepted: only Doc, PDF, or JPEG can be accepted',
		3:'No more than 5 files can be uploaded',
		4:'Uploaded item not a file',
		5:'Uploaded item not a file object',
		6:'No files available to be uploaded',
	}),maxNumFiles,maxFileSize,acceptableTypes);
	var V=CBJobsDetails_View(
		listFilesTpl,
		dropFilesEl,listFilesEl,successEl,submitEl,
		feedbackEls,inputEls,errEls
	);

	init();
	return;
};


function CBJobsDetails_Data(Err,maxNumFiles,maxFileSize,acceptableTypes){
	var files={};
	var errors=[];
	function set_files(arrayOfFiles){
		if(arrayOfFiles.length===0			){Err.set(6);errors.push(Err.error());return false;}
		if(arrayOfFiles.length>maxNumFiles	){Err.set(3);errors.push(Err.error());return false;}
		errors=[];
		var ret={
			added	:0,
			updated	:0
		};
		for(let i=0;i<arrayOfFiles.length;i++){
			if(!val_file(arrayOfFiles[i])){errors.push(Err.error());	continue			;}
			if(typeof(files[arrayOfFiles[i].name])!='undefined'){
				ret.updated++;
			}else{
				ret.added++;
			}
			files[arrayOfFiles[i].name]=arrayOfFiles[i];
			if(Object.entries(files).length>(maxNumFiles)){
				delete files[arrayOfFiles[i].name];
				Err.set(3);		errors.push(Err.error());				return false		;}
		}
		if(errors.length!=0&&ret.added===0&&ret.updated===0){			return false		;}
		return ret;
	}
	function rem_file(name){
		delete files[name];
	}
	function get_files(){	return files	;}
	function get_errors(){	return errors	;}
	function val_file(fileObj){
		if((typeof fileObj)!='object'){					return Err.set(4);}
		if(fileObj.constructor.name!='File'){			return Err.set(5);}
		if(fileObj.size>maxFileSize){					return Err.set(1,{file:fileObj.name});}
		if(!acceptableTypes.includes(fileObj.type)){	return Err.set(2,{file:fileObj.name});}
		return true;
	}

	function clear(inputEls){			for(let i in inputEls	){inputEls[i]	.value		='';}
										inputEls.terms_and_conditions.checked=false;
										files=[];
										inputEls.highest_qualification.classList.remove(	'selected');
										inputEls.how_did_you_find_out.classList.remove(		'selected');}

	function send(data,location,token,onreadystatechange){
		var FD=new FormData();
		for(let i in data){
			if(typeof(data[i])=='undefined'){
				continue;
			}
			FD.append(i,data[i]);
		}
		FD.append('token',token);
		var xhr=new XMLHttpRequest();
		xhr.onreadystatechange=onreadystatechange;
		xhr.open('POST',location,true);
		xhr.send(FD);
	}

	return {
		set_files	:set_files,
		get_files	:get_files,
		rem_file	:rem_file,
		clear		:clear,
		send		:send,
		get_errors	:get_errors,
		errno		:Err.errno,
		error		:Err.error
	};
};


function CBJobsDetails_View(
	listFilesTpl,
	dropFilesEl,listFilesEl,successEl,submitEl,
	feedbackEls,inputEls,errEls
){
	function dragover(	){dropFilesEl.classList.add(	'dragover');}
	function dragleave(	){dropFilesEl.classList.remove(	'dragover');}

	function clearErrEls(){				for(let i in errEls		){errEls[i]		.innerHTML	='';}}

	function displayError(field,err){	errEls[field].innerHTML=err		;}

	function textFeedback(msg){			feedbackEls.text		.textContent		=msg		;}
	function displayFeedback(){			feedbackEls.feedback	.classList.add(		'enable'	);}
	function displaySuccess(){			successEl				.classList.add(		'enable'	);}

	function hideFeedback(){			feedbackEls.feedback	.classList.remove(	'enable'	);}
	function hideSuccess(){				successEl				.classList.remove(	'enable'	);}

	function enableSubmission(){		submitEl.disabled=false	;}
	function disableSubmission(){		submitEl.disabled=true	;}

	function enableElements(){			for(let field in inputEls){inputEls[field].disabled=false	;}
										enableSubmission(	);}
	function disableElements(){			for(let field in inputEls){inputEls[field].disabled=true	;}
										disableSubmission(	);}

	function files(el,display,clickFunction){
		var html=document.createElement('div');
		var div=null;
		var name=null;
		while(el.firstChild){
			el.removeChild(el.firstChild);
		}
		for(let i=0;i<display.length;i++){
			div=document.createElement('div');
			name=document.createTextNode(display[i]);
			div.appendChild(name);
			div.innerHTML=listFilesTpl.replace('{file}',div.innerHTML).replace('{b64}',nameEnc(display[i]));
			div.querySelector('figcaption').addEventListener('click',clickFunction);
			el.appendChild(div.querySelector('figure'));
		}
	}

	function nameEnc(name){return btoa(name);}
	function nameDec(hash){return atob(hash);}

	return {
		dragover			:dragover,
		dragleave			:dragleave,
		clearErrEls			:clearErrEls,
		displayError		:displayError,
		textFeedback		:textFeedback,
		displayFeedback		:displayFeedback,
		displaySuccess		:displaySuccess,
		hideFeedback		:hideFeedback,
		hideSuccess			:hideSuccess,
		enableSubmission	:enableSubmission,
		disableSubmission	:disableSubmission,
		enableElements		:enableElements,
		disableElements		:disableElements,
		files				:files,
		nameEnc				:nameEnc,
		nameDec				:nameDec
	};
}
