/**
 * Copyright (C) 2020. Robert Bosch GmbH Copyright (C) 2020. Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { LocationLayer, LocationMapService, LocationService, OpenLayersMapComponent } from '@bci-web-core/maps';
import { Feature, Overlay } from 'ol';
import { click } from 'ol/events/condition';
import Select from 'ol/interaction/Select';
import { Observable, Subject } from 'rxjs';
import { DEVICE_PIN_STYLE, FACILITY_SELECTION_STYLE, FACILITY_TYPE } from './demo-location-layers.mocks';

@Component({
  selector: 'bci-demo-location-layers',
  templateUrl: './demo-location-layers.component.html',
  styleUrls: ['./demo-location-layers.component.scss'],
  providers: [LocationMapService],
})
export class DemoLocationLayersComponent implements OnInit, AfterViewInit, OnDestroy {
  maxZoom = 24;
  minZoom = 10;
  zoom = 16;
  lat = 48.81485;
  lon = 9.17;
  viewCenter: [number, number] = [this.lon, this.lat];
  overlayContent: string;
  mapOverlay;
  locationLayers: Observable<LocationLayer[]>;

  @ViewChild(OpenLayersMapComponent, { static: true }) map: OpenLayersMapComponent;
  @ViewChild('overlay', { static: false }) overlayElement: ElementRef;

  protected ngUnsubscribe = new Subject<void>();

  constructor(private locationService: LocationService, public locationMapService: LocationMapService) {}

  ngOnInit(): void {
    this.locationLayers = this.locationMapService.locationLayers;
    this.locationService.queryAllLayers({
      minZoom: this.minZoom,
      maxZoom: this.maxZoom,
      zoom: this.zoom,
    });
  }

  ngAfterViewInit(): void {
    this.addMapInteraction();
    this.addOverlay();
  }

  addMapInteraction(): void {
    const selectClick = new Select({
      condition: click,
      style: (feature: Feature) => {
        const entity = this.locationMapService.featureToEntityMap.getEntityOfFeature(feature);
        if (entity.type === FACILITY_TYPE.device) {
          return DEVICE_PIN_STYLE;
        } else {
          return FACILITY_SELECTION_STYLE;
        }
      },
    });
    this.map.map.addInteraction(selectClick);

    selectClick.on('select', (event: any) => {
      const targetFeatures = event.target.getFeatures();
      const features = targetFeatures.getArray();
      const coordinate = event.mapBrowserEvent.coordinate;

      if (features && features.length > 0) {
        const selectedFeature = features[0];
        const entity = this.locationMapService.featureToEntityMap.getEntityOfFeature(selectedFeature);
        if (entity.type === FACILITY_TYPE.device) {
          this.overlayContent = 'Device : ' + entity.name;
          this.mapOverlay.setPosition(coordinate);
        } else {
          this.map.map.getView().fit(selectedFeature.getGeometry(), { duration: 500 });
        }
      } else {
        this.mapOverlay.setPosition(undefined);
      }
    });
  }

  addOverlay(): void {
    this.mapOverlay = new Overlay({
      element: this.overlayElement.nativeElement,
    });
    this.map.map.addOverlay(this.mapOverlay);
  }

  ngOnDestroy(): void {
    this.ngUnsubscribe.next();
    this.ngUnsubscribe.complete();
  }
}
