/*
 * Copyright (C) 2022 StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {LngLatBoundsLike, MapLibreEvent} from 'maplibre-gl';
import {
  ControlComponent,
  GeolocateControlDirective,
  MapComponent,
  ScaleControlDirective,
} from '@maplibre/ngx-maplibre-gl';
import {TranslateModule} from '@ngx-translate/core';
import {ActivatedRoute, RouterLink} from '@angular/router';
import {MapAuto3dDirective} from './map-auto-3d.directive';
import {MediaQueryPipe} from '../../util/media-query.pipe';
import {MapStyleDirective} from './map-style.directive';
import {DataProvider} from '../data/data.provider';
import {SCSearchFilter, SCThingType} from '@openstapps/core';
import {DataModule} from '../data/data.module';
import {AsyncPipe} from '@angular/common';
import {GeolocateControlComponent} from './controls/geolocate-control.component';
import {CompassControlComponent} from './controls/compass-control.component';
import {MapSizeFixDirective} from './map-size-fix.directive';
import {MapDataProvider} from './map-data.provider';
import {ThingPoiFeatureCollectionPipe, ThingPolygonFeatureCollectionPipe} from './feature-collection.pipe';
import {BuildingMarkersComponent} from './elements/building-markers.component';
import {PoiMarkersComponent} from './elements/poi-markers.component';
import {AttributionComponent} from './controls/attribution.component';
import {filter, map} from 'rxjs';
import {IonButton, IonContent, IonLabel, IonRouterLink} from '@ionic/angular/standalone';
import {IonIconDirective} from 'src/app/util/ion-icon/ion-icon.directive';

/**
 * The main page of the map
 */
@Component({
  styleUrls: ['./map-page.scss'],
  templateUrl: './map-page.html',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [
    MapDataProvider,
    {
      provide: DataProvider,
      useExisting: MapDataProvider,
    },
  ],
  imports: [
    AsyncPipe,
    AttributionComponent,
    BuildingMarkersComponent,
    CompassControlComponent,
    ControlComponent,
    DataModule,
    GeolocateControlComponent,
    GeolocateControlDirective,
    IonIconDirective,
    MapAuto3dDirective,
    MapComponent,
    MapSizeFixDirective,
    MapStyleDirective,
    MediaQueryPipe,
    PoiMarkersComponent,
    RouterLink,
    ScaleControlDirective,
    ThingPoiFeatureCollectionPipe,
    ThingPolygonFeatureCollectionPipe,
    TranslateModule,
    IonContent,
    IonLabel,
    IonRouterLink,
    IonButton,
  ],
})
export class MapPageComponent {
  forcedFilter: SCSearchFilter = {
    type: 'boolean',
    arguments: {
      operation: 'or',
      filters: [
        {
          type: 'value',
          arguments: {
            field: 'type',
            value: [SCThingType.Building],
          },
        },
        {
          type: 'boolean',
          arguments: {
            operation: 'and',
            filters: [
              {
                type: 'value',
                arguments: {
                  field: 'categories',
                  value: ['restaurant', 'library', 'canteen', 'cafe'],
                },
              },
              {
                type: 'value',
                arguments: {
                  field: 'type',
                  value: [SCThingType.Building, SCThingType.Room, SCThingType.PointOfInterest],
                },
              },
            ],
          },
        },
      ],
    },
  };

  bounds = this.activatedRoute.queryParams.pipe(
    map(
      parameters =>
        (parameters?.bounds as [string, string])?.map(it =>
          it.split(',').map(Number.parseFloat),
        ) as LngLatBoundsLike,
    ),
    filter(uid => uid !== undefined),
  );

  constructor(
    readonly dataProvider: MapDataProvider,
    readonly activatedRoute: ActivatedRoute,
  ) {}

  mapMove(event: MapLibreEvent) {
    const bounds = event.target.getBounds();
    this.dataProvider.currentBounds.next([
      [bounds.getWest(), bounds.getNorth()],
      [bounds.getEast(), bounds.getSouth()],
    ]);
  }
}
