import { Component, OnInit } from '@angular/core';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { IFlavorModel } from '@fleio-api/openstack/model/flavor.model';
import { UntypedFormArray, UntypedFormBuilder, Validators } from '@angular/forms';
import { FlavorsApiService } from '@fleio-api/openstack/flavor/flavors-api.service';
import { of } from 'rxjs';
import { NotificationService } from '@shared/ui-api/notification.service';

@Component({
  selector: 'app-flavor-properties-edit-form',
  templateUrl: './flavor-properties-edit-form.component.html',
  styleUrls: ['./flavor-properties-edit-form.component.scss']
})
export class FlavorPropertiesEditFormComponent extends DetailsFormBase<IFlavorModel> implements OnInit {
  flavorPropertiesForm = this.formBuilder.group({
    properties: this.formBuilder.array([])
  });
  formProperties = this.flavorPropertiesForm.get('properties') as UntypedFormArray;

  constructor(
    private formBuilder: UntypedFormBuilder,
    private flavorsApi: FlavorsApiService,
    private notificationService: NotificationService,
  ) {
    super();
  }

  propertiesDictToList(propDict: Record<string, any>) {
    for (const key in propDict) {
      if (propDict.hasOwnProperty(key)) {
        this.formProperties.push(this.formBuilder.group({
          key: this.formBuilder.control({value: key, disabled: true}, [Validators.required, Validators.maxLength(255)]),
          value: this.formBuilder.control(propDict[key], [Validators.maxLength(255)]),
        }));
      }
    }
  }

  deletePropertyFromList(index: number) {
    const properties = this.formProperties.getRawValue();
    if (!properties[index].key) {
      this.formProperties.removeAt(index);
    } else {
      this.objectController.loading = true;
      this.flavorsApi.unsetProperty(this.object.id, properties[index].key).subscribe(() => {
        this.notificationService.showMessage($localize`Successfully removed property.`);
        this.formProperties.removeAt(index);
      }, error => {
        if (error && error.status === 404) {
          this.formProperties.removeAt(index);
          this.notificationService.showMessage($localize`Removed property because it was not found.`);
        } else {
          this.notificationService.showMessage($localize`Could not remove property.`);
        }
      }).add(() => {
        this.objectController.loading = false;
      });
    }
  }

  addPropertyToList() {
    this.formProperties.push(this.formBuilder.group({
      key: this.formBuilder.control('', [Validators.required, Validators.maxLength(255)]),
      value: this.formBuilder.control('', [Validators.maxLength(255)]),
    }));
  }

  saveProperties() {
    this.validate();
    if (this.formGroup.invalid) {
      this.displayControlErrors();
      return of(null);
    }
    const value = this.flavorPropertiesForm.getRawValue();
    const propertiesDict = this.propertiesListToDict(value.properties);
    this.objectController.loading = true;
    this.flavorsApi.setProperties(this.object.id, propertiesDict).subscribe(() => {
      this.notificationService.showMessage($localize`Successfully saved properties.`);
    }, error => {
      if (error.error) {
        this.setErrors(error.error);
      }
    }).add(() => {
      this.objectController.loading = false;
    });
    return of(null);
  }

  propertiesListToDict(props: Array<{key: string; value: string}>): Record<any, any> {
    const dict = {};
    for (const prop of props) {
      dict[prop.key] = prop.value;
    }
    return dict;
  }

  protected initTabData() {
    if (this.objectController) {
      this.objectController.actionCallback = () => this.saveProperties();
    }
  }

  ngOnInit(): void {
    super.ngOnInit();
    if (this.object && this.object.properties) {
      const propertiesDict = JSON.parse(this.object.properties);
      this.propertiesDictToList(propertiesDict);
    }
  }

}
