/*
 * Copyright (C) 2021 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 {
  HttpClient,
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
  HttpResponse,
  HTTP_INTERCEPTORS,
} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {
  SCIndexResponse,
  SCSettingInputType,
  SCThingOriginType,
  SCThingType,
} from '@openstapps/core';
import {Observable, of} from 'rxjs';
import {delay, map} from 'rxjs/operators';
import packageJson from '../../../package.json';
import {facetsMock} from './data/sample-facets';
import {SampleThings} from './data/sample-things';

/* eslint-disable unicorn/no-abusive-eslint-disable */
/* eslint-disable */
export const sampleIndexResponse: SCIndexResponse = {
  app: {
    aboutPages: {},
    campusPolygon: {
      coordinates: [
        [
          [
            13.31916332244873,
            52.50796756998264,
          ],
          [
            13.336544036865234,
            52.50796756998264,
          ],
          [
            13.336544036865234,
            52.51726547416385,
          ],
          [
            13.31916332244873,
            52.51726547416385,
          ],
          [
            13.31916332244873,
            52.50796756998264,
          ],
        ],
      ],
      type: 'Polygon',
    },
    features: {
    },
    menus: [
      {
        icon: 'menu',
        id: 'main',
        items: [
          {
            icon: 'search',
            route: '/search',
            title: 'search',
            translations: {
              de: {
                title: 'Suche',
              },
              en: {
                title: 'search',
              },
            },
          },
          {
            icon: 'map',
            route: '/map',
            title: 'campus map',
            translations: {
              de: {
                title: 'Campus Karte',
              },
              en: {
                title: 'campus map',
              },
            },
          },
          {
            icon: 'cafe',
            route: '/canteen',
            title: 'canteen',
            translations: {
              de: {
                title: 'Mensa',
              },
              en: {
                title: 'canteen',
              },
            },
          },
        ],
        name: 'main menu',
        translations: {
          de: {
            name: 'Hauptmenü',
          },
          en: {
            name: 'main menu',
          },
        },
      },
      {
        icon: 'person',
        id: 'personal',
        items: [
          {
            icon: 'settings',
            route: '/settings',
            title: 'settings',
            translations: {
              de: {
                title: 'Einstellungen',
              },
              en: {
                title: 'settings',
              },
            },
          },
          {
            icon: 'information',
            route: '/about',
            title: 'about',
            translations: {
              de: {
                title: 'Über StApps',
              },
              en: {
                title: 'About StApps',
              },
            },
          },
        ],
        name: 'Your Study-App',
        translations: {
          de: {
            name: 'Deine Studi-App',
          },
          en: {
            name: 'Your Study-App',
          },
        },
      },
    ],
    name: 'StApps - Technische Universität Berlin',
    privacyPolicyUrl: 'https://stappsbe01.innocampus.tu-berlin.de/_static/privacy.md',
    settings: [
      {
        categories: ['profile'],
        defaultValue: 'student',
        description: 'The user group the app is going to be used.'
          + 'This settings for example is getting used for the predefined price category of mensa meals.',
        inputType: SCSettingInputType.SingleChoice,
        name: 'group',
        order: 1,
        origin: {
          indexed: '2018-09-11T12:30:00Z',
          name: 'Dummy',
          type: SCThingOriginType.Remote,
        },
        translations: {
          de: {
            description: 'Mit welcher Benutzergruppe soll die App verwendet werden?'
              + ' Die Einstellung wird beispielsweise für die Vorauswahl der Preiskategorie der Mensa verwendet.',
            name: 'Gruppe',
            values: [
              'Student',
              'Angestellter',
              'Gast',
            ],
          },
          en: {
            description: 'The user group the app is going to be used.'
              + 'This settings for example is getting used for the predefined price category of mensa meals.',
            name: 'Group',
            values: [
              'Student',
              'Employee',
              'Guest',
            ],
          },
        },
        type: SCThingType.Setting,
        uid: '2c97aa36-4aa2-43de-bc5d-a2b2cb3a530e',
        values: ['student', 'employee', 'guest'],
      },
      {
        categories: ['profile'],
        defaultValue: 'en',
        description: 'The language this app is going to use.',
        inputType: SCSettingInputType.SingleChoice,
        name: 'language',
        order: 0,
        origin: {
          indexed: '2018-09-11T12:30:00Z',
          name: 'Dummy',
          type: SCThingOriginType.Remote,
        },
        translations: {
          de: {
            description: 'Die Sprache in der die App angezeigt wird.',
            name: 'Sprache',
            values: [
              'Deutsch',
              'English',
            ],
          },
          en: {
            description: 'The language this app is going to use.',
            name: 'Language',
            values: [
              'Deutsch',
              'English',
            ],
          },
        },
        type: SCThingType.Setting,
        uid: 'dc9d6dec-6576-45ef-9e35-3598c0d6a662',
        values: ['de', 'en'],
      },
    ],
  },
  auth: {},
  backend: {
    SCVersion: packageJson.dependencies['@openstapps/core'],
    externalRequestTimeout: 5000,
    hiddenTypes: [
      SCThingType.DateSeries,
      SCThingType.Diff,
      SCThingType.Floor,
    ],
    mappingIgnoredTags: [],
    maxMultiSearchRouteQueries: 5,
    maxRequestBodySize: 512 * 1024,
    name: 'Technische Universität Berlin',
    namespace: '909a8cbc-8520-456c-b474-ef1525f14209',
    sortableFields: [
      {
        fieldName: 'name',
        sortTypes: ['ducet'],
      },
      {
        fieldName: 'type',
        sortTypes: ['ducet'],
      },
      {
        fieldName: 'categories',
        onlyOnTypes: [
          SCThingType.AcademicEvent,
          SCThingType.Building,
          SCThingType.Catalog,
          SCThingType.Dish,
          SCThingType.PointOfInterest,
          SCThingType.Room,
        ],
        sortTypes: ['ducet'],
      },
      {
        fieldName: 'geo.point.coordinates',
        onlyOnTypes: [
          SCThingType.Building,
          SCThingType.PointOfInterest,
          SCThingType.Room,
        ],
        sortTypes: ['distance'],
      },
      {
        fieldName: 'geo.point.coordinates',
        onlyOnTypes: [
          SCThingType.Building,
          SCThingType.PointOfInterest,
          SCThingType.Room,
        ],
        sortTypes: ['distance'],
      },
      {
        fieldName: 'inPlace.geo.point.coordinates',
        onlyOnTypes: [
          SCThingType.DateSeries,
          SCThingType.Dish,
          SCThingType.Floor,
          SCThingType.Organization,
          SCThingType.PointOfInterest,
          SCThingType.Room,
          SCThingType.Ticket,
        ],
        sortTypes: ['distance'],
      },
      {
        fieldName: 'offers',
        onlyOnTypes: [
          SCThingType.Dish,
        ],
        sortTypes: ['price'],
      },
    ],
  },
};

