// 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, HostListener } from '@angular/core';
import { FormControl, AbstractControl, ReactiveFormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';

@Component({
	selector: 'app-suggestion-input',
	standalone: true,
	imports: [CommonModule, IonicModule, ReactiveFormsModule],
	template: `
		<ion-item lines="none">
			<ion-input style="text-transform: capitalize;" [id]="inputId" [formControl]="control" [readonly]="isReadonly" [placeholder]="placeholder" (ionInput)="onInput($event)" (ionFocus)="onFocus()" (keydown)="onKeyDown($event)"></ion-input>
		</ion-item>
		<ion-list class="suggestion-list" *ngIf="filteredSuggestions.length > 0 && showSuggestions">
			<ion-item
				*ngFor="let suggestion of filteredSuggestions; let i = index"
				(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 SuggestionInputComponent {
	@Input() suggestions: string[] = [];
	@Input() isReadonly: boolean = false;
	@Input() hideAllWhenEmpty: boolean = false;
	@Input() inputId: string = '';
	@Input() formControlName: string = '';
	@Input() placeholder: string = '';

	@Input() set control(control: AbstractControl | null) {
		if (control instanceof FormControl) {
			this._control = control;
		}
	}
	get control(): FormControl {
		return this._control;
	}

	@Output() valueSelected = new EventEmitter<string>();

	private _control: FormControl = new FormControl('');
	filteredSuggestions: string[] = [];
	showSuggestions: boolean = false;
	focusedSuggestionIndex: number = -1;

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

	filterSuggestions(inputValue: string) {
		this.filteredSuggestions = this.suggestions.filter((suggestion) => suggestion.toLowerCase().includes(inputValue.toLowerCase()));
		this.showSuggestions = true;
		this.focusedSuggestionIndex = -1;
	}

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

	onFocus(): void {
		this.showSuggestions = true;
	}

	selectSuggestion(suggestion: string): void {
		this.control.setValue(suggestion);
		this.showSuggestions = false;
		this.clearFilterSuggestions();
		this.valueSelected.emit(suggestion);
	}

	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');
				}
			});
			(suggestionItems[this.focusedSuggestionIndex] as HTMLElement).focus();
		}
	}
}
