import { Component, OnDestroy, OnInit } from '@angular/core';
import { DetailsComponentBase } from '@objects-view/details-component-base';
import { IBaseFleioObjectModel } from '@fleio-api/base-model/base-fleio-object.model';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { IUserModel } from '@fleio-api/client-user/model/user.model';
import { NotificationService } from '@shared/ui-api/notification.service';
import { PermissionsSetsApiService } from '@fleio-api/core/permissions/permissions-sets-api.service';
import { ConfigService } from '@shared/config/config.service';
import { IUserPermissionsModel } from '@fleio-api/core/permissions/model/user-permissions.model';
import { UiHelper } from '@shared/ui-api/helpers/ui-helper';
import { UsersApiService } from '@fleio-api/client-user/user/users-api.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-users-authorization',
  templateUrl: './users-authorization.component.html',
  styleUrls: ['./users-authorization.component.scss']
})
export class UsersAuthorizationComponent extends DetailsComponentBase<IBaseFleioObjectModel> implements OnInit, OnDestroy {
  userAuthorizationForm = this.formBuilder.group({
    user: ['', Validators.required],
  });
  userPermissions: IUserPermissionsModel;
  selectedUser: IUserModel;
  usersSubscription: Subscription;
  hasUsers = true;

  constructor(
    private formBuilder: UntypedFormBuilder,
    private notificationService: NotificationService,
    private permissionsSetsApiService: PermissionsSetsApiService,
    private usersApiService: UsersApiService,
    public config: ConfigService,
  ) {
    super();
  }

  newUserSelected(user) {
    this.selectedUser = user;
    if (user && !user.is_superuser) {
      this.refreshAllPermissions();
    }
  }

  refreshAllPermissions() {
    if (this.selectedUser) {
      this.objectController.loading = true;
      this.permissionsSetsApiService.userPermissions(this.selectedUser.id).subscribe(response => {
        this.userPermissions = response;
      }).add(() => {
        this.objectController.loading = false;
      });
    }
  }

  reloadEffectivePermissions() {
    if (this.selectedUser) {
      this.objectController.loading = true;
      this.permissionsSetsApiService.userPermissions(this.selectedUser.id).subscribe(response => {
        this.userPermissions.effective_permissions = response.effective_permissions;
      }).add(() => {
        this.objectController.loading = false;
      });
    }
  }

  showPermissionOptions(): boolean {
    return this.userPermissions?.permissions && !this.selectedUser?.is_superuser;
  }

  saveUserPermissions() {
    if (!this.selectedUser) {
      this.notificationService.showMessage($localize`Please select an user.`);
    }
    this.objectController.loading = true;
    // get permissions out of categories
    const permissionsToBeSaved = JSON.parse(JSON.stringify(this.userPermissions));
    const permissionsList = [];
    for (const panelKey of Object.keys(permissionsToBeSaved.permissions)) {
      for (const categoryKey of Object.keys(permissionsToBeSaved.permissions[panelKey])) {
        for (const permission of permissionsToBeSaved.permissions[panelKey][categoryKey]) {
          permissionsList.push(permission);
        }
      }
      permissionsToBeSaved.permissions[panelKey] = permissionsList;
    }
    this.permissionsSetsApiService.saveUserPermissions(permissionsToBeSaved).subscribe(response => {
      this.reloadEffectivePermissions();
      this.notificationService.showMessage($localize`User permissions saved`);
    }, error => {
      this.notificationService.showMessage(error.error.detail);
      this.objectController.loading = false;
    });
  }

  ngOnInit(): void {
    super.ngOnInit();
    this.userAuthorizationForm.controls.user.valueChanges.subscribe(value => {
      if (value && value.id) {
        this.newUserSelected(value);
      }
    });
  }

  protected initTabData() {
    super.initTabData();
    this.usersSubscription = this.usersApiService.list({is_superuser: false}).subscribe(value => {
      this.hasUsers = !!value?.objects?.length;
      UiHelper.focusAndSelectFirstInput(this.elementRef, this.changeDetector, true);
    });
  }

  ngOnDestroy() {
    super.ngOnDestroy();
    if (this.usersSubscription) {
      this.usersSubscription.unsubscribe();
      this.usersSubscription = null;
    }
  }

}
