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 CBBSPLoanCalculator_Ctrl(
	loanTermsLabelEl,
	inpEls,
	inpErrEls,
	resEls,
	prods,iban,cur_symb,decimals
) {

	function update(){
		var valid=D.populate(
			inpEls.product_type_value	.value,
			inpEls.loan_terms_value		.value,
			inpEls.interest_rate_value	.value,
			inpEls.loan_amount_value	.value
		);
		if(valid===true){
			V.error({},{});
			var R=D.calculate();
			var start=null;
			var end=null;
			V.results(
				R.product_type,
				R.terms_val,
				R.interest,
				R.amount,
				R.repayment
			);
			if(inpEls.interest_rate_value.value!=R.interest){
				start=inpEls.interest_rate_value.selectionStart;
				end=inpEls.interest_rate_value.selectionEnd;
				inpEls.interest_rate_value.value=R.interest;
				if(start	>inpEls.interest_rate_value.value.length){start	=inpEls.interest_rate_value.value.length;}
				if(end		>inpEls.interest_rate_value.value.length){end	=inpEls.interest_rate_value.value.length;}
				inpEls.interest_rate_value.setSelectionRange(start,end);
			}
			return;
		}
		V.error(D.errors(),D.values());
	}

	function updateType(){
		var product=D.product(inpEls.product_type_value.value);
		if(product===false){
			V.error(D.errors());
			return;
		}
		inpEls.loan_terms_value.value		=	product.default_term;
		inpEls.interest_rate_value.value	=	product.default_rate;
		inpEls.loan_amount_value.value		=	product.default_loan;
		update();
	}

	function init() {
		inpEls.product_type_value.addEventListener('change',function(e){
			e.preventDefault();
			updateType();
		});
		inpEls.loan_terms_value		.addEventListener('keyup',function(e){update();});
		inpEls.interest_rate_value	.addEventListener('keyup',function(e){update();});
		inpEls.loan_amount_value	.addEventListener('keyup',function(e){update();});
		inpEls.interest_rate_value.type='text';
	}
	var D=CBBSPLoanCalculator_Data(prods);
	var V=CBBSPLoanCalculator_View(
		loanTermsLabelEl,
		inpErrEls.loan_terms_value,
		inpErrEls.interest_rate_value,
		inpErrEls.loan_amount_value,
		resEls.product_type_label,
		resEls.loan_terms_value,
		resEls.interest_rate_value,
		resEls.loan_amount_value,
		resEls.monthly_repayment,
		iban,cur_symb,decimals
	);

	init();
}


function CBBSPLoanCalculator_Data(this_products){
	var this_product_type	=null;
	var this_loan_terms		=null;
	var this_interest_rate	=null;
	var this_loan_amount	=null;
	var this_product		=null;
	var this_errors=[];
	var this_messages={
		1   :['product_type'	,'Please select one of the products'					],
		11  :['loan_terms'		,'Please enter a number'								],
		12  :['loan_terms'		,'Please enter a whole number, no decimals'				],
		13  :['loan_terms'		,'Value is below the minimum allowed for this product'	],
		14  :['loan_terms'		,'Value exceeds the maximum allowed for this product'	],
		21  :['interest_rate'	,'Please enter a number'								],
		22  :['interest_rate'	,'Please enter at most 2 decimal places'				],
		23  :['interest_rate'	,'Please enter a number greater than 0'					],
		31	:['loan_amount'		,'Please enter a number'								],
		32	:['loan_amount'		,'Please enter a whole number, no cents'				],
		33	:['loan_amount'		,'Value is below the minimum allowed for this product'	],
		34	:['loan_amount'		,'Value exceeds the maximum allowed for this product'	],
	};

	function populate(
		product_type_value,
		loan_terms_value,
		interest_rate_value,
		loan_amount_value
	){
		this_product	=null;
		this_errors		=[];

		this_product_type			=				product_type_value		;
		this_loan_terms				=parseFloat(	loan_terms_value		);
		this_interest_rate			=parseFloat(	interest_rate_value		);
		this_loan_amount			=parseFloat(	loan_amount_value		);

		if(typeof(this_products[this_product_type])=='unsigned'				){	this_errors.push(1);		return false;	}
		this_product=this_products[this_product_type];

		if(Number.isNaN(this_loan_terms)									){	this_errors.push(11);						}
		else if(parseInt(loan_terms_value)	!=parseFloat(loan_terms_value)	){	this_errors.push(12);						}
		else if(this_loan_terms				<this_product.min_term			){	this_errors.push(13);						}
		else if(this_loan_terms				>this_product.max_term			){	this_errors.push(14);						}

		if(Number.isNaN(this_interest_rate)									){	this_errors.push(21);						}
		this_interest_rate=Number(this_interest_rate.toPrecision(5).substring(0,5));
		if(this_interest_rate				<=0								){	this_errors.push(23);						}

		if(Number.isNaN(this_loan_amount)									){	this_errors.push(31);						}
		else if(parseInt(loan_amount_value)	!=parseFloat(loan_amount_value)	){	this_errors.push(32);						}
		else if(this_loan_amount			<this_product.min_loan			){	this_errors.push(33);						}
		else if(this_loan_amount			>this_product.max_loan			){	this_errors.push(34);						}
		if(this_errors.length!=0											){								return false;	}
																											return true;
	}

	function values(){
		return {
			product_type	:this_product.type,
			terms_val		:this_loan_terms,
			interest		:this_interest_rate,
			amount			:this_loan_amount,
		};
	}

	function calculate(){
		var r	=this_interest_rate	/this_product.term_period_r/100;
		var n	=this_loan_terms	*this_product.term_period_n;
		var rp1	=Math.pow(r+1		,n);
		return {
			product_type	:this_product.type,
			terms_val		:this_loan_terms,
			interest		:this_interest_rate,
			amount			:this_loan_amount,
			repayment		:this_product.pay_month*this_loan_amount*(r*rp1)/(rp1-1)
		};
	}

	function errors(){
		var ret={};
		for(let i=0;i<this_errors.length;i++){
			ret[this_messages[this_errors[i]][0]]=this_messages[this_errors[i]][1];
		}
		return ret;
	}

	function product(product_type_value){
		this_product	=null;
		this_product_type			=				product_type_value		;

		if(typeof(this_products[this_product_type])=='unsigned'				){	this_errors.push(1);		return false;	}
		this_product=this_products[this_product_type];
		return {
			default_term	:this_product.default_term,
			default_loan	:this_product.default_loan,
			default_rate	:this_product.default_rate
		};
	}

	return {
		populate	:populate	,
		calculate	:calculate	,
		product		:product	,
		errors		:errors		,
		values		:values
	};
}


