import { Component, OnInit, OnDestroy, Output, EventEmitter } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable, of, Subscription } from 'rxjs';
import { catchError, exhaustMap, map, tap, take } from 'rxjs/operators';

import { NoAuthProbe } from '@overflow/commons-typescript/model/noauth';
import { AuthSelector } from '@overflow/shared/auth/store';
import { DomainMember } from '@overflow/commons-typescript/model/domain';

import { NoAuthProbeService } from '../service/noauth-probe.service';
import { NoAuthProbeSubscriber, NoAuthProbeNotify } from '../subscriber/noauth-probe.subscriber';

@Component({
  selector: 'of-noauth-probe-list',
  templateUrl: './noauth-probe-list.component.html',
})
export class NoAuthProbeListComponent implements OnInit, OnDestroy {
  pending$: Observable<boolean>;
  error$: Observable<any>;

  noauthProbes: NoAuthProbe[];
  noauthProbeSubscription: Subscription;

  @Output() select = new EventEmitter<NoAuthProbe>();

  constructor(
    private store: Store<any>,
    private noAuthProbeService: NoAuthProbeService,
    private noAuthProbeSubscriber: NoAuthProbeSubscriber,
  ) {
    this.noauthProbes = [];
    this.noauthProbeSubscription = null;
  }

  ngOnInit() {
    this.store.pipe(
      tap(() => {
        this.pending$ = of(true);
      }),
      select(AuthSelector.selectDomainMember),
      exhaustMap((domainMember: DomainMember) =>
        this.noAuthProbeService.readAllByDomainID(domainMember.domain.id)
          .pipe(
            map((noauthProbes: NoAuthProbe[]) => {
              this.setNoauthProbes(noauthProbes);
            }),
            catchError(error => {
              this.setError$(error);
              return of();
            })
          )
      ),
      tap(() => {
        this.pending$ = of(false);
      }),
      take(1),
    ).subscribe();

    this.noauthProbeSubscription = this.noAuthProbeSubscriber.observable().pipe(
      tap((noAuthProbeNotify: NoAuthProbeNotify) => {
        const noauthProbes = [];
        this.noauthProbes.forEach(noauthProbe => {
          const n = noAuthProbeNotify.params;
          if (noauthProbe.id === n.id) {
            noauthProbes.push(n);
          } else {
            noauthProbes.push(noauthProbe);
          }
        });

        this.setNoauthProbes(noauthProbes);
      }
      ),
    ).subscribe();
  }

  ngOnDestroy(): void {
    if (null !== this.noauthProbeSubscription) {
      this.noauthProbeSubscription.unsubscribe();
    }
  }

  private setNoauthProbes(noauthProbes: NoAuthProbe[]): void {
    if (null === noauthProbes) {
      return;
    }
    noauthProbes.forEach(noauthProbe => {
      noauthProbe.infraHost = JSON.parse(noauthProbe.infraHostMeta);
    });
    this.noauthProbes = noauthProbes;
    console.log(this.noauthProbes);
  }

  private setError$(error: any): void {
    this.error$ = of(error);
  }

  getOS(noauthProbe: NoAuthProbe): string {
    if (null == noauthProbe.infraHost.infraHostOS) {
      return null;
    }
    let os = noauthProbe.infraHost.infraHostOS.os;

    os += noauthProbe.infraHost.infraHostOS.platform ?
      ' (' + noauthProbe.infraHost.infraHostOS.platform + ') ' : '';
    return os;
  }

}
