import { Injectable } from '@angular/core';
import { throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { Setting } from 'src/app/model/entities/setting';
import { Apollo, gql } from 'apollo-angular';
import { Logger } from 'src/app/service/logger.service';

const log = new Logger('UserSettings');

@Injectable({
  providedIn: 'root',
})
export class SettingsService {
  constructor(private apollo: Apollo) {}

  get(key: string): Promise<string | undefined> {
    log.debug('get', key);
    return new Promise((resolve, reject) => {
      this.apollo
        .query<{ settings: Setting[] }>({
          query: gql`
            query getSetting($key: String!) {
              settings(key: $key) {
                key
                value
              }
            }
          `,
          variables: {
            key,
          },
        })
        .pipe(
          catchError(err => {
            throw err;
          })
        )
        .pipe(
          map(result =>
            result.data.settings.length > 0
              ? result.data.settings[0]
              : undefined
          )
        )
        .pipe(
          catchError(err => {
            reject(err);
            return throwError(() => err);
          })
        )
        .subscribe(setting => {
          resolve(setting?.value);
        });
    });
  }

  set(key: string, value: string): Promise<void> {
    log.debug('set', key, value);
    return new Promise((resolve, reject) => {
      this.apollo
        .mutate<{ setting: { change: Setting } }>({
          mutation: gql`
            mutation changeSetting($input: SettingInput!) {
              setting {
                change(input: $input) {
                  key
                  value
                }
              }
            }
          `,
          variables: {
            input: {
              key: key,
              value: value,
            },
          },
        })
        .pipe(
          catchError(err => {
            throw err;
          })
        )
        .pipe(map(result => result.data?.setting.change))
        .pipe(
          catchError(err => {
            reject(err);
            return throwError(() => err);
          })
        )
        .subscribe(() => {
          resolve();
        });
    });
  }
}
