import {
  AfterViewInit,
  Component,
  effect,
  EventEmitter,
  input,
  Input,
  OnDestroy,
  OnInit,
  Output,
  signal,
} from '@angular/core';
import { Coordinates } from '@app/domain/localisation/coordinates.model';
import * as L from 'leaflet';
import { LoadingComponent } from '@app/shared/components/loading/loading.component';
import { ProfileViewModel } from '@app/adapters/profiles/profile.presenter.model';

export interface MapMarker {
  id: string;
  coordinates: Coordinates;
  title?: string;
  description?: string;
  icon?: string;
  profile?: ProfileViewModel;
}

@Component({
  selector: 'app-map',
  standalone: true,
  imports: [LoadingComponent],
  templateUrl: './map.component.html',
  styleUrl: './map.component.scss',
})
export class MapComponent implements OnInit, AfterViewInit, OnDestroy {
  @Input() center: Coordinates = { latitude: 48.8566, longitude: 2.3522 }; // Paris par défaut
  @Input() zoom: number = 13;
  @Input() interactive: boolean = true;
  @Input() showUserLocation: boolean = false;
  @Input() height: string = '500px';

  @Output() onLocationSelected = new EventEmitter<Coordinates>();
  @Output() onMarkerClick = new EventEmitter<MapMarker>();

  markers = input<MapMarker[]>([]);

  private map: L.Map | null = null;
  private markersLayer: L.LayerGroup | null = null;
  private userMarker: L.Marker | null = null;

  protected mapReady = signal<boolean>(false);

  constructor() {
    effect(() => {
      const isReady = this.mapReady();
      if (isReady && this.map) {
        this.updateMarkers();
      }
    });

    this.fixLeafletIconPath();
  }

  ngOnInit(): void {
    // Fix pour les icônes Leaflet
    this.fixLeafletIconPath();
  }

  ngAfterViewInit(): void {
    setTimeout(() => this.initMap(), 100);
  }

  ngOnDestroy(): void {
    if (this.map) {
      this.map.remove();
    }
  }

