import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { IVolumeModel } from '@fleio-api/openstack/model/volume.model';
import { IVolumeSnapshotModel } from '@fleio-api/openstack/model/volume-snapshot.model';
import { VolumeSnapshotsApiService } from '@fleio-api/openstack/volume/volume-snapshots-api.service';
import { VolumesApiService } from '@fleio-api/openstack/volume/volumes-api.service';
import { debounceTime } from 'rxjs/operators';
import { AuthService } from '@shared/auth/auth.service';
import { ConfigService } from '@shared/config/config.service';
import { IBaseDialog } from '@shared/common-dialogs/base-dialog';
import { IAction } from '@objects-view/interfaces/actions/action';
import { DialogCallbackAction } from '@objects-view/actions/dialog-callback-action';

@Component({
  selector: 'app-edit-volume-snapshot-dialog',
  templateUrl: './edit-volume-snapshot-dialog.component.html',
  styleUrls: ['./edit-volume-snapshot-dialog.component.scss']
})
export class EditVolumeSnapshotDialogComponent implements IBaseDialog, OnInit {
  @ViewChild('formErrors') protected formErrors;
  backendErrors = {};
  snapshotForm = this.formBuilder.group({
    for_client: [false],
    name: ['', Validators.required],
    force: [false],
    description: [''],
    volume: ['', Validators.required],
  });
  dialogTitle = null;
  dialogActions: Array<IAction> = [];
  dialogForm = this.snapshotForm;
  showVolumeSelect: boolean;
  loading: boolean;
  fieldRequiredTxt = $localize`This field is required!`;
  volumeSelectedPlaceholder = $localize`Volume`;
  volumeUnselectedPlaceholder = $localize`Select volume ...`;
  estimatedCost: string;
  estimatedCostLoading = false;

  constructor(
    public dialogRef: MatDialogRef<EditVolumeSnapshotDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: {
      volume: IVolumeModel;
      snapshot: IVolumeSnapshotModel;
    },
    private volumeSnapshotsApiService: VolumeSnapshotsApiService,
    private formBuilder: UntypedFormBuilder,
    public auth: AuthService,
    public config: ConfigService,
    public volumesApiService: VolumesApiService,
  ) {
  }

  volumeDisplay(volume?: IVolumeModel): string | undefined {
    if (volume) {
      return volume.name ? `${volume.name} - ${volume.id}` : volume.id.toString();
    } else {
      return undefined;
    }
  }

  ngOnInit() {
    if (this.data.snapshot) {
      this.dialogTitle = $localize`Edit volume snapshot ${this.data.snapshot.name}`;
      this.dialogActions.push(
        new DialogCallbackAction({
          name: $localize`Update snapshot`,
          primary: true,
          callback: () => this.createOrUpdate(),
        }),
      );
      this.snapshotForm.patchValue(this.data.snapshot);
      this.snapshotForm.controls.for_client.disable();
      this.snapshotForm.controls.force.disable();
      this.snapshotForm.controls.description.disable();
    } else {
      if (this.data.volume) {
        this.dialogTitle = $localize`Create snapshot for volume ${this.data.volume.name || this.data.volume.id}`;
      } else {
        this.dialogTitle = $localize`Create snapshot`;
      }
      this.dialogActions.push(
        new DialogCallbackAction({
          name: $localize`Create snapshot`,
          primary: true,
          callback: () => this.createOrUpdate(),
        }),
      );
    }

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

    this.showVolumeSelect = !this.data.snapshot && !this.data.volume;

    if (!this.showVolumeSelect) {
      this.snapshotForm.controls.volume.disable();
    }
  }

  createOrUpdate() {
    if (this.snapshotForm.invalid) {
      return;
    }
    const value = this.snapshotForm.value;
    let volume = this.data.volume;

    if (this.showVolumeSelect) {
      volume = value.volume;
    }

    if (volume) {
      value.volume_id = volume.id ? volume.id : volume;
    }

    let request;

    if (this.data.snapshot) {
      value.id = this.data.snapshot.id;
      request = this.volumeSnapshotsApiService.update(value.id, value);
    } else {
      request = this.volumeSnapshotsApiService.create(value);
    }

    this.loading = true;
    request.subscribe(result => {
      if (result) {
        this.dialogRef.close('Ok');
      } else {
        this.dialogRef.close('');
      }
    }, error => {
      this.backendErrors = error.error;
      this.formErrors.setBackendErrors(error.error);
    }).add(() => {
      this.loading = false;
    });
  }

  getSimulatedPrice() {
    if (this.auth.feature('openstack.volumes.snapshots.show-price-on-create')) {
      const volume = this.snapshotForm.controls.volume.value || this.data.volume;
      if (volume && typeof volume.size === 'number' && volume.region &&
        ((this.snapshotForm.controls.for_client.value && volume.client) ||
          !this.auth.feature('ui.openstack.volumes.snapshots.show-project-checkbox'))) {
        const params = {
          volume_size: volume.size,
          region: volume.region,
        } as any;
        if (volume.client?.id) {
          params.client_id = volume.client?.id;
        }
        this.estimatedCostLoading = true;
        this.volumeSnapshotsApiService.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;
        });
      } else {
        this.estimatedCost = null;
      }
    }
  }
}
