import { Component, OnInit } from '@angular/core';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfigService } from '@shared/config/config.service';
import { Observable, of } from 'rxjs';
import { IActionResult } from '@objects-view/interfaces/actions/action-result';
import { VolumesApiService } from '@fleio-api/openstack/volume/volumes-api.service';
import { IClientModel } from '@fleio-api/client-user/model/client.model';
import { debounceTime } from 'rxjs/operators';
import { ClientsApiService } from '@fleio-api/client-user/client/clients-api.service';
import { IVolumeCreateOptionsModel } from '@fleio-api/openstack/model/volume-create-options.model';
import { IVolumeModel } from '@fleio-api/openstack/model/volume.model';
import { IVolumeType } from '@fleio-api/openstack/model/volume-type.model';
import { ValidatorsHelper } from '@shared/ui-api/helpers/validators-helper';

@Component({
  selector: 'app-volume-edit-form',
  templateUrl: './volume-edit-form.component.html',
  styleUrls: ['./volume-edit-form.component.scss']
})
export class VolumeEditFormComponent extends DetailsFormBase<IVolumeModel> implements OnInit {
  volumeForm = this.formBuilder.group({
    region: ['', Validators.required],
    name: ['', Validators.required],
    description: [''],
    source: this.formBuilder.group({
      source: ['', Validators.required],
      source_type: ['new', Validators.required],
    }),
    size: ['', [ValidatorsHelper.requiredIntegerValidator, Validators.required]],
    type: ['', Validators.required],
    availability_zone: [''],
  });

  client;
  region = this.volumeForm.controls.region;
  source = (this.volumeForm.controls.source as UntypedFormGroup).controls.source;
  source_type = (this.volumeForm.controls.source as UntypedFormGroup).controls.source_type;
  createOptions: IVolumeCreateOptionsModel;
  sourceTypes: object[];
  selectedVolumeType: IVolumeType;
  selectClient = false;
  createInClientProject = true;
  showAvailabilityZonesSelect = false;
  estimatedCost: string;
  estimatedCostLoading = false;

  constructor(
    private formBuilder: UntypedFormBuilder,
    private volumesApi: VolumesApiService,
    private clientsApi: ClientsApiService,
    private router: Router,
    public config: ConfigService,
    private activatedRoute: ActivatedRoute,
  ) {
    super();
  }

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

  ngOnInit() {
    super.ngOnInit();
    this.createOptions = this.activatedRoute.snapshot.data.createOptions;
    if (this.config.authService.feature('ui.openstack.volumes.client')) {
      this.selectClient = true;
      this.volumeForm.addControl('client', this.formBuilder.control('', Validators.required));
      this.client = this.volumeForm.controls.client;
    }
    if (this.objectController) {
      this.objectController.actionCallback = () => this.saveVolume();
      this.volumeForm.controls.region.setValue(this.createOptions.selected_region);
      if (this.createOptions?.availability_zones?.length && this.authSvc.feature('openstack.volumes.availability_zones')) {
        this.showAvailabilityZonesSelect = true;
        if (this.createOptions.availability_zones.length === 1) {
          this.volumeForm.controls.availability_zone.setValue(this.createOptions.availability_zones[0]);
        }
      }
    }

    this.source.disable();

    this.region.valueChanges.subscribe(region => {
      this.volumesApi.createOptions({region}).subscribe(createOptions => {
        this.createOptions = createOptions as IVolumeCreateOptionsModel;
        this.refreshSourceTypes();
      });
    });

    this.source_type.valueChanges.subscribe(sourceType => {
      if (sourceType !== 'new') {
        this.source.enable();
      } else {
        this.source.disable();
      }
    });

    this.refreshSourceTypes();

    this.volumeForm.valueChanges.pipe(debounceTime(300)).subscribe(() => {
      this.getSimulatedPrice();
    });
  }

  volumeTypeChanged(newVolumeType: IVolumeType) {
    this.selectedVolumeType = newVolumeType;
    if (newVolumeType) {
      this.volumeForm.controls.type.setValidators([
        Validators.required, Validators.min(newVolumeType.minimumSize)
      ]);
    } else {
      this.volumeForm.controls.type.setValidators(Validators.required);
    }
  }

  refreshSourceTypes() {
    this.sourceTypes = [{name: 'new', description: $localize`Create a new empty volume`}];
    if (this.createOptions && this.createOptions.sources) {
      if (this.createOptions.sources.image && this.createOptions.sources.image.length) {
        this.sourceTypes.push({name: 'image', description: $localize`Use image as a source`});
      }
      if (this.createOptions.sources.volume && this.createOptions.sources.volume.length) {
        this.sourceTypes.push({name: 'volume', description: $localize`Use an existing volume`});
      }
    }
  }

  saveVolume(): Observable<IActionResult> {
    const value = this.volumeForm.value;
    if (this.selectClient && value.client && value.client.id) {
      value.client = (value.client as IClientModel).id;
    }

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

    this.createOrUpdate(
      this.volumesApi,
      value,
    ).subscribe(() => {
      this.redirectAfterCreate('openstack/volumes', this.router, this.config);
    });

    return of(null);
  }

  getSimulatedPrice() {
    if (this.authSvc.feature('openstack.volumes.show-price-on-create')) {
      const region = this.volumeForm.controls.region.value;
      const volumeSize = this.volumeForm.controls.size.value;
      const volumeType = this.volumeForm.controls.type.value;
      let clientId = null;
      if (this.selectClient) {
        clientId = this.volumeForm.controls.client.value?.id;
      }
      if (region && volumeSize && volumeType && ((this.selectClient && clientId) || !this.selectClient)) {
        const params = {
          volume_size: volumeSize,
          volume_type: volumeType,
          region,
        } as any;
        if (clientId) {
          params.client_id = clientId;
        }
        if (this.volumeForm.contains('availability_zone') && this.volumeForm.controls.availability_zone.value) {
          params.availability_zone = this.volumeForm.controls.availability_zone.value;
        }
        this.estimatedCostLoading = true;
        this.volumesApi.getPrice(params).subscribe({
          next: response => {
            this.estimatedCost = response.estimated_cost_display;
          },
          error: error => {
            if (error?.error?.detail) {
              if (this.config.authService.feature('ui.staff')) {
                this.estimatedCost = error.error.detail;
              } else {
                this.estimatedCost = null;
              }
            }
          }
        }).add(() => {
          this.estimatedCostLoading = false;
        });
      }
    }
  }
}
