// Questo file fa parte di MyTown.
// MyTown è software libero: puoi ridistribuirlo e/o modificarlo secondo
// i termini della GNU Affero General Public License come pubblicata dalla
// Free Software Foundation, versione 3.
// Distribuito senza ALCUNA GARANZIA; vedi la GNU AGPL v3 per i dettagli.
// Copyright (C) Kondor Consulting & Services S.r.l.
// SPDX-License-Identifier: AGPL-3.0-or-later

import { CommonModule } from '@angular/common';
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { IonicModule, IonInput } from '@ionic/angular';

@Component({
	selector: 'app-suggestion-simple-input',
	standalone: true,
	imports: [CommonModule, FormsModule, IonicModule, ReactiveFormsModule],
	template: `
		<ion-input
		  style="text-transform: capitalize;"
		  [disabled]="isDisabled"
		  [placeholder]="placeholder"
		  [type]="type"
		  [tabindex]="tabindex"
		  [(ngModel)]="valueSel"
		  (ionInput)="onInput($event)"
		  (ionFocus)="onFocus()"
		  (keydown)="onKeyDown($event)"
		  (ionBlur)="onBlur()"
		  [attr.min]="type === 'number' ? 1 : null"
		  #in_digit
		></ion-input>
		@if (filteredSuggestions.length > 0 && showSuggestions) {
		  <ion-list class="suggestion-list">
		    @for (suggestion of filteredSuggestions; track suggestion; let i = $index) {
		      <ion-item
		        (click)="selectSuggestion(suggestion)"
		        [ngClass]="{ focused: i === focusedSuggestionIndex }"
		        suggestion-item
		        tabindex="0"
		        (keydown)="onSuggestionKeyDown($event, suggestion)"
		        (focus)="focusedSuggestionIndex = i"
		        >
		        {{ suggestion }}
		      </ion-item>
		    }
		  </ion-list>
		}
		`,
	styles: [
		`
			ion-item {
				position: relative;
				z-index: 1;
			}

			ion-list.suggestion-list {
				position: relative;
				left: 0;
				right: 0;
				background: var(--ion-color-light);
				border: 1px solid var(--ion-color-medium);
				z-index: 1000;
				max-height: 200px;
				overflow-y: auto;
				padding-top: 0px;
				padding-bottom: 0px;
			}

			ion-item[suggestion-item] {
				cursor: pointer;
			}

			ion-item[suggestion-item]:hover,
			ion-item[suggestion-item].focused {
				--background: var(--ion-color-light);
			}

			ion-item[suggestion-item].focused {
				--background: var(--ion-color-secondary);
				color: var(--ion-color-light);
			}
		`,
	],
})
export class SuggestionSimpleInputComponent {
	@Input() suggestions: string[] = [];
	@Input() isDisabled: boolean = false;
	@Input() hideAllWhenEmpty: boolean = false;
	@Input() placeholder: string = '';
	@Input() valueSel: string = '';
	/*@Input() set valueSel(valueSel: string | null) {
		if (valueSel) {
			this.value_in = valueSel;
		}
	}*/

	@Input() type: string = '';
	@Input() tabindex: number = -1;
	@Output() valueSelected = new EventEmitter<any>();

	filteredSuggestions: string[] = [];
	showSuggestions: boolean = false;
	focusedSuggestionIndex: number = -1;
	//value_in: string = '';

	@ViewChild('in_digit') digit!: IonInput;

	onInput(event: any): void {
		const inputValue = event.target.value;
		if (this.hideAllWhenEmpty) {
			if (inputValue) {
				this.filterSuggestions(inputValue);
			} else {
				this.clearFilterSuggestions();
			}
		} else {
			this.filterSuggestions(inputValue);
		}

		if (this.type !== 'combo' && inputValue !== undefined && inputValue !== null) {
			let obj = { value: inputValue, isOnBlur: false };
			this.valueSelected.emit(obj);
		}
	}

