import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';
import { SessionContext } from './common/session-context';
import { Globals } from './common/globals';
import { BaseDataLoaderService } from './services/jobs/base-data-loader.service';
import { MessageService, MessageDefines } from './services/message.service';
import { JwtHelper } from 'angular2-jwt';
import { User } from './model/user';
import { HttpResponseInterceptorService } from './services/http-response-interceptor.service';
import { ReminderCallerJobService } from './services/jobs/reminder-caller-job.service';
import { ImportFileCallerService } from './services/jobs/import-file-caller.service';
import { BannerMessage } from './common/banner-message';
import { BannerMessageStatusEn } from './common/enums';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
  title = 'app works!';
  private bannerMessageStatus = BannerMessageStatusEn;

  constructor(private http: Http, public router: Router,
    public baseDataLoader: BaseDataLoaderService,
    private activatedRoute: ActivatedRoute,    
    public httpInterceptor: HttpResponseInterceptorService,    
    private sessionContext: SessionContext,
    private messageService: MessageService,
    public reminderCallerJobService: ReminderCallerJobService,
    public importFileCallerService: ImportFileCallerService) {

    this.http.get('assets/settings.json')
      .subscribe(res => this.sessionContext.settings = res.json());

    this.sessionContext.centralHttpResultCode$.subscribe(rc => {
      this.onRcFromHttpService(rc);
    });

  }

  ngOnInit() {
    this.extractTokenFromParameters();
  }


  /**
   * Extract the params (suscribe to router event) and store them in the sessionContext.
   */
  private extractTokenFromParameters() {
    this.activatedRoute.params.subscribe((params: Params) => {
      const accessToken = this.getParametersFromUrl();
      if (accessToken) {
        const jwtHelper: JwtHelper = new JwtHelper();
        const decoded: any = jwtHelper.decodeToken(accessToken);
        const user: User = new User();
        user.username = decoded.preferred_username;
        user.itemName = decoded.preferred_username;
        user.name = decoded.given_name + ' ' + decoded.family_name;
  
        if (decoded.realm_access.roles.filter(s => s === Globals.OAUTH2CONF_SUPERUSER_ROLE).length >= 1) {
          user.specialUser = true;
        }
  
        this.sessionContext.setCurrUser(user);
        this.sessionContext.setAccessToken(accessToken);

      }  
      this.messageService.loginLogoff$.emit(MessageDefines.MSG_LOG_IN_SUCCEEDED);     
    });

  }

  private getParametersFromUrl() {
    const parameter = window.location.search.substr(1);
    return parameter != null && parameter !== '' ? this.readParamAccessToken(parameter) : null;
  }

  private readParamAccessToken(prmstr) {
    const params = {};
    const prmarr = prmstr.split('&');
    for (let i = 0; i < prmarr.length; i++) {
      const tmparr = prmarr[i].split('=');
      params[tmparr[0]] = tmparr[1];
    }
    return params['accessToken'];
  }

  //TODO redirect to Portal as login component has been removed.
  //handle different adresses for redirect (test, local, production environment)
  private onRcFromHttpService(rc: number): void {
    if (rc === 401) {
      this.router.navigate(['/logout']);
    }
  }
}