/* eslint-enable no-magic-numbers */

/**
 * TODO
 */
@Injectable()
export class FakeBackendInterceptor implements HttpInterceptor {

  /**
   * Delay time of faked responses
   */
  RESPONSE_DELAY = 1000;

  /**
   * TODO
   */
  sampleFetcher: SampleThings;

  constructor(http: HttpClient) {
    this.sampleFetcher = new SampleThings(http);
  }

  /**
   * TODO
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (request.method === 'POST') {
      if (request.url.endsWith('/') && request.method === 'POST') {
        // respond with expected (faked) index response
        return of(new HttpResponse({status: 200, body: sampleIndexResponse}));
        // respond with a search response with sample data
      }
      if (request.url.endsWith('/search')) {
        if (typeof request.body.filter !== 'undefined' && typeof request.body.filter.arguments !== 'undefined') {
          if (request.body.filter.arguments.field === 'uid') {
            return this.sampleFetcher.getSampleThing(request.body.filter.arguments.value)
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    .pipe(map((sampleData: any) => {
              return new HttpResponse({status: 200, body: {data: sampleData}});
            }), delay(this.RESPONSE_DELAY)); // add delay for skeleton screens to be seen (see !16)
          }
        }

        return this.sampleFetcher.getSampleThings(request.body.filter)
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
          .pipe(map((sampleData: any) => {
            return new HttpResponse({status: 200, body: {data: sampleData, facets: facetsMock}});
          }), delay(this.RESPONSE_DELAY)); // add delay for skeleton screens to be seen (see !16)
      }
    }

    return next.handle(request);
  }
}

export const fakeBackendProvider = {
  multi: true,
  provide: HTTP_INTERCEPTORS,
  useClass: FakeBackendInterceptor,
};
