import { Location } from '@angular/common';
import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { Directive, Input, NgModule } from '@angular/core';
import { AbstractControl, FormControl, FormGroup, FormsModule, NgForm, NgModel, Validators } from '@angular/forms';
// import { UniqueSelectionDispatcher } from '@angular/material';
import { ActivatedRoute, Router } from '@angular/router';

import { IApiError, RouterExtService, TokenService } from '../core/shared';
import { ICountry } from '../core/shared/country/country.model';
import { CountryService } from '../core/shared/country/country.service';

import { ICreateUser, User } from '../core/shared/user/user.model';
import { UserService } from '../core/shared/user/user.service';

import { TranslateService } from '@ngx-translate/core';
import { ILanguage, ILanguages } from '../core/shared/language/language.model';
import { LanguageService } from '../core/shared/language/language.service';

import { BaseComponent } from '../core/components/base.component';
import { IApiResponseError } from '../core/shared/token/apiresponse.model';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';

@Component({
  // providers: [UniqueSelectionDispatcher],
  selector: 'knk-registration',
  styleUrls: ['./registration.component.scss'],
  templateUrl: './registration.component.pug'
})
export class RegistrationComponent implements OnInit, OnDestroy {
  lang: string;
  user: ICreateUser;
  submitAttempt: boolean = false;
  registrationError: { id: number, msg: string } = null;
  languages: ILanguage[];
  phoneFull: string;
  phoneFocused: boolean = false;
  private ngUnsubscribe: Subject<void> = new Subject<void>();

  constructor(private router: Router,
              private activatedRoute: ActivatedRoute,
              private routerExt: RouterExtService,
              private tokenService: TokenService,
              private userService: UserService,
              private countryService: CountryService,
              private languageService: LanguageService,
              private translateService: TranslateService) {
    this.user = {userName: '', email: '', password: ''};
  }

  ngOnInit(): void {
    this.lang = this.translateService.currentLang || this.translateService.defaultLang;

    // this.countryService.Country.subscribe((country: ICountry) => {
    //   if (country) {
    //     this.user.countryId = country.countryId;
    //     this.user.phonePrefix = country.phonePrefix;
    //     this.phoneFull = country.phonePrefix;
    //   } else {
    //     console.log('Country code is not found');
    //   }
    // });

    this.languageService.Languages.subscribe((languages: ILanguages) => {
      this.languages = languages.items;
      languages.items.forEach(function (lang: ILanguage, key: number): void {
        if (lang.languageCode === this.lang) {
          this.user.languageId = lang.languageId;
          return;
        }
      }, this);
    });
  }

  ngOnDestroy(): void {
    this.ngUnsubscribe.next();
    this.ngUnsubscribe.complete();
  }

  register(): void {
    // e.preventDefault();
    this.registrationError = null;

    // todo: should I?
    /*if (this.user['userName']) {
      let names: string[] = this.user['userName'].split(/\s+/);
      this.user['firstName'] = names[0];
      this.user['lastName'] = names[1];
    }

    if (!this.user['birthDate']) {
      this.user['birthDate'] = new Date('01/01/1991');
    }

    if (!this.user['phonePrefix']) {
      this.user['phonePrefix'] = '8';
    }

    if (!this.user['phone']) {
      this.user['phone'] = '8008008080';
    }

    if (!this.user['gender']) {
      this.user['gender'] = '1';
    }*/

    // this.user.isUSTaxEntity = false;
    // this.user.kycApproved = false;
    // this.user.phoneVerified = false;
    // this.user.mailVerfied = false;
    // this.user.termsOfServiceChecked = false;

    this.userService.createUser(this.user).subscribe(
      (user) => {
        this.tokenService.apiUserToken(user).subscribe(() => {
          this.goToHome();
        });
      },
      (err: IApiResponseError) => {
        let error: IApiError = err.error;
        if (error.id === -1) {
          error.msg = 'An error occurs on the server. Try again later.';
        }
        this.registrationError = err.error;
      });
  }

  onSubmit(form: NgForm): void {
    this.submitAttempt = true;
    if (form.valid) {
      this.parsePhone();
      Observable.timer(1000).takeUntil(this.ngUnsubscribe).subscribe((): void => {
        this.ngUnsubscribe.next();
        this.register();
      });
    } else {
      this.registrationError = {id: -1, msg: 'Please fill all required fields.'};
    }
  }

  getErrorMessage(p: FormControl, key: string): string {
    if (p.hasError('required')) {
      if (key) {
        return 'You must enter a value for \"' + this.translateService.instant(key) + '\"';
      } else {
        return 'You must enter a value';
      }
    }

    if (p.hasError('confirmInvalid')) {
      if (key.match(/(password)/i)) {
        return 'Passwords do not match';
      } else {
        return 'Input confirm is invalid';
      }
    }

    if (p.hasError('patternInvalid')) {
      return 'Input format is invalid';
    }
    // let val: string = 'You must enter a value for ' +  this.translateService.instant['[user name]'];
    // if (name) {
    //    this.translateService.get('[user name]').flatMap((res: string)  => {
    //        console.log('dddddddddd');
    //        return val += name + res;
    //    });
    // }
    // return p.hasError('required') ? 'You must enter a value' :
    //    p.hasError('email') ? 'Not a valid email' : '';
  }

  parsePhone(): void {
    // if (this.phoneFull) {
    //   let p: string = this.phoneFull.replace(/\s+|-|\+/g, '');
    //   if (p.length >= 7) {
    //     this.user.phonePrefix = p.substr(0, p.length - 7);
    //     this.user.phone = p.substr(p.length - 7);
    //   }
    // }
  }

  close(): void {
    this.goToPrevious();
  }

  goToPrevious(): void {
    let previous: string = this.routerExt.getPreviousUrl();
    if (previous) {
      this.router.navigateByUrl(previous);
    } else {
      this.goToHome();
    }
  }

  goToHome(): void {
    this.routerExt.goToHome();
  }

  isFormExists(form: FormGroup | NgForm): boolean {
    return (form instanceof FormGroup) || (form instanceof NgForm);
  }

  isFormValid(form: FormGroup | NgForm): boolean {
    return (this.isFormExists(form) && form.valid);
  }

  isControlExists(control: AbstractControl | NgModel): boolean {
    return (control instanceof AbstractControl) || (control instanceof NgModel);
  }

  isControlDirtyOrTouched(control: AbstractControl | NgModel): boolean {
    return (this.isControlExists(control) && (control.dirty || control.touched));
  }
}
