import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Http} from '@angular/http';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Headers} from '@angular/http';
import {CookieService} from 'ngx-cookie-service';
import {User, UsersService} from '../components/user/users/users.service';
import {TypesService} from '../components/basic/types/types.service';
import {RolesService} from '../components/user/roles/roles.service';
import {Router} from '@angular/router';
import {GlobalService} from './global.service';
import {environment} from '../../environments/environment';
import {MessageService} from './message.service';


@Injectable()
export class AuthService {
  auth: AuthService;
  currentUser: any = new BehaviorSubject(false);
  cloud_token = new BehaviorSubject('');
  firebase;


  /**
   * @param {Http} http  baray darkhadt hay http estefade mishe
   * @param {CookieService} cookieService baray save kardan token
   */
  constructor(private http: Http,
              private cookieService: CookieService,
              private router: Router,
              private userService: UsersService,
              private typeService: TypesService,
              private roleService: RolesService,
              private global: GlobalService,
              private MessageService: MessageService,
  ) {
    this.cloud_token.subscribe(x => {
      if (x) {
        this.firebase = x;
      }
    });

    this.typeService.register();
    this.roleService.register();
  }

  /**
   *
   * @param username email user hast
   * @param password
   * @param type type user hast mesl dr ya parastar
   * @param cloud_token
   * @param remember
   * @returns {Observable<boolean>}
   */

  login(username, password, type, cloud_token, remember): Observable<boolean> {
    const headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    return this.http.post(environment.app_url + 'login',
      'username=' + (username) + '&password=' + (password) +
      '&type=' + (type) + '&cloud_token=' + (cloud_token),
      {headers: headers})
      .map(res => res.json())
      .map(res => {
        if (res) {
          this.currentUser.next(this.convertUserFromText(res['user']));
          this.global.tokenLogin = res['token'];
          this.setLoginParams(res, remember, true);
        }
        return this.isLoggedIn();
      });
  }

  getUser(): User {
    const user = localStorage.getItem('user');
    if (user) {
      const us: User = this.convertUserFromText(user);
      return us;
    }
    return null;
  }


  setUser(user: string) {
    if (user === '') {
      localStorage.removeItem('user');
    }
    localStorage.setItem('user', user);
  }

  /**
   * auth token
   */
  getToken(): string {
    return this.cookieService.get('token');
  }

  /**
   * auth token
   */


  setToken(token: string, remember: boolean) {
    if (token === '') {
      this.cookieService.delete('token');
      localStorage.removeItem('token');
    } else {
      this.cookieService.set('token', token, remember ? 60 : 0);
      localStorage.setItem('token', token);
    }
  }


  isLoggedIn(): boolean {
    return !!this.getUser();
  }

  logout() {
    this.setUser('');
    this.setToken('', false);
    if (!this.isLoggedIn()) {
      this.router.navigateByUrl('/auth/signin');
    } else {
      // tood ino test kon
      this.router.navigateByUrl('');
      return false;
    }
  }

  convertUserFromText(userString: string): User {
    const userObj = this.userService.new();
    if (userString !== 'null') {
      this.userService.convert(JSON.parse(userString), userObj);
    }
    return userObj;
  }

  /**
   *
   * @returns {Observable<boolean>}
   */
  init(cloudeToken: string): Observable<boolean> {
    const headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    headers.append('Accept', 'application/vnd.api+json');
    headers.append('Authorization', 'Bearer ' + this.getToken());
    return this.http.post(environment.app_url + 'init',
      'app_packagename=' + 'hpen_web' +
      '&app_version=' + '1' +
      '&app_sdk=' + '1' +
      '&cloud_token=' + cloudeToken
      ,
      {headers: headers})
      .map(res => res.json())
      .map(res => {
        if (res) {
          this.currentUser.next(this.convertUserFromText(res['user']));
          this.setLoginParams(res, null, false);
        }
        return this.isLoggedIn();
      });
  }

  getNoAuthUrls(): string[] {
    return ['/auth/signin', '/auth/forgot'];
  }

  forgotPass1(username, type_id): Observable<any> {
    const headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    return this.http.post(environment.app_url + 'forgotpass/step1',
      'username=' + (username) + '&type_id=' + (type_id), {headers: headers});
    // todo errore cheie
    // .map(res => res.json());
  }

  forgotPass2(username, key, type_id): Observable<any> {
    const headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    return this.http.post(environment.app_url + 'forgotpass/step2',
      'username=' + (username) + '&key=' + (key) + '&type_id=' + (type_id), {headers: headers});
    // .map(res => res.json());
  }

  forgotPass3(username, type_id, sms_token): Observable<any> {
    const headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    return this.http.post(environment.app_url + 'forgotpass/step3',
      'username=' + (username) + '&type_id=' + (type_id) + '&sms_token=' + (sms_token)
      , {headers: headers});
    // .map(res => res.json());
  }


  forgotPass4(username, sms_token, password, type_id): Observable<boolean> {
    const headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    return this.http.post('https:' + environment.app_url + 'forgotpass/step4',
      'username=' + (username)
      + '&sms_token=' + (sms_token) + '&password=' + (password) + '&type_id=' + (type_id)
      , {headers: headers})
      .map(res => res.json())
      .map(res => {
        if (res) {
          this.setLoginParams(res);
        }
        return this.isLoggedIn();
      });
  }

// Bearer bayad ba fasele bashe
  // in tabe request id va status ro mifreste be server


  setLoginParams(loginResponse, remember?: boolean, fromLogin?: boolean) {
    if (remember == null) {
      remember = false;
    }
    if (fromLogin) {
      this.setToken(loginResponse['token'], remember);
    }
    localStorage.setItem('basics', JSON.stringify(loginResponse['basics']));
    localStorage.setItem('columns', JSON.stringify(loginResponse['columns']));
    this.setUser(loginResponse['user']);
    // todo for available bebinnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
    // this.currentUser.value.available = true;
    // this.currentUser.value.save();
    // this.menuService.refreshItems();
  }


  sendRequestToNurse(receiver_id, request_id, status) {
    const headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    headers.append('Accept', 'application/vnd.api+json');
    headers.append('Authorization', 'Bearer ' + this.getToken());
    return this.http.post(environment.app_url + 'center_action',
      'receiver_id=' + (receiver_id) + '&request_id=' + (request_id) + '&status=' + (status), {headers: headers})
      ;
  }
}
