import { Component, OnInit } from '@angular/core';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { ClusterTemplatesApiService } from '@fleio-api/openstack/cluster-template/cluster-templates-api.service';
import { NotificationService } from '@shared/ui-api/notification.service';
import { Router } from '@angular/router';
import { ConfigService } from '@shared/config/config.service';
import { Observable, of } from 'rxjs';
import { IClusterTemplateCreateOptionsModel } from '@fleio-api/openstack/model/cluster-template-create-options.model';
import { IClusterTemplateModel } from '@fleio-api/openstack/model/cluster-template.model';
import { ValidatorsHelper } from '@shared/ui-api/helpers/validators-helper';

@Component({
  selector: 'app-cluster-template-edit-form',
  templateUrl: './cluster-template-edit-form.component.html',
  styleUrls: ['./cluster-template-edit-form.component.scss']
})
export class ClusterTemplateEditFormComponent extends DetailsFormBase<IClusterTemplateModel> implements OnInit {
  createOptions: IClusterTemplateCreateOptionsModel;
  dockerVolumeSizeMin = 1;
  dockerVolumeSizeRequired = true;
  createClusterTemplateForm = this.formBuilder.group({
    name: ['', Validators.required],
    coe: ['', Validators.required],
    server_type: ['vm', Validators.required],
    registry_enabled: [false],
    tls_disabled: [false],
    hide_discovery_url: [false],
    hide_timeout_input: [false],
    make_labels_immutable: [false],
    region: ['', Validators.required],
    image_id: ['', Validators.required],
    keypair_id: ['null'],
    flavor_id: ['', Validators.required],
    master_flavor_id: ['', Validators.required],
    volume_driver: ['cinder', Validators.required],
    docker_storage_driver: ['', Validators.required],
    docker_volume_size: [null, [Validators.required, Validators.min(this.dockerVolumeSizeMin)]],
    insecure_registry: [''],
    network_driver: ['flannel', Validators.required],
    external_network_id: ['', Validators.required],
    fixed_network: [null],
    fixed_subnet: [''],
    http_proxy: [''],
    https_proxy: [''],
    no_proxy: [''],
    dns_nameserver: [null],
    master_lb_enabled: [false],
    floating_ip_enabled: [false],
    labels: [''],
  });
  hiddenCheckbox = false;
  publicCheckbox = false;
  fixed_subnet = this.createClusterTemplateForm.controls.fixed_subnet;
  clientSelection: boolean;
  createInClientProject = true;

  subnetUnselectedPlaceholder = $localize`Select subnet ...`;
  subnetSelectedPlaceholder = $localize`Subnet`;
  subnetOptionsSwitchMap: (search: string) => Observable<any>;

  constructor(
    private formBuilder: UntypedFormBuilder,
    private clusterTemplatesApiService: ClusterTemplatesApiService,
    private notificationService: NotificationService,
    private router: Router,
    private config: ConfigService,
  ) {
    super();
  }

  changeDestination(value: boolean) {
    // createInClientProject
    if (value === false) {
      this.createClusterTemplateForm.controls.client.setValue('');
      this.createClusterTemplateForm.controls.client.clearValidators();
      this.createClusterTemplateForm.controls.client.reset();
    } else {
      this.createClusterTemplateForm.controls.client.setValidators(Validators.required);
    }
  }

  changedDockerStorageDriver() {
    const dStorageDriver = this.createClusterTemplateForm.controls.docker_storage_driver.value;
    if (dStorageDriver === 'devicemapper') {
      this.dockerVolumeSizeRequired = true;
      this.dockerVolumeSizeMin = 3;
      this.createClusterTemplateForm.controls.docker_volume_size.setValidators(
        [ValidatorsHelper.requiredIntegerValidator, Validators.min(this.dockerVolumeSizeMin)]
      );
    } else {
      this.dockerVolumeSizeRequired = false;
      this.dockerVolumeSizeMin = 1;
      this.createClusterTemplateForm.controls.docker_volume_size.setValidators(
        [Validators.min(this.dockerVolumeSizeMin)]
      );
    }
    const dockerVolumeSize = this.createClusterTemplateForm.controls.docker_volume_size;
    if (dockerVolumeSize.value && dockerVolumeSize.value < this.dockerVolumeSizeMin) {
      dockerVolumeSize.setValue(null);
    }
  }

