import { ENVIRONMENT } from '@admin/providers'
import { AfterViewInit, Component, ElementRef, forwardRef, inject, input, output, viewChild } from '@angular/core'
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
import { importLibrary, setOptions } from '@googlemaps/js-api-loader'

@Component({
	standalone: true,
	selector: 'kadi-places-autocomplete',
	providers: [
		{
			provide: NG_VALUE_ACCESSOR,
			useExisting: forwardRef(() => PlacesAutocompleteComponent),
			multi: true,
		},
	],
	template: `
		<input
			#addressInput
			[placeholder]="placeholder()"
			type="text"
			class="w-full" />
	`,
})
export class PlacesAutocompleteComponent implements AfterViewInit, ControlValueAccessor {
	readonly addresstext = viewChild.required<ElementRef<HTMLInputElement>>('addressInput')

	readonly addressType = input<'establishment' | 'address' | 'geocode'>('geocode')
	readonly placeholder = input('Enter a location')
	readonly fields = input.required<string[]>()

	readonly placeChange = output<google.maps.places.PlaceResult>()

	private readonly environment = inject(ENVIRONMENT)

	constructor() {
		setOptions({ key: this.environment.googleMapsApiKey })
	}

	/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function */
	onChange = (place: google.maps.places.PlaceResult | undefined) => {}
	onTouched = () => {}
	/* eslint-enable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function */

	//#region ControlValueAccessor method implementation
	writeValue(place: google.maps.places.PlaceResult | null | undefined): void {
		this.addresstext().nativeElement.value = place?.name ?? ''
	}

	registerOnChange(onChange: (place: google.maps.places.PlaceResult | undefined) => void): void {
		this.onChange = onChange
	}

	registerOnTouched(onTouched: () => void): void {
		this.onTouched = onTouched
	}
	//#endregion

	ngAfterViewInit() {
		importLibrary('places').then((places) => {
			const autocomplete = new places.Autocomplete(this.addresstext().nativeElement, { fields: this.fields() })
			autocomplete.addListener('place_changed', () => {
				const place = autocomplete.getPlace()

				this.onTouched()
				this.onChange(place)
				this.placeChange.emit(place)
			})
		})
	}
}