	filterSuggestions(inputValue: string) {
		if (this.type === 'combo') {
			this.filteredSuggestions = this.suggestions
				.filter((suggestion) => suggestion.toLowerCase().includes(inputValue.toLowerCase()))
				.slice(0, 999)
				.map((item) => item.split('|')[1]);
		} else {
			this.filteredSuggestions = this.suggestions.filter((suggestion) => suggestion.toLowerCase().startsWith(inputValue.toLowerCase())).slice(0, 999);
		}
		this.showSuggestions = true;
		this.focusedSuggestionIndex = -1;
	}

	clearFilterSuggestions() {
		this.filteredSuggestions = [];
		this.showSuggestions = false;
		this.focusedSuggestionIndex = -1;
	}

	onFocus(): void {
		this.showSuggestions = true;
		if (this.type === 'combo') {
			this.focusedSuggestionIndex = -1;
			this.filteredSuggestions = this.suggestions.slice(0, 999).map((item) => item.split('|')[1]);
		}
	}

	onBlur(): void {
		setTimeout(() => {
			if (this.showSuggestions) {
				this.clearFilterSuggestions();
			}

			let valEmit = this.valueSel;
			if (this.type === 'combo') {
				if (!this.suggestions.map((item) => item.split('|')[1]).includes(valEmit)) {
					valEmit = '';
					this.valueSel = '';
				} else {
					valEmit = this.suggestions.find((x) => x.split('|')[1] == valEmit)?.split('|')[0] || '';
				}
			}
			let obj = { value: valEmit, isOnBlur: true };
			this.valueSelected.emit(obj);
		}, 500);
	}

	selectSuggestion(suggestion: string): void {
		this.showSuggestions = false;
		this.clearFilterSuggestions();
		this.valueSel = suggestion;

		if (this.type === 'combo') {
			suggestion = this.suggestions.find((x) => x.split('|')[1] == suggestion)?.split('|')[0] || '';
		}
		let obj = { value: suggestion, isOnBlur: false };
		this.valueSelected.emit(obj);
	}

	onKeyDown(event: KeyboardEvent): void {
		if (this.showSuggestions) {
			if (event.key === 'ArrowDown') {
				event.preventDefault();
				this.focusedSuggestionIndex = (this.focusedSuggestionIndex + 1) % this.filteredSuggestions.length;
				this.focusSuggestionItem();
			} else if (event.key === 'ArrowUp') {
				event.preventDefault();
				this.focusedSuggestionIndex = (this.focusedSuggestionIndex - 1 + this.filteredSuggestions.length) % this.filteredSuggestions.length;
				this.focusSuggestionItem();
			} else if (event.key === 'Enter' || event.key === ' ') {
				if (this.focusedSuggestionIndex >= 0 && this.focusedSuggestionIndex < this.filteredSuggestions.length) {
					event.preventDefault();
					this.selectSuggestion(this.filteredSuggestions[this.focusedSuggestionIndex]);
				}
			}
		}
	}

	onSuggestionKeyDown(event: KeyboardEvent, suggestion: string): void {
		if (event.key === 'Enter' || event.key === ' ') {
			event.preventDefault();
			this.selectSuggestion(suggestion);
		}
	}

	private focusSuggestionItem(): void {
		const suggestionItems = document.querySelectorAll('[suggestion-item]');
		if (this.focusedSuggestionIndex >= 0 && this.focusedSuggestionIndex < suggestionItems.length) {
			suggestionItems.forEach((item, index) => {
				if (index === this.focusedSuggestionIndex) {
					item.classList.add('focused');
				} else {
					item.classList.remove('focused');
				}
			});

			const focusedItem = suggestionItems[this.focusedSuggestionIndex] as HTMLElement;
			focusedItem.scrollIntoView({
				block: 'nearest', // 'nearest' per farlo scorrere solo se necessario
				inline: 'nearest',
				behavior: 'smooth', // Scorrimento fluido
			});
			focusedItem.focus();
		}
	}

	setFocus() {
		this.digit.setFocus().then(() => {
			const nativeInput = (this.digit as any).el.querySelector('input');
			if (nativeInput) {
				nativeInput.select();
			}
		});
	}
}