  refreshCreateOptions() {
    const region = this.createClusterTemplateForm.controls.region.value;
    this.createClusterTemplateForm.controls.external_network_id.setValue('');
    this.createClusterTemplateForm.controls.flavor_id.setValue('');
    this.createClusterTemplateForm.controls.master_flavor_id.setValue('');
    this.createClusterTemplateForm.controls.fixed_network.setValue('');
    this.createClusterTemplateForm.controls.image_id.setValue('');
    this.createClusterTemplateForm.controls.fixed_subnet.setValue('');
    if (region) {
      this.clusterTemplatesApiService.createOptions({
        region
      }).subscribe({
        next: response => {
          this.createOptions = response as any;
        }, error: () => {
          this.notificationService.showMessage($localize`Error while trying to refresh create options.`);
        }
      });
    }
  }

  changedRegion() {
    const region = this.createClusterTemplateForm.controls.region.value;
    if (region) {
      this.refreshCreateOptions();
    }
  }

  createClusterTemplate() {
    const value = this.createClusterTemplateForm.value as any;
    if (value.fixed_subnet) {
      value.fixed_subnet = value.fixed_subnet.id;
    } else {
      delete value.fixed_subnet;
    }
    const doNotSubmitIfEmpty = ['dns_nameserver', 'fixed_network', 'http_proxy', 'https_proxy', 'no_proxy',
      'insecure_registry', 'labels'];
    for (const key in value) {
      if (value.hasOwnProperty(key)) {
        if (doNotSubmitIfEmpty.indexOf(key) > -1 && !value[key]) {
          delete value[key];
        }
      }
    }
    if (value.client && value.client.id) {
      value.client = value.client.id;
    }

    if (this.object?.id) {
      // in edit mode public and hidden should be sent
      if (!this.publicCheckbox) {
        value.public = this.object.public;
      }

      if (!this.hiddenCheckbox) {
        value.hidden = this.object.hidden;
      }
    }

    if (!this.object.id && !this.createInClientProject) {
      value.create_as_admin = true;
    }

    this.createOrUpdate(this.clusterTemplatesApiService, value, true).subscribe(() => {
      this.redirectAfterCreate('openstack/cluster-templates', this.router, this.config);
    });
    return of(null);
  }

  ngOnInit(): void {
    super.ngOnInit();
    this.clientSelection = !this.object.id && this.config.authService.feature(
      'ui.openstack.cluster-templates.create-form.client-select'
    );
    if (this.objectController) {
      this.objectController.actionCallback = () => this.createClusterTemplate();
      this.createOptions = this.objectController.additionalObjects.createOptions;
    }
    if (this.clientSelection) {
      this.createClusterTemplateForm.addControl(
        'client', this.formBuilder.control('', Validators.required)
      );
    }
    if (this.createOptions) {
      if (this.createOptions.coe) {
        const coeKeys = Object.keys(this.createOptions.coe);
        this.createClusterTemplateForm.controls.coe.setValue(coeKeys[0]);
        if (this.createOptions.network_driver_defaults) {
          this.createClusterTemplateForm.controls.network_driver.setValue(
            this.createOptions.network_driver_defaults[coeKeys[0]]
          );
        }
      }
      if (this.createOptions.docker_storage_driver_default) {
        this.createClusterTemplateForm.controls.docker_storage_driver.setValue(
          this.createOptions.docker_storage_driver_default
        );
      }
      if (this.createOptions.regions && this.createOptions.regions.length) {
        const region = this.createOptions.region || this.createOptions.default_region;
        this.createClusterTemplateForm.controls.region.setValue(region);
      }
    }
    this.changedDockerStorageDriver();

    this.subnetOptionsSwitchMap = (search) => {
      const lowerCaseValue = search.toLocaleLowerCase();
      return of(this.createOptions.fixed_subnets.filter(
        subnet => subnet.name.toLocaleLowerCase().includes(lowerCaseValue)
      ));
    };

    if (this.config.authService.feature('ui.openstack.cluster-templates.create-form.hidden-checkbox')) {
      this.hiddenCheckbox = true;
      this.createClusterTemplateForm.addControl('hidden', this.formBuilder.control(false));
    }
    if (this.config.authService.feature('ui.openstack.cluster-templates.create-form.public-checkbox')) {
      this.publicCheckbox = true;
      this.createClusterTemplateForm.addControl('public', this.formBuilder.control(false));
    }

    if (this.object?.id) {
      this.createClusterTemplateForm.patchValue(this.object);
    }
  }

}