  private initMap(): void {
    // Initialiser la carte
    this.map = L.map('map', {
      center: [this.center.latitude, this.center.longitude],
      zoom: this.zoom,
      zoomControl: true,
      dragging: this.interactive,
      scrollWheelZoom: this.interactive,
    });

    // Ajouter le layer de tuiles
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors',
      maxZoom: 19,
    }).addTo(this.map);

    // Créer le layer pour les markers
    this.markersLayer = L.layerGroup().addTo(this.map);

    // Ajouter l'événement de clic sur la carte si interactive
    if (this.interactive) {
      this.map.on('click', (e: L.LeafletMouseEvent) => {
        this.onMapClick(e);
      });
    }

    this.mapReady.set(true);
    this.updateMarkers();
  }

  private onMapClick(event: L.LeafletMouseEvent): void {
    const coords: Coordinates = {
      latitude: event.latlng.lat,
      longitude: event.latlng.lng,
    };

    this.onLocationSelected.emit(coords);

    // Ajouter un marker temporaire à la position cliquée
    if (this.showUserLocation) {
      this.setUserLocation(coords);
    }
  }

  /*private updateMarkers(): void {
    if (!this.markersLayer) return;

    // Nettoyer les markers existants
    this.markersLayer.clearLayers();

    // Ajouter les nouveaux markers
    this.markers().forEach((marker) => {
      const leafletMarker = L.marker([marker.coordinates.latitude, marker.coordinates.longitude], {
        icon: this.createCustomIcon(marker.icon),
      });

      if (marker.title || marker.description) {
        leafletMarker.bindPopup(
          `<div class="map-popup">
              ${marker.title ? `<strong>${marker.title}</strong>` : ''}
              ${marker.description ? `<p>${marker.description}</p>` : ''}
            </div>`
        );
      }

      leafletMarker.on('click', () => {
        this.onMarkerClick.emit(marker);
      });

      this.markersLayer!.addLayer(leafletMarker);
    });

    // Ajuster la vue pour montrer tous les markers
    if (this.markers().length > 0) {
      const bounds = L.latLngBounds(
        this.markers().map((m) => [m.coordinates.latitude, m.coordinates.longitude])
      );
      this.map?.fitBounds(bounds, { padding: [50, 50] });
    }
  }*/

  private updateMarkers(): void {
    if (!this.markersLayer) return;

    this.markersLayer.clearLayers();

    this.markers().forEach((marker) => {
      // 1. Création du Marker
      const leafletMarker = L.marker([marker.coordinates.latitude, marker.coordinates.longitude], {
        icon: this.createCustomIcon(),
      });

      // --- A. GESTION DU SURVOL (HOVER) ---
      // On utilise un Tooltip pour l'affichage au survol
      if (marker.profile!.fullName) {
        leafletMarker.bindTooltip(marker.profile!.fullName!, {
          permanent: false, // false = n'apparaît qu'au survol
          direction: 'top', // s'affiche au-dessus du marker
          className: 'custom-map-tooltip', // Pour le style CSS si besoin
          offset: [0, -35], // Décalage pour ne pas chevaucher le marker
        });
      }

      // --- B. GESTION DU CLIC (POPUP) ---
      // On construit la Card complète pour le clic
      const popupContainer = document.createElement('div');
      popupContainer.className =
        'custom-popup-card flex flex-col items-center gap-3 min-w-[160px] text-center p-1';

      // Image (Avatar)
      if (marker.profile!.avatarUrl) {
        const img = document.createElement('img');
        img.src = marker.profile!.avatarUrl.replace('320x240', '100x100');
        img.className = 'w-16 h-16 rounded-full object-cover border-2 border-indigo-500 shadow-sm';
        popupContainer.appendChild(img);
      } else {
        const placeholder = document.createElement('div');
        placeholder.className =
          'w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center text-indigo-500 font-bold text-xl';
        placeholder.innerText = marker.profile!.fullName
          ? marker.profile!.fullName.charAt(0).toUpperCase()
          : '?';
        popupContainer.appendChild(placeholder);
      }

      // Nom (Titre)
      if (marker.profile!.fullName) {
        const title = document.createElement('h3');
        title.className = 'font-bold text-gray-800 text-sm m-0';
        title.innerText = marker.profile!.fullName;
        popupContainer.appendChild(title);
      }

      // Bouton "Voir le profil"
      const btn = document.createElement('button');
      btn.className =
        'bg-indigo-600 text-white text-xs px-4 py-1.5 rounded-full hover:bg-indigo-700 transition-colors w-full mt-1';
      btn.innerText = 'Voir le profil';

      btn.addEventListener('click', () => {
        this.onMarkerClick.emit(marker);
      });
      popupContainer.appendChild(btn);

      // On lie la popup au marker (Par défaut, bindPopup s'active au clic)
      leafletMarker.bindPopup(popupContainer, {
        closeButton: true, // On remet la croix pour pouvoir fermer si besoin
        offset: [0, -30],
        className: 'custom-leaflet-popup',
      });

      this.markersLayer!.addLayer(leafletMarker);
    });

    // Recentrage automatique (optionnel, selon votre goût)
    if (this.markers().length > 0 && this.map) {
      const bounds = L.latLngBounds(
        this.markers().map((m) => [m.coordinates.latitude, m.coordinates.longitude])
      );
      this.map.fitBounds(bounds, { padding: [50, 50] });
    }
  }

  setUserLocation(coordinates: Coordinates): void {
    if (!this.map) return;

    // Supprimer l'ancien marker utilisateur
    if (this.userMarker) {
      this.userMarker.remove();
    }

    // Créer un nouveau marker utilisateur
    this.userMarker = L.marker([coordinates.latitude, coordinates.longitude], {
      icon: this.createUserIcon(),
    }).addTo(this.map);

    this.userMarker.bindPopup('Votre position').openPopup();

    // Centrer la carte sur la position
    this.map.setView([coordinates.latitude, coordinates.longitude], this.zoom);
  }

  recenterMap(): void {
    if (this.map) {
      this.map.setView([this.center.latitude, this.center.longitude], this.zoom);
    }
  }

  private createCustomIcon(iconUrl?: string): L.Icon {
    return L.icon({
      iconUrl: iconUrl || 'assets/leaflet/marker-icon.png',
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -34],
      shadowUrl: 'assets/leaflet/marker-shadow.png',
      shadowSize: [41, 41],
    });
  }

  private createUserIcon(): L.Icon {
    return L.icon({
      iconUrl: 'assets/leaflet/marker-icon.png',
      iconRetinaUrl: 'assets/leaflet/marker-icon-2x.png',
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -34],
      tooltipAnchor: [16, -28],
      shadowSize: [41, 41],
    });
  }

  private fixLeafletIconPath(): void {
    const iconRetinaUrl = 'assets/leaflet/marker-icon-2x.png';
    const iconUrl = 'assets/leaflet/marker-icon.png';
    const shadowUrl = 'assets/leaflet/marker-shadow.png';
    const iconDefault = L.icon({
      iconRetinaUrl,
      iconUrl,
      shadowUrl,
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -34],
      tooltipAnchor: [16, -28],
      shadowSize: [41, 41],
    });
    L.Marker.prototype.options.icon = iconDefault;
  }
}
