import {Injectable} from '@angular/core';
import {DataProvider} from '../data/data.provider';
import {SCGeoFilter, SCSearchRequest, SCSearchResponse} from '@openstapps/core';
import {BehaviorSubject} from 'rxjs';

@Injectable()
export class MapDataProvider extends DataProvider {
  readonly current = new BehaviorSubject<SCSearchResponse | undefined>(undefined);

  readonly currentBounds = new BehaviorSubject<
    [[minLon: number, maxLat: number], [maxLon: number, minLat: number]] | undefined
  >(undefined);

  override async search(query: SCSearchRequest): Promise<SCSearchResponse> {
    if (query.query && this.currentBounds.value !== undefined) {
      const boundsFilter: SCGeoFilter = {
        type: 'geo',
        arguments: {
          field: 'geo',
          shape: {
            type: 'envelope',
            coordinates: this.currentBounds.value,
          },
        },
      };
      query.filter = query.filter
        ? {
            type: 'boolean',
            arguments: {
              operation: 'and',
              filters: [query.filter, boundsFilter],
            },
          }
        : boundsFilter;
    }

    if (query.from === 0 || this.current.value === undefined) {
      this.current.next(
        await super.search({
          ...query,
          size: undefined,
        }),
      );
    }
    if (query.from === undefined || query.size === undefined) {
      return this.current.value!;
    }

    return {
      ...this.current.value!,
      data: this.current.value!.data.slice(query.from, query.from + query.size),
      pagination: {
        ...this.current.value!.pagination,
        offset: query.from,
        count: Math.min(query.size, this.current.value!.data.length - query.from),
      },
    };
  }
}
