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 { NotificationService } from '@shared/ui-api/notification.service';
import { PermissionsSetsApiService } from '@fleio-api/core/permissions/permissions-sets-api.service';
import { IUserGroupModel } from '@fleio-api/client-user/model/user-group.model';
import { UserGroupsApiService } from '@fleio-api/client-user/user-group/user-groups-api.service';
import { IGroupPermissionsModel } from '@fleio-api/core/permissions/model/group-permissions.model';
import { UiHelper } from '@shared/ui-api/helpers/ui-helper';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-user-groups-authorization',
  templateUrl: './user-groups-authorization.component.html',
  styleUrls: ['./user-groups-authorization.component.scss']
})
export class UserGroupsAuthorizationComponent
  extends DetailsComponentBase<IBaseFleioObjectModel> implements OnInit, OnDestroy {
  userGroupAuthorizationForm = this.formBuilder.group({
    userGroup: ['', Validators.required],
  });
  groupPermissions: IGroupPermissionsModel;
  selectedUserGroup: IUserGroupModel;
  userGroupSelectedPlaceholder = $localize`User group`;
  userGroupUnselectedPlaceholder = $localize`Select user group ...`;
  hasUserGroups = true;
  groupsSubscription: Subscription;

  constructor(private formBuilder: UntypedFormBuilder,
              public userGroupsApiService: UserGroupsApiService,
              private notificationService: NotificationService,
              private permissionsSetsApiService: PermissionsSetsApiService,
  ) {
    super();
  }

  newGroupSelected(userGroup) {
    this.selectedUserGroup = userGroup;
    this.refreshAllPermissions();
  }

  refreshAllPermissions() {
    if (this.selectedUserGroup) {
      this.objectController.loading = true;
      this.permissionsSetsApiService.groupPermissions(this.selectedUserGroup.id).subscribe(groupPermissions => {
        this.groupPermissions = groupPermissions;
      }).add(() => {
        this.objectController.loading = false;
      });
    }
  }

  showPermissionOptions() {
    return this.groupPermissions?.permissions && this.selectedUserGroup;
  }

  saveUserGroupPermissions() {
    if (!this.selectedUserGroup) {
      this.notificationService.showMessage($localize`Please select an user group.`);
    }
    this.objectController.loading = true;
    // get permissions out of categories
    const permissionsToBeSaved = JSON.parse(JSON.stringify(this.groupPermissions));
    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.saveGroupPermissions(permissionsToBeSaved).subscribe(response => {
      this.notificationService.showMessage($localize`User group permissions saved`);
    }, error => {
      this.notificationService.showMessage(error.error.detail);
    }).add(() => {
      this.objectController.loading = false;
    });
  }

  ngOnInit(): void {
    super.ngOnInit();
    this.userGroupAuthorizationForm.controls.userGroup.valueChanges.subscribe(value => {
      if (value && value.id) {
        this.newGroupSelected(value);
      } else {
        this.groupPermissions = null;
      }
    });
  }

  protected initTabData() {
    super.initTabData();
    this.groupsSubscription = this.userGroupsApiService.list().subscribe(value => {
      this.hasUserGroups = !!value?.objects?.length;
      UiHelper.focusAndSelectFirstInput(this.elementRef, this.changeDetector, true);
    });
  }

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