import { Component } from '@angular/core';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { IBaseFleioObjectModel } from '@fleio-api/base-model/base-fleio-object.model';
import { UntypedFormBuilder } from '@angular/forms';
import {
  IOpenstackNotificationsModel,
  IOpenStackRegionNotificationsSettings
} from '@fleio-api/core/model/openstack-notifications.model';
import { SettingsOpenstackApiService } from '@fleio-api/core/settings-openstack-api.service';
import { EMPTY } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { NotificationService } from '@shared/ui-api/notification.service';
import { MatDialog } from '@angular/material/dialog';
import {
  TestNotificationsDialogComponent
} from './dialogs/test-notifications-dialog/test-notifications-dialog.component';
import { UiHelper } from '@shared/ui-api/helpers/ui-helper';
import {
  EditRegionNotificationsSettingsDialogComponent
} from './dialogs/edit-region-notifications-settings-dialog/edit-region-notifications-settings-dialog.component';
import { IYesNoDialogResult } from '@shared/ui-api/interfaces/yes-no-dialog-result';

@Component({
  selector: 'app-notifications',
  templateUrl: './notifications.component.html',
  styleUrls: ['./notifications.component.scss']
})
export class NotificationsComponent extends DetailsFormBase<IBaseFleioObjectModel> {
  notificationsForm = this.formBuilder.group({
    amqp_durable_queues: [false],
  });
  notificationsLoading = false;
  notifications: IOpenstackNotificationsModel;
  notificationSettingsChanged = false;

  regionsNotificationsSettings: IOpenStackRegionNotificationsSettings[] = [];
  protected focusFirstInput = false;
  private regions: string[];

  constructor(
    private formBuilder: UntypedFormBuilder, private settingsOpenstackApi: SettingsOpenstackApiService,
    private notificationService: NotificationService, private matDialog: MatDialog,
  ) {
    super();
  }

  deleteRegionNotificationsSettings(index: number) {
    if (index < this.regionsNotificationsSettings.length && index >= 0) {
      const regionNotificationsSettings = this.regionsNotificationsSettings[index];
      this.notificationService.confirmDialog({
        title: $localize`Delete region notification settings`,
        message: $localize`Are you sure you want to delete settings for region ${regionNotificationsSettings.region}`,
      }).subscribe((result: IYesNoDialogResult) => {
        if (result?.button === 'yes') {
          this.regionsNotificationsSettings.splice(index, 1);
        }
      });
    }
  }

  editRegionNotificationsSettings(index: number) {
    if (index < this.regionsNotificationsSettings.length && index >= 0) {
      const regionNotificationsSettings = this.regionsNotificationsSettings[index];
      this.matDialog.open(
        EditRegionNotificationsSettingsDialogComponent, {
          data: {
            regionSettings: regionNotificationsSettings,
            regions: this.regions,
            amqp_durable_queues: this.notificationsForm.controls.amqp_durable_queues.value,
          },
          autoFocus: false,
        }).afterClosed().subscribe(result => {
        if (result) {
          this.regionsNotificationsSettings[index] = result;
          this.notificationSettingsChanged = true;
        }
      });
    }
  }

  addRegionNotificationsSettings() {
    const regionNotificationsSettings: IOpenStackRegionNotificationsSettings = {
      region: '',
      urls: [{
        url: '', topic: ['notifications'],
        pool: '', exchange: [
          'cinder', 'glance', 'designate', 'keystone', 'neutron', 'nova', 'openstack', 'magnum', 'trove',
        ], amqp_durable_queues: this.notificationsForm.controls.amqp_durable_queues.value,
      }]
    }
    this.matDialog.open(
      EditRegionNotificationsSettingsDialogComponent, {
        data: {
          regionSettings: regionNotificationsSettings,
          regions: this.regions,
        },
        autoFocus: false,
      }).afterClosed().subscribe(result => {
      if (result) {
        this.regionsNotificationsSettings.push(result);
        this.notificationSettingsChanged = true;
      }
    });
  }

  getFormValue() {
    this.notifications = this.notificationsForm.value as IOpenstackNotificationsModel;
    this.notifications.regions_notifications_settings = this.regionsNotificationsSettings;
  }

  setUrlErrors(invalid_urls: string[]) {
    for (const region of this.notifications.regions_notifications_settings) {
      for (const url of region.urls) {
        if (invalid_urls.includes(url.url)) {
          url.invalid = true;
        }
      }
    }
  }

  save() {
    this.validate();
    if (this.formGroup.invalid) {
      this.displayControlErrors();
      return EMPTY;
    }

    this.getFormValue();

    this.objectController.loading = true;
    return this.settingsOpenstackApi.saveNotifications(this.notifications).pipe(catchError((error) => {
      if (error.error) {
        if (error.error['invalid_urls']) {
          this.setUrlErrors(error.error['invalid_urls']);
          this.formErrors.showError($localize`At least one URL is invalid`)
        } else {
          this.setErrors(error.error);
        }
        return EMPTY;
      } else {
        throw error;
      }
    })).subscribe((response) => {
      this.notificationService.showMessage(response.detail);
      this.notifications = response.notifications_settings;
      this.regionsNotificationsSettings = response.notifications_settings.regions_notifications_settings;
    }).add(() => {
      this.objectController.loading = false;
      this.notificationSettingsChanged = false;
    });
  }

  test() {
    this.getFormValue();

    return this.matDialog.open(
      TestNotificationsDialogComponent, {
        data: {
          notifications: this.notifications,
        },
        autoFocus: false,
      }).afterClosed().subscribe(() => {
    });
  }

  protected initTabData() {
    this.notificationsLoading = true;
    this.settingsOpenstackApi.getNotifications().subscribe(notifications => {
      this.notifications = notifications;
      this.notificationsForm.patchValue({
        amqp_durable_queues: notifications.amqp_durable_queues,
      });
      this.regionsNotificationsSettings = notifications.regions_notifications_settings;
      this.regions = notifications.regions;
    }).add(() => {
      this.notificationsLoading = false;
      UiHelper.focusAndSelectFirstInput(this.elementRef, this.changeDetector, true);
    });
  }
}
