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();
  }

  private processAccessToken( accessToken: string ) {
    const jwtHelper: JwtHelper = new JwtHelper();
    const decoded: any = jwtHelper.decodeToken(accessToken);
    const user: User = new User();      
    user.id = decoded.sub;
    user.username = decoded.preferred_username;
    user.itemName = decoded.preferred_username;
    let firstName = decoded.given_name;       
    if (!firstName) {
      firstName = '';        
    }
    let lastName = decoded.family_name;       
    if (!lastName) {
      lastName = '';        
    }        

    user.name = firstName + ' ' + lastName;

    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);
}

  /**
   * 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) {
        this.processAccessToken( 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']);
    }
  }
}
