import { ObjectUIServiceBase } from '@objects-view/object-ui-service-base';
import { IVolumeBackupModel } from '@fleio-api/openstack/model/volume-backup.model';
import { ConfigService } from '@shared/config/config.service';
import { VolumeBackupsApiService } from '@fleio-api/openstack/volume/volume-backups-api.service';
import { MatDialog } from '@angular/material/dialog';
import { IPermissionsModel } from '@fleio-api/base-model/IPermissionsModel';
import { ITitle } from '@objects-view/interfaces/card-data/card-title';
import { IAction } from '@objects-view/interfaces/actions/action';
import { CallbackAction } from '@objects-view/actions/callback-action';
import {
  RestoreVolumeBackupDialogComponent
} from '@shared/common-dialogs/openstack/volme-backups/restore-volume-backup-dialog/restore-volume-backup-dialog.component';
import { map } from 'rxjs/operators';
import { IActionResult } from '@objects-view/interfaces/actions/action-result';
import { ApiCallAction, CallType } from '@objects-view/actions/api-call-action';
import { IIcon } from '@shared/ui/common/interfaces/icon';
import { IObjectStatus, StatusType, StatusValue } from '@objects-view/interfaces/object-status';
import { IDataField } from '@objects-view/interfaces/card-data/data-field';
import { FleioObjectsList } from '@fleio-api/fleio-objects-list';
import { IDetailsTab } from '@objects-view/interfaces/details/details-tab';
import {
  VolumeBackupDetailsOverviewComponent
} from '@shared/common-tabs/openstack/volume-backups/volume-backup-details-overview/volume-backup-details-overview.component';
import {
  EditVolumeBackupDialogComponent
} from '@shared/common-dialogs/openstack/volme-backups/edit-volume-backup-dialog/edit-volume-backup-dialog.component';
import { EntityAuditLogComponent } from '../../common-components/entity-audit-log/entity-audit-log.component';

export class VolumeBackupUiService extends ObjectUIServiceBase<IVolumeBackupModel> {
  private readonly config: ConfigService;
  private readonly volumeBackupsApiService: VolumeBackupsApiService;
  private readonly matDialog: MatDialog;


  constructor(
    volumeBackupModel: IVolumeBackupModel, permissions: IPermissionsModel, state: string,
    config: ConfigService, volumeBackupsApiService: VolumeBackupsApiService, matDialog: MatDialog,
  ) {
    super(volumeBackupModel, permissions, state);
    this.matDialog = matDialog;
    this.config = config;
    this.volumeBackupsApiService = volumeBackupsApiService;
  }

  getIcon(): IIcon {
    return null;
  }

  getStatus(): IObjectStatus {
    switch (this.object.status) {
      case 'error':
      case 'error_deleting':
        return {
          value: StatusValue.Error,
          type: StatusType.Defined,
        };
      case 'deleting':
        return {
          value: StatusValue.Deleted,
          type: StatusType.Changing,
        };
      case 'attaching':
      case 'creating':
      case 'restoring':
        return {
          value: StatusValue.Pending,
          type: StatusType.Changing,
        };
      case 'available':
      default:
        return {
          value: StatusValue.Enabled,
          type: StatusType.Defined,
        };
    }
  }

  getTitle(): ITitle {
    switch (this.state) {
      case 'edit':
        return {
          text: $localize`Edit volume backup ${this.object.name || this.object.id}`,
        };

      case 'create':
        return {
          text: $localize`Create new volume backup`,
        };

      default:
        let subText = this.object.status.toLocaleUpperCase();
        if (this.object.is_incremental) {
          subText += $localize` (incremental)`;
        }
        return {
          text: `${this.object.name || this.object.id}`,
          subText,
        };
    }
  }

  getActions(): IAction[] {
    const actions: IAction[] = [];

    actions.push(new CallbackAction(
      {
        object: this.object,
        icon: {name: 'edit'},
        tooltip: $localize`Edit backup`,
        name: $localize`Edit`,
        noPermissions: !this.permissions['volumebackups.update'],
        callback: () => this.matDialog.open(
          EditVolumeBackupDialogComponent, {
            data: {
              backup: this.object,
            },
            autoFocus: false,
          }).afterClosed().pipe(map(result => {
          if (!result) {
            return;
          }
          return {message: $localize`Backup update scheduled`} as IActionResult;
        })),
        refreshAfterExecute: true,
      }
    ));

    actions.push(new CallbackAction(
      {
        object: this.object,
        icon: {name: 'redo'},
        tooltip: $localize`Restore volume backup`,
        name: $localize`Restore`,
        noPermissions: !this.permissions['volumebackups.restore'],
        callback: () => this.matDialog.open(
          RestoreVolumeBackupDialogComponent, {
            data: {backup: this.object},
            autoFocus: false,
          }).afterClosed().pipe(map(result => {
          if (!result) {
            return;
          }
          return {message: result} as IActionResult;
        }))
      }
    ));

    actions.push(new ApiCallAction(
      {
        object: this.object,
        icon: {name: 'delete'},
        name: $localize`Delete`,
        tooltip: $localize`Delete volume backup`,
        confirmOptions: {
          confirm: true,
          title: $localize`Delete volume backup`,
          message: $localize`Are you sure you want to delete volume backup ${this.object.name}?`,
        },
        successMessage: $localize`Volume backup delete queued`,
        errorMessage: $localize`Failed to delete volume backup, check logs for details`,
        noPermissions: !this.permissions['volumebackups.destroy'],
        apiService: this.volumeBackupsApiService,
        callType: CallType.Delete,
        refreshAfterExecute: false,
        redirectAfterExecute: true,
        redirectUrl: this.config.getPanelUrl('openstack/volume-backups'),
      }
    ));

    return actions;
  }

  getDetailsActions(): IAction[] {
    const actions = [];
    return actions;
  }

  getDetailsLink(): string {
    return this.config.getPanelUrl(`openstack/volume-backups/${this.object.id}`);
  }

  getCardFields(): IDataField[] {
    const fields = [
      {
        value: $localize`${this.object.size} GB, ${this.object.region}`
      },
      {
        name: $localize`Volume`,
        value: this.object.volume ? this.object.volume.toString() : $localize`n/a`,
      },
      {
        name: $localize`Client`,
        value: this.object.client ? this.object.client.display : $localize`n/a`,
      },
    ];

    return fields;
  }

  getTabs(additionalObjects?: {
    backups: FleioObjectsList<IVolumeBackupModel>;
    snapshots: FleioObjectsList<IVolumeBackupModel>;
  }): IDetailsTab[] {
    switch (this.state) {
      case 'details':
        return [
          {
            tabName: $localize`Overview`,
            tabIdentifier: 'overview',
            component: VolumeBackupDetailsOverviewComponent,
          },
          {
            tabName: $localize`Audit log`,
            tabIdentifier: 'audit-log',
            component: EntityAuditLogComponent,
            featureName: 'utils.activitylog',
            data: {
              entity_type: 'volume_backup'
            }
          }
        ];
    }
  }

  getCardTags(): string[] {
    const tags: string[] = [];
    return tags;
  }

  getObjectDetailsRefreshInterval(): number {
    switch (this.state) {
      case 'details':
        if (['restoring', 'attaching'].indexOf(this.object.status) < 0) {
          return this.config.getDefaultRefreshInterval();
        } else {
          return this.config.getDefaultRefreshInterval(true);
        }
      default:
        return null;
    }
  }
}
