import { CommonModule } from '@angular/common'; import { Component, Input, OnInit } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, } from '@angular/forms'; import { forkJoin, of, Subscription } from 'rxjs'; import { catchError, debounceTime, distinctUntilChanged, switchMap, } from 'rxjs/operators'; import { AutocompleteService } from '../../services/auto-complete/auto-complete.service'; import { ExifService } from '../../services/exif/exif.service'; import { ImageService } from '../../services/image/image.service'; import { MapReloadService } from '../../services/map-reload/map-reload.service'; import { ModalService } from '../../services/modal/modal.service'; import { PinService } from '../../services/pin/pin.service'; import { DragDropComponent } from '../drag-drop/drag-drop.component'; @Component({ selector: 'app-add-pin-popup', standalone: true, imports: [ReactiveFormsModule, CommonModule, DragDropComponent], templateUrl: './add-pin-popup.component.html', }) export class AddPinPopupComponent implements OnInit { form: FormGroup; suggestions: any[] = []; inputFocused: boolean = false; @Input() isHomePage: boolean = false; files: any[] = []; isPinModalOpen: boolean = false; modalId: string = 'add-pin-modal'; private modalSub!: Subscription; constructor( private fb: FormBuilder, private autocompleteService: AutocompleteService, private pinService: PinService, private exifService: ExifService, private modalService: ModalService, private mapReloadService: MapReloadService, private imageService: ImageService ) { this.form = this.fb.group({ title: new FormControl(''), description: new FormControl(''), location: new FormControl(''), complete_address: new FormControl(''), coordinates: new FormControl([]), files: new FormControl(null), date: new FormControl(''), }); } onFocus(): void { this.inputFocused = true; } onBlur(): void { setTimeout(() => { this.inputFocused = false; // Désactiver le focus après un petit délai pour permettre un clic sur la liste }, 200); } ngOnInit(): void { this.modalSub = this.modalService .getModalState(this.modalId) .subscribe((open) => { this.isPinModalOpen = open; if (open) { const images = this.modalService.getImageFiles().getValue(); if (images && images.length > 0) { this.files = images; this.form.patchValue({ files: images }); } } }); this.form .get('location') ?.valueChanges.pipe( debounceTime(200), // Attendre 200ms après la dernière frappe distinctUntilChanged(), // Ignorer si la nouvelle valeur est la même que la précédente switchMap((query) => { const trimmedQuery = query.trim(); if (trimmedQuery.length > 2) { return this.autocompleteService.getAddressSuggestions(trimmedQuery); } return of([]); }), catchError((error) => { console.error('Error fetching suggestions:', error); return of([]); }) ) .subscribe((data) => { this.suggestions = data; }); } selectSuggestion(suggestion: any): void { const locationControl = this.form.get('location'); if (locationControl instanceof FormControl) { locationControl.setValue(suggestion.display_name); this.form.get('complete_address')?.setValue(suggestion.display_name); this.form.get('coordinates')?.setValue([suggestion.lat, suggestion.lon]); } this.suggestions = []; } async onFilesReceived(files: FileList): Promise { this.files = Array.from(files); for (let i = 0; i < this.files.length; i++) { try { const data = await this.exifService.getLocation(this.files[i]); if (data.latitude !== undefined && data.longitude !== undefined) { const address = await this.autocompleteService .getAddressFromCoordinates(data.latitude, data.longitude) .toPromise(); if (address) { console.error('Data : ' + JSON.stringify(address)); this.form.get('location')?.setValue(address.display_name); this.form.get('complete_address')?.setValue(address.display_name); this.form.get('coordinates')?.setValue([data.latitude, data.longitude]); break; } } } catch (error) { console.error('Error : ' + error); } } } ngOnDestroy() { this.modalSub.unsubscribe(); } submitForm(): void { if (this.form.valid) { const uploadObservables = this.files.map((file) => this.imageService.postImage(file) ); forkJoin(uploadObservables).subscribe((responses) => { this.files = responses.map((res: any) => res.id); const coordinates = this.form.get('coordinates')?.value; const pinData = { ...this.form.value, files: this.files, date: this.form.get('date')?.value || null, location: coordinates || [0, 0], // Utiliser les coordonnées pour location complete_address: this.form.get('complete_address')?.value || this.form.get('location')?.value, }; // Supprimer le champ coordinates qui n'est pas dans le modèle Pin delete pinData.coordinates; console.log('Files : ' + JSON.stringify(this.files)); console.log('Pin Data : ' + JSON.stringify(pinData)); this.pinService.addPin(pinData)?.subscribe(() => { this.mapReloadService.requestReload(); // Demander le rechargement de la carte this.closePinModal(); this.form.reset(); // Réinitialiser le formulaire après soumission }); }); } else { console.error('Le formulaire est invalide'); } } openPinModal() { // this.isPinModalOpen = true; this.modalService.openModal(this.modalId); } closePinModal() { // this.isPinModalOpen = false; this.modalService.closeModal(this.modalId); } getImagePreview(file: File): string { return URL.createObjectURL(file); } }