/*
 * Copyright (C) 2019 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 {Injectable} from '@angular/core';
import {
  SCDish,
  SCISO8601Date,
  SCMultiSearchRequest,
  SCPlace,
  SCThingType,
} from '@openstapps/core';
import {keyBy, mapValues, range} from 'lodash-es';
import moment from 'moment';
import {DataProvider} from '../../../../data.provider';

/**
 * TODO
 */
@Injectable({
  providedIn: 'root',
})
export class PlaceMensaService {
  constructor(private dataProvider: DataProvider) {}

  /**
   * Fetches all dishes for this building
   *
   * Splits dishes as such that each list contains all dishes that are available at that day.
   */
  async getAllDishes(
    place: SCPlace,
    days: number,
  ): Promise<Record<SCISO8601Date, SCDish[]>> {
    const request: SCMultiSearchRequest = mapValues(
      keyBy(range(days).map(i => moment().add(i, 'days').toISOString())),
      (date: SCISO8601Date) => ({
        filter: {
          arguments: {
            filters: [
              {
                arguments: {
                  field: 'offers.inPlace.uid',
                  value: place.uid,
                },
                type: 'value',
              },
              {
                arguments: {
                  field: 'type',
                  value: SCThingType.Dish,
                },
                type: 'value',
              },
              {
                arguments: {
                  field: 'offers.availabilityRange',
                  scope: 'd',
                  time: date,
                },
                type: 'availability',
              },
            ],
            operation: 'and',
          },
          type: 'boolean',
        },
        size: 1000,
      }),
    );

    return mapValues(
      await this.dataProvider.multiSearch(request),
      'data',
    ) as Record<SCISO8601Date, SCDish[]>;
  }
}
