import { Component, inject, OnInit } from '@angular/core';
import { HttpResponse } from '@angular/common/http';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { finalize, map } from 'rxjs/operators';

import SharedModule from 'app/shared/shared.module';
import { FormsModule, ReactiveFormsModule, FormArray } from '@angular/forms';

import { ISecurityResource } from 'app/security/security-resource/security-resource.model';
import { ISecurityGroup } from './../security-group.model';
import { ISecurityGroupPermission, NewSecurityGroupPermission } from './../security-group-permission.model';
import { SecurityGroupService } from '../service/security-group.service';
import { SecurityResourceService } from 'app/security/security-resource/service/security-resource.service';
import { SecurityGroupFormService, SecurityGroupFormGroup } from './security-group-form.service';
import { SecurityGroupPermissionFormService } from './security-group-permission-form.service';
import { SecurityPermission } from 'app/security/security-permission.model';

@Component({
  standalone: true,
  selector: 'jhi-security-group-update',
  templateUrl: './security-group-update.component.html',
  styleUrl: './security-group-update.component.css',
  imports: [SharedModule, FormsModule, ReactiveFormsModule],
})
export class SecurityGroupUpdateComponent implements OnInit {
  isSaving = false;
  securityGroup: ISecurityGroup | null = null;
  currentTab: string = 'permissions'; // default tab
  securityPermissions = Object.keys(SecurityPermission);
  
  protected securityGroupService = inject(SecurityGroupService);
  protected securityResourceService = inject(SecurityResourceService);
  protected securityGroupFormService = inject(SecurityGroupFormService);
  protected securityGroupPermissionFormService = inject(SecurityGroupPermissionFormService);
  protected activatedRoute = inject(ActivatedRoute);

  // eslint-disable-next-line @typescript-eslint/member-ordering
  editForm: SecurityGroupFormGroup = this.securityGroupFormService.createSecurityGroupFormGroup();

  ngOnInit(): void {
    this.activatedRoute.data.subscribe(({ securityGroup }) => {
      this.securityGroup = securityGroup;
      if (securityGroup) {
        // Editing
        this.updateForm(securityGroup);
        
        // Load SecurityGroupPermission's
        this.loadSecurityGroupPermissions();
      } else {
        // New Group
        // Load empty (default) SecurityGroupPermission's
        this.loadNewSecurityGroupPermissions();
      }
      
      this.loadRelationshipsOptions();
    });
  }

  previousState(): void {
    window.history.back();
  }

  save(): void {
    this.isSaving = true;
    const securityGroup = this.securityGroupFormService.getSecurityGroup(this.editForm);
    if (securityGroup.id !== null) {
      this.subscribeToSaveResponse(this.securityGroupService.update(securityGroup));
    } else {
      this.subscribeToSaveResponse(this.securityGroupService.create(securityGroup));
    }
  }

  setTab(tabId: string): void {
    this.currentTab = tabId;
  }
  
  /* Nested collection methods : SecurityGroupPermission's  */
  /* Use it like a property : this.securityGroupPermissions */
  get securityGroupPermissions(): FormArray {
    return this.editForm.get('securityGroupPermissions') as FormArray;
  }

  removeSecurityGroupPermission(index: number): void {
    this.securityGroupPermissions.removeAt(index);
  }
  
  protected subscribeToSaveResponse(result: Observable<HttpResponse<ISecurityGroup>>): void {
    result.pipe(finalize(() => this.onSaveFinalize())).subscribe({
      next: () => this.onSaveSuccess(),
      error: () => this.onSaveError(),
    });
  }

  protected onSaveSuccess(): void {
    this.previousState();
  }

  protected onSaveError(): void {
    // Api for inheritance.
  }

  protected onSaveFinalize(): void {
    this.isSaving = false;
  }

  protected updateForm(securityGroup: ISecurityGroup): void {
    this.securityGroup = securityGroup;
    this.securityGroupFormService.resetForm(this.editForm, securityGroup);
	
    securityGroup.securityGroupPermissions?.forEach(securityGroupPermission => {
      this.securityGroupPermissions.push(this.securityGroupPermissionFormService.createSecurityGroupPermissionFormGroup(securityGroupPermission));
    });
  }
  
  protected loadRelationshipsOptions(): void {

  }
  
  protected loadSecurityGroupPermissions(): void {
    if (this.securityGroup) {
      //Load all SecurityGroupPermissions associated to this SecurityGroup
      this.securityGroupService.queryPermissions(this.securityGroup.id).subscribe({
        next: (resources: HttpResponse<ISecurityGroupPermission[]>) => {
          const permissions: ISecurityGroupPermission[] | null = resources.body;
          
          // For each SecurityResource
          permissions?.forEach(permission => {
            // #2. create a new SecurityGroupPermissionForm
            const securityGroupPermissionFormGroup = this.securityGroupPermissionFormService.createSecurityGroupPermissionFormGroup(permission)
          
            // #3. add to this.securityGroupPermissions
            this.securityGroupPermissions.push(securityGroupPermissionFormGroup);          
          });
        },
      });
    }
  }
  
  protected loadNewSecurityGroupPermissions(): void {
    //Load all SecurityResources
    this.securityResourceService.query().subscribe({
      next: (resources: HttpResponse<ISecurityResource[]>) => {
        const securityResources: ISecurityResource[] | null = resources.body;
        
        // For each SecurityResource
        securityResources?.forEach(resource => {
          // #1. create a new NewSecurityGroupPermission
          const newSecurityGroupPermission: NewSecurityGroupPermission = {
            id: null,
            securityResource: resource, 
            createPermission: resource.defaultCreatePermission,
            readPermission: resource.defaultReadPermission,
            updatePermission: resource.defaultUpdatePermission,
            deletePermission: resource.defaultDeletePermission
          };
          
          // #2. create a new SecurityGroupPermissionForm
          const newSecurityGroupPermissionFormGroup = this.securityGroupPermissionFormService.createSecurityGroupPermissionFormGroup(newSecurityGroupPermission)
        
          // #3. add to this.securityGroupPermissions
          this.securityGroupPermissions.push(newSecurityGroupPermissionFormGroup);
        });
      },
    });
    
  }
}
