import {
  AfterViewInit,
  Component,
  effect,
  ElementRef,
  inject, Injector,
  input,
  output,
  PLATFORM_ID, runInInjectionContext,
  ViewChild
} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
import {MapOptions} from '../../adapters/map-adapter.interface';
import {MapFacade} from '../../adapters/map-facade';
import {WebglDetectionDirective} from '../../directives/webgl-detection.directive';

export interface OpenMapOptions extends MapOptions {
  forceRaster: boolean;
}

@Component({
  selector: 'open-map',
  imports: [
    WebglDetectionDirective
  ],
  templateUrl: './open-map.component.html',
  styleUrl: './open-map.component.css',
  standalone: true,
})
export class OpenMapComponent implements AfterViewInit {
  private readonly platformId = inject(PLATFORM_ID);
  private readonly injector = inject(Injector);

  webglSupported?: boolean;
  map?: MapFacade;

  @ViewChild('mapContainer', { static: true }) mapContainer!: ElementRef<HTMLDivElement>;

  options = input<OpenMapOptions>({
    center: [50.426606229502525, 30.56308375468811],
    zoom: 6,
    styleUrl: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
    tileUrl: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
    forceRaster: false,
  });

  mapReady = output<MapFacade>();

  ngAfterViewInit(): void {
    if (false === isPlatformBrowser(this.platformId))
      return;

    runInInjectionContext(this.injector, () => {
      effect(() => {
        if (undefined === this.webglSupported)
          return;

        if (!this.map)
          this.initializeMap();
      });
    });
  }

  webglDetection(supported: boolean): void {
    this.webglSupported = supported;
    if (undefined === this.map)
      this.initializeMap();
  }

  private initializeMap(): void {
    const options = this.options();
    this.map = new MapFacade(options.forceRaster, this.webglSupported!);
    this.map.init(this.mapContainer.nativeElement, options);
    this.mapReady.emit(this.map);
  }
}
