import { Component, inject, OnInit, ElementRef } 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 } from '@angular/forms';
import { NgSelectModule } from '@ng-select/ng-select';

import { AlertError } from 'app/shared/alert/alert-error.model';
import { EventManager, EventWithContent } from 'app/core/util/event-manager.service';
import { DataUtils, FileLoadError } from 'app/core/util/data-util.service';
import { IUser } from 'app/entities/user/user.model';
import { UserService } from 'app/entities/user/service/user.service';
import { IOrganizationType } from 'app/entities/organization-type/organization-type.model';
import { OrganizationTypeService } from 'app/entities/organization-type/service/organization-type.service';
import { OrganizationService } from '../service/organization.service';
import { IOrganization } from '../organization.model';
import { OrganizationFormService, OrganizationFormGroup } from './organization-form.service';
import { OrganizationNature } from 'app/entities/enumerations/organization-nature.model';

@Component({
  standalone: true,
  selector: 'jhi-organization-update',
  templateUrl: './organization-update.component.html',
  imports: [SharedModule, FormsModule, ReactiveFormsModule, NgSelectModule],
})
export class OrganizationUpdateComponent implements OnInit {
  // Properties with defaults by router
  parentOrganizationDefault : IOrganization | null = null;
  organizationTypeDefault : IOrganizationType | null = null;
  
  // Needed to make the enum OrganizationNature accessible to the template
  organizationNature = OrganizationNature;
  
  isSaving = false;
  organization: IOrganization | null = null;

  usersSharedCollection: IUser[] = [];
  organizationsSharedCollection: IOrganization[] = [];
  organizationTypesSharedCollection: IOrganizationType[] = [];

  protected dataUtils = inject(DataUtils);
  protected eventManager = inject(EventManager);
  protected organizationService = inject(OrganizationService);
  protected organizationFormService = inject(OrganizationFormService);
  protected userService = inject(UserService);
  protected organizationTypeService = inject(OrganizationTypeService);
  protected elementRef = inject(ElementRef);
  protected activatedRoute = inject(ActivatedRoute);

  // eslint-disable-next-line @typescript-eslint/member-ordering
  editForm: OrganizationFormGroup = this.organizationFormService.createOrganizationFormGroup();

  compareUser = (o1: IUser | null, o2: IUser | null): boolean => this.userService.compareUser(o1, o2);

  compareOrganization = (o1: IOrganization | null, o2: IOrganization | null): boolean =>
    this.organizationService.compareEntity(o1, o2);

  compareOrganizationType = (o1: IOrganizationType | null, o2: IOrganizationType | null): boolean =>
    this.organizationTypeService.compareEntity(o1, o2);

  ngOnInit(): void {
    this.activatedRoute.data.subscribe(({ organization }) => {
      this.organization = organization;
      if (organization) {
		// Set defaults. Important for html form behavior
		this.parentOrganizationDefault = organization.parent;
  	    this.organizationTypeDefault = organization.organizationType;
  
		// Editing an existing Organization
        this.updateForm(organization);
        this.loadRelationshipsOptions();	// Load all relations
      } else {
		// Create a new Organization
		// Router parameter's ?
		this.activatedRoute.queryParams.subscribe(params => {
      	  const parentOrganizationId = params['parentOrganizationId'];      	  
      	  if (parentOrganizationId) {
			// Load the Parent Organization list (only this one)
			this.loadRelationshipsOptionsOrganization(Number(parentOrganizationId));
		  } else {
			// No default. Load the list
			this.loadRelationshipsOptionsOrganization(null);
		  }
		  
		  const organizationTypeId = params['organizationTypeId'];
		  if (organizationTypeId) {
			// Load the OrganizationType list (only this one)
			this.loadRelationshipsOptionsOrganizationType(Number(organizationTypeId));
		  } else {
			// No default. Load the list
			this.loadRelationshipsOptionsOrganizationType(null);
		  }
		  
    	});
	  }

      this.loadRelationshipsOptions();
    });
  }

  byteSize(base64String: string): string {
    return this.dataUtils.byteSize(base64String);
  }

  openFile(base64String: string, contentType: string | null | undefined): void {
    this.dataUtils.openFile(base64String, contentType);
  }

