import { Injectable, Injector } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import {
  StatsResp,
  StatsByDzResp,
  StatsByAircraftResp,
  StatsByJumpTypeResp,
  StatsByGearResp,
  StatsByYearResp,
  StatsForLastMonthResp,
  StatsForLastYearResp,
  SimpleSummary
} from '../models/stats';

import { BaseService } from './base.service';


@Injectable()
export class StatsService extends BaseService {
  constructor(private http: HttpClient) {
    super();
  }

  public getStatsOfJumps(): StatsResp {
    const resultats = new StatsResp();

    resultats.simpleSummary = this.getSimpleSummary();

    resultats.statsByDz = this.getStatsByDz();
    resultats.statsByAircraft = this.getStatsByAircraft();
    resultats.statsByJumpType = this.getStatsByJumpType();
    resultats.statsByGear = this.getStatsByGear();
    resultats.statsByYear = this.getStatsByYear();

    resultats.statsForLastYear = this.getStatsOfLastYear();
    resultats.statsForLastMonth = this.getStatsOfLastMonth();

    return resultats;
  }

  private getSimpleSummary(): Observable<SimpleSummary> {
    return this.http
      .get<Array<SimpleSummary>>(`${this.apiUrl}/Stats/Simple`, {
        headers: this.headers
      })
      .pipe(
        map(response => {
          const stats = new SimpleSummary(response);
          return stats;
        })
      );
  }

  private getStatsByDz(): Observable<Array<StatsByDzResp>> {
    return this.http
      .get<Array<StatsByDzResp>>(`${this.apiUrl}/Stats/ByDz`, {
        headers: this.headers
      })
      .pipe(
        map(response => {
          const stats = response.map(data => new StatsByDzResp(data));
          return stats;
        })
      );
  }

  private getStatsByAircraft(): Observable<Array<StatsByAircraftResp>> {
    return this.http
      .get<Array<StatsByAircraftResp>>(
        `${this.apiUrl}/Stats/ByAircraft`,
        { headers: this.headers }
      )
      .pipe(
        map(response => {
          const stats = response.map(data => new StatsByAircraftResp(data));
          return stats;
        })
      );
  }

  private getStatsByJumpType(): Observable<Array<StatsByJumpTypeResp>> {
    return this.http
      .get<Array<StatsByJumpTypeResp>>(
        `${this.apiUrl}/Stats/ByJumpType`,
        { headers: this.headers }
      )
      .pipe(
        map(response => {
          const stats = response.map(data => new StatsByJumpTypeResp(data));
          return stats;
        })
      );
  }

  private getStatsByGear(): Observable<Array<StatsByGearResp>> {
    return this.http
      .get<Array<StatsByGearResp>>(`${this.apiUrl}/Stats/ByGear`, {
        headers: this.headers
      })
      .pipe(
        map(response => {
          const stats = response.map(data => new StatsByGearResp(data));
          return stats;
        })
      );
  }

  private getStatsByYear(): Observable<Array<StatsByYearResp>> {
    return this.http
      .get<Array<StatsByYearResp>>(`${this.apiUrl}/Stats/ByYear`, {
        headers: this.headers
      })
      .pipe(
        map(response => {
          const stats = response.map(data => new StatsByYearResp(data));
          return stats;
        })
      );
  }

  private getStatsOfLastYear(): Observable<StatsForLastYearResp> {
    return this.http
      .get<StatsForLastYearResp>(
        `${this.apiUrl}/Stats/ForLastYear`,
        { headers: this.headers }
      )
      .pipe(
        map(response => {
          const statsByDz = response.byDz.map(data => new StatsByDzResp(data));
          const statsByJumpType = response.byJumpType.map(
            data => new StatsByDzResp(data)
          );

          return new StatsForLastYearResp(statsByDz, statsByJumpType);
        })
      );
  }

  private getStatsOfLastMonth(): Observable<StatsForLastMonthResp> {
    return this.http
      .get<StatsForLastYearResp>(
        `${this.apiUrl}/Stats/ForLastMonth`,
        { headers: this.headers }
      )
      .pipe(
        map(response => {
          const statsByDz = response.byDz.map(data => new StatsByDzResp(data));
          const statsByJumpType = response.byJumpType.map(
            data => new StatsByDzResp(data)
          );

          return new StatsForLastMonthResp(statsByDz, statsByJumpType);
        })
      );
  }
}
