import { Component, OnInit, ViewChild } from '@angular/core';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { EMPTY, of } from 'rxjs';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { IUserProfileModel } from '@fleio-api/profile/model/user-profile.model';
import { UserProfileApiService } from '@fleio-api/profile/user-profile/user-profile-api.service';
import { NotificationService } from '@shared/ui-api/notification.service';
import { IUserProfileCreateOptionsModel } from '@fleio-api/profile/model/user-profile-create-options.model';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfigService } from '@shared/config/config.service';
import { ThemingService } from '@shared/ui/theming/theming.service';
import { TokenStorageService } from '@shared/ui-api/token-storage.service';
import { IIcon } from '@shared/ui/common/interfaces/icon';
import { RefreshService } from '@shared/ui-api/refresh.service';
import { CoreApiService } from '@fleio-api/core/core-api.service';

@Component({
  selector: 'app-user-profile-edit-form',
  templateUrl: './user-profile-edit-form.component.html',
  styleUrls: ['./user-profile-edit-form.component.scss']
})
export class UserProfileEditFormComponent extends DetailsFormBase<IUserProfileModel> implements OnInit {
  @ViewChild('formErrors') formErrors;
  profileForm = this.formBuilder.group({
    first_name: ['', Validators.required],
    last_name: ['', Validators.required],
    email: ['', Validators.required],
    mobile_phone_number: [''],
    old_password: [''],
    password: [''],
    password_confirm: [''],
    language: [''],
    theme: [''],
  });
  showOldPasswordText = false;
  showPasswordText = false;
  showPasswordConfirmText = false;
  phoneNumber = '';
  createOptions: IUserProfileCreateOptionsModel;
  holdButtonTxt = $localize`Hold button to reveal password`;
  unverifiedEmailInfo: IIcon = {
    name: 'info',
    verticalAlign: 'middle',
    fontSize: '20px',
    marginLeft: '15px',
    marginTop: '19px',
    tooltipDirection: 'right',
    tooltip: $localize`Email change is waiting confirmation.\nRemove this in order to discard email change.`
  };

  constructor(private formBuilder: UntypedFormBuilder, private userProfileApiService: UserProfileApiService,
              private notificationService: NotificationService, private activatedRoute: ActivatedRoute,
              public config: ConfigService, private themingService: ThemingService,
              private router: Router, private tokenStorage: TokenStorageService,
              private refreshService: RefreshService,
              private coreApiService: CoreApiService) {
    super();
  }

  private saveProfile() {
    this.validate();
    if (this.formGroup.invalid) {
      this.displayControlErrors();
      return EMPTY;
    }
    const value = this.profileForm.value as any;
    let selectedTheme = null;
    if (value.hasOwnProperty('theme')) {
      selectedTheme = value.theme;
      delete value.theme;
    }
    if (selectedTheme) {
      this.themingService.setNewActiveTheme(selectedTheme);
    }
    let languageUpdated = false;
    if (this.object.user.language !== value.language) {
      languageUpdated = true;
    }
    const changesPass = !!(value.old_password && value.password && value.password_confirm);
    this.objectController.loading = true;
    this.userProfileApiService.putAction(
      'update',
      value
    ).subscribe({
      next: () => {
        if (changesPass) {
          this.tokenStorage.clearToken();
          if (this.authSvc.feature('ui.staff')) {
            // make sure that impersonation tokens are also removed
            this.tokenStorage.clearPanelToken('enduser');
          }
          this.router.navigateByUrl(this.config.getPanelUrl('login'));
        } else {
          this.notificationService.showMessage($localize`User profile updated.`);
          if (languageUpdated) {
            window.location.reload();
          } else {
            this.refreshService.refresh(() => {
              this.profileForm.patchValue(this.object.user);
              if (this.object.user?.unverified_email) {
                if (!this.profileForm.contains('unverified_email')) {
                  this.profileForm.addControl(
                    'unverified_email', this.formBuilder.control(this.object.user.unverified_email)
                  );
                }
              } else {
                if (this.profileForm.contains('unverified_email')) {
                  this.profileForm.removeControl('unverified_email');
                }
              }
            });
          }
        }
      }, error: error => {
        this.backendErrors = error.error;
        this.setErrors(this.backendErrors);
      }
    }).add(() => {
      this.objectController.loading = false;
    });
    return of(null);
  }

  passwordErrors() {
    if (Array.isArray(this.fieldErrors.password)) {
      return this.fieldErrors.password[0];
    }
    return this.fieldErrors.password;
  }

  resendVerificationCode() {
    this.coreApiService.resendEmailConfirmationMessage().subscribe({
      next: value => {
        this.notificationService.showMessage(value.detail);
      }, error: error => {
        this.notificationService.showMessage(error.error.detail);
      }
    });
  }

  ngOnInit() {
    super.ngOnInit();
    this.createOptions = this.activatedRoute.snapshot.data.createOptions;
    if (this.objectController) {
      this.objectController.actionCallback = () => this.saveProfile();
    }
    if (this.object) {
      this.profileForm.patchValue(this.object.user);
      if (this.object.user?.unverified_email) {
        this.profileForm.addControl(
          'unverified_email', this.formBuilder.control(this.object.user.unverified_email)
        );
      }
    }
    this.profileForm.controls.theme.setValue(this.themingService.getActiveThemeName());
    if (this.object && this.object.user.mobile_phone_number) {
      this.phoneNumber = this.object.user.mobile_phone_number;
    }
    if (this.object && [undefined, null, ''].indexOf(this.object.user.language) > -1) {
      // set the default language if missing
      if (this.config && this.config.current) {
        this.profileForm.controls.language.setValue(this.config.current.settings.defaultLanguage);
      }
    }
  }

}