  setFileData(event: Event, field: string, isImage: boolean): void {
    this.dataUtils.loadFileToForm(event, this.editForm, field, isImage).subscribe({
      error: (err: FileLoadError) =>
        this.eventManager.broadcast(new EventWithContent<AlertError>('resilientApp.error', { ...err, key: 'error.file.' + err.key })),
    });
  }

  clearInputImage(field: string, fieldContentType: string, idInput: string): void {
    this.editForm.patchValue({
      [field]: null,
      [fieldContentType]: null,
    });
    if (idInput && this.elementRef.nativeElement.querySelector('#' + idInput)) {
      this.elementRef.nativeElement.querySelector('#' + idInput).value = null;
    }
  }

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

  save(): void {
    this.isSaving = true;
    const organization = this.organizationFormService.getOrganization(this.editForm);
    if (organization.id !== null) {
      this.subscribeToSaveResponse(this.organizationService.update(organization));
    } else {
      this.subscribeToSaveResponse(this.organizationService.create(organization));
    }
  }

  protected subscribeToSaveResponse(result: Observable<HttpResponse<IOrganization>>): 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(organization: IOrganization): void {
    this.organization = organization;
    this.organizationFormService.resetForm(this.editForm, organization);

    this.usersSharedCollection = this.userService.addUserToCollectionIfMissing<IUser>(this.usersSharedCollection, organization.user);
    this.organizationsSharedCollection = this.organizationService.addEntityToCollectionIfMissing<IOrganization>(
      this.organizationsSharedCollection,
      organization.parent,
    );
    this.organizationTypesSharedCollection = this.organizationTypeService.addEntityToCollectionIfMissing<IOrganizationType>(
      this.organizationTypesSharedCollection,
      organization.organizationType,
    );
  }

  protected loadRelationshipsOptions(): void {
    this.loadRelationshipsOptionsUser();
	this.loadRelationshipsOptionsOrganization(null);
	this.loadRelationshipsOptionsOrganizationType(null);
  }
  
  protected loadRelationshipsOptionsUser(): void {
    this.userService
      .queryForOrganization()
      .pipe(map((res: HttpResponse<IUser[]>) => res.body ?? []))
      .pipe(map((users: IUser[]) => this.userService.addUserToCollectionIfMissing<IUser>(users, this.organization?.user)))
      .subscribe((users: IUser[]) => (this.usersSharedCollection = users));
  }
  
  protected loadRelationshipsOptionsOrganization(parentOrganizationId: number | null): void {
    this.organizationService
      .query()
      .pipe(map((res: HttpResponse<IOrganization[]>) => res.body ?? []))
      .pipe(
        map((organizations: IOrganization[]) =>
          this.organizationService.addEntityToCollectionIfMissing<IOrganization>(organizations, this.organization?.parent),
        ),
      )
      .subscribe((organizations: IOrganization[]) => {
		this.organizationsSharedCollection = organizations;
		
		if (parentOrganizationId) {
		  this.parentOrganizationDefault = this.organizationsSharedCollection.find(org => org.id === parentOrganizationId) ?? null;
		  this.editForm.patchValue({ parent: this.parentOrganizationDefault });
		}
	  });
  }
  
  protected loadRelationshipsOptionsOrganizationType(organizationTypeId: number | null): void {
    this.organizationTypeService
      .query()
      .pipe(map((res: HttpResponse<IOrganizationType[]>) => res.body ?? []))
      .pipe(
        map((organizationTypes: IOrganizationType[]) =>
          this.organizationTypeService.addEntityToCollectionIfMissing<IOrganizationType>(
            organizationTypes,
            this.organization?.organizationType,
          ),
        ),
      )
      .subscribe((organizationTypes: IOrganizationType[]) => {
		this.organizationTypesSharedCollection = organizationTypes;
		
		if (organizationTypeId) {
		  this.organizationTypeDefault = this.organizationTypesSharedCollection.find(orgType => orgType.id === organizationTypeId) ?? null;
		  this.editForm.patchValue({ organizationType: this.organizationTypeDefault });
		}
	  });
  }

  userSearchFn = (term: string, item: any) => {
    term = term.toLowerCase();
    return (item.login + "( " + item.email + " )").toLowerCase().includes(term);
  };
}