function CBBSPLoanCalculator_View(
	loanTermsLblEl,
	inputLoanTermsValEl,
	inputInterestRateValEl,
	inputLoanAmountValEl,
	resProductTypeLblEl,
	resLoanTermsValEl,
	resInterestValEl,
	resLoanAmountValEl,
	resMonthlyRepEl,
	iban,cur_symb,decimals
){
	function _here(){Intl.DateTimeFormat().resolvedOptions().locale;}
	function _format(amount){
		return amount.toLocaleString(_here(),{style:'decimal',minimumFractionDigits:decimals,maximumFractionDigits:decimals});
	}
	function error(errors,values){
		if(typeof(errors.product_type	)!='undefined'){
			resProductTypeLblEl	.innerText='';
			alert(errors.product_type);
		}
		inputLoanTermsValEl		.innerText='';
		inputInterestRateValEl	.innerText='';
		inputLoanAmountValEl	.innerText='';
		if(typeof(errors.loan_terms		)!='undefined'){
			inputLoanTermsValEl		.innerText=errors.loan_terms	;
			resLoanTermsValEl		.innerText=''					;
		}else{
			if(typeof(values.terms_val	)!='undefined'){
				_terms(values.terms_val);
			}
		}
		if(typeof(errors.interest_rate	)!='undefined'){
			inputInterestRateValEl	.innerText=errors.interest_rate	;
			resInterestValEl		.innerText=''					;
		}else{
			if(typeof(values.interest	)!='undefined'){
				_interest(values.interest);
			}
		}
		if(typeof(errors.loan_amount	)!='undefined'){
			inputLoanAmountValEl	.innerText=errors.loan_amount	;
			resLoanAmountValEl		.innerText=''					;
		}else{
			if(typeof(values.amount		)!='undefined'){
				_amount(values.amount);
			}
		}
	}

	function _amount(amount){
		amount							=_format(amount);
		resLoanAmountValEl	.innerText	=`${amount} ${iban}`;
	}
	function _product_type(product_type){	resProductTypeLblEl	.innerText	=product_type	;}
	function _terms(terms_val){				resLoanTermsValEl	.innerText	=terms_val		;}
	function _interest(interest){			resInterestValEl	.innerText	=interest+'%'	;}

	function results(product_type,terms_val,interest,amount,repayment){
		_amount(		amount			);
		_product_type(	product_type	);
		_terms(			terms_val		);
		_interest(		interest		);
		repayment	=_format(repayment);
		resMonthlyRepEl		.innerText=cur_symb.replace('%s',repayment);
	}

	return {
		error		:error		,
		results		:results
	}
}
