
import { Component, OnInit, HostListener, AfterViewInit, ViewChild, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { MdbTableDirective, MdbTablePaginationComponent, MDBModalService } from 'angular-bootstrap-md';
import { ProvisionsService } from '../services/provisions.service';
import { AlertService } from '../services/alert.service';
import { ModalInfoComponent } from '../modals/modalinfo.component';
import { ModalConfirmComponent } from '../modals/confirm.component';
import { Subscription } from 'rxjs';
import { ProvisionModalComponent } from '../modals/edit-provision.component';
import * as moment from 'moment-timezone';

@Component({
  selector: 'table-provisions',
  templateUrl: './table-provisions.component.html',
  styleUrls: ['./table-provisions.component.scss']
})
export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterViewInit {
  
  public nowTimeUTC : String = moment().utc().format("H:mm");

  subscription: Subscription;
  filter = {
    showDestroyed : false
  };
  filterParams : any = {
    isDestroyed: false
  };
  loading: boolean = false;

  pagingIsDisabled: Boolean = false;
  totalCount: number = 0;

  @ViewChild(MdbTablePaginationComponent, { static: true }) mdbTablePagination: MdbTablePaginationComponent;
  @ViewChild(MdbTableDirective, { static: true }) mdbTable: MdbTableDirective;

  //@ViewChild('row', { static: true }) row: ElementRef;

  elements = [];
  searchText: string = '';
  previous: string;

  @HostListener('input') oninput() {
    this.mdbTablePagination.searchText = this.searchText;
  }

  selectedprov: any = null;
  showInfo: boolean = false;
  logShow: boolean = false;
  logstype: String = 'provision';
  timeInterval;

  maxVisibleItems: number = 25;


  constructor(private modalService: MDBModalService, private _alertService: AlertService, private cdRef: ChangeDetectorRef, private _provisionsService: ProvisionsService) {

  }

  _initElements(): void {
    this.mdbTable.setDataSource(this.elements);
    this.elements = this.mdbTable.getDataSource();
    this.previous = this.mdbTable.getDataSource();
  }

  private _process(provisions) : void {
    if ( this.elements.length === 0 ) {
      this.elements = provisions;
    } else {
      this.elements.forEach( function(p, index, object) {
        let found = provisions.filter(a=>a._id.toString() === p._id.toString());
        if ( found.length ) {
          p.status = found[0].status;
          p.statusVms = found[0].statusVms;
          p.isDestroyed = found[0].isDestroyed;
          p.outputs = found[0].outputs;
          p.destroy = found[0].destroy;
          this._provisionsService.timeRunning(p);
        } else {
          object.splice(index, 1);
        }   
      }.bind(this));

      provisions.forEach(function(p) {
        let found = this.elements.filter(a=>a._id.toString() === p._id.toString());
        if (found.length === 0){
          this.elements.unshift(p);
        }
      }.bind(this));
    }

    this._initElements();

  }

  getAzureProvisionUrl(provision) : String {
    let rgName = provision.scenario.toUpperCase();
    rgName = rgName.replace(/AZQMI/g, 'QMI');
    rgName = rgName + "-" + provision._id.toString();
    let subsId = provision.deployOpts? provision.deployOpts.subsId : "62ebff8f-c40b-41be-9239-252d6c0c8ad9";
    let url = `https://portal.azure.com/#@qliktech.com/resource/subscriptions/${subsId}/resourceGroups/${rgName}/overview`;
    return url;
  }

  ngOnInit() {

    this.refreshData();

    //this._initElements();

    this.timeInterval = setInterval(() => {
      this.nowTimeUTC = moment().utc().format("H:mm");
    }, 60 * 1000);
  }


  ngOnDestroy() {
    if ( this.subscription ) {
      this.subscription.unsubscribe();
    }
    if (this.timeInterval) {
      clearInterval(this.timeInterval);
    }
  }

  ngAfterViewInit() {
    if ( this.mdbTablePagination ) {
      this.mdbTablePagination.setMaxVisibleItemsNumberTo(this.maxVisibleItems);

      this.mdbTablePagination.calculateFirstItemIndex();
      this.mdbTablePagination.calculateLastItemIndex();
      this.cdRef.detectChanges();
    }
  }

  openOwnerChange($event, provision){
    $event.preventDefault();
    var modalRef = this.modalService.show(ProvisionModalComponent, {
      class: 'modal-md modal-notify',
      containerClass: '',
      data: {
        provision: provision
      }
    } );
    
    var sub = modalRef.content.action.subscribe( (result: any) => { 
      sub.unsubscribe();
      provision.user = result.user;
      this._alertService.showAlert({
        type: 'alert-dark', 
        text: `New owner <b>${provision.user.displayName}</b> assigned to this provision`
      });
    });
  }

  searchItems() {
    const prev = this.mdbTable.getDataSource();

    if (!this.searchText) {
      this.mdbTable.setDataSource(this.previous);
      this.elements = this.mdbTable.getDataSource();
    }

    if (this.searchText) {
      this.elements = this.mdbTable.searchLocalDataBy(this.searchText);
      this.mdbTable.setDataSource(prev);
    }

    if ( this.mdbTablePagination ) {
      this.mdbTablePagination.calculateFirstItemIndex();
      this.mdbTablePagination.calculateLastItemIndex();

      this.mdbTable.searchDataObservable(this.searchText).subscribe(() => {
        this.mdbTablePagination.calculateFirstItemIndex();
        this.mdbTablePagination.calculateLastItemIndex();
      });
    }
  }

  showLogs($event, provision, type): void {
    $event.preventDefault();
    $event.stopPropagation();
    this.logstype = type;
    this.logShow = false;
    this.selectedprov = provision;
    this.logShow = true;
  }

  onLogsClose(): void {
    this.selectedprov = null;
    this.logShow = false;
  }

  openConfirmStartModal(provision) {
    var modalRef = this.modalService.show(ModalConfirmComponent, {
      class: 'modal-sm modal-notify modal-info',
      containerClass: '',
      data: {
        info: {
          title: 'Confirm Start VMs?',
          icon: 'play',
          buttonColor: 'grey'
        },
        provision: provision
      }
    } );

    var sub = modalRef.content.action.subscribe( (result: any) => { 
      sub.unsubscribe();
      this._startVms(provision);
    });
  }

  private _startVms(provision): void {
    var sub = this._provisionsService.startVms(provision._id.toString(), provision.user._id).subscribe( res => {
      provision.startVms = res.startVms;
      sub.unsubscribe();
      this._alertService.showAlert({
        type: 'alert-dark', 
        text: `Starting all VMs for scenario <b>${provision.scenario}</b>...`
      });
    })
  }

  openConfirmStopModal(provision) {
    var modalRef = this.modalService.show(ModalConfirmComponent, {
      class: 'modal-sm modal-notify modal-info',
      containerClass: '',
      data: {
        info: {
          title: 'Confirm Stop VMs?',
          icon: 'stop',
          buttonColor: 'grey'
        },
        provision: provision
      }
    } );

    var sub = modalRef.content.action.subscribe( (result: any) => { 
      sub.unsubscribe();
      this._stopVms(provision, result);
    });
  }

  openConfirmAbortModal(provision) {
    var modalRef = this.modalService.show(ModalConfirmComponent, {
      class: 'modal-sm modal-notify modal-info',
      containerClass: '',
      data: {
        info: {
          title: 'Confirm Abort Provision?',
          icon: 'close',
          buttonColor: 'grey'
        },
        provision: provision
      }
    } );

    var sub = modalRef.content.action.subscribe( (result: any) => { 
      sub.unsubscribe();
      this._abortProvision(provision);
    });
  }

  private _stopVms(provision, patch): void {
    var sub = this._provisionsService.stopVms(provision._id.toString(), provision.user._id, patch).subscribe( res => {
      provision.startVms = res.startVms;
      sub.unsubscribe();
      this._alertService.showAlert({
        type: 'alert-dark', 
        text: `Stopping all VMs for scenario <b>${provision.scenario}</b>...`
      });
    })
  }

  private _abortProvision(provision): void {
    var sub = this._provisionsService.abort(provision._id.toString(), provision.user._id).subscribe( res => {
      provision.status = res.status;
      sub.unsubscribe();
      this._alertService.showAlert({
        type: 'alert-dark', 
        text: `Aborting provision for scenario <b>${provision.scenario}</b>...`
      });
    })
  }


  openInfoModal(provisionId) {
    this._provisionsService.getProvisionById(provisionId).subscribe( res=> {
      
      this.modalService.show(ModalInfoComponent, {
        backdrop: true,
        keyboard: true,
        focus: true,
        show: false,
        ignoreBackdropClick: false,
        class: 'modal-lg',
        containerClass: '',
        animated: true,
        data: {
          info: res
        }
      } );
    })
  }

  openConfirmDestroyModal(provision) {
    var modalRef = this.modalService.show(ModalConfirmComponent, {
      class: 'modal-sm modal-notify modal-danger',
      containerClass: '',
      data: {
        info: {
          title: 'Confirm destroy this provision?',
          icon: 'times-circle'
        }
      }
    } );

    var sub = modalRef.content.action.subscribe( (result: any) => { 
      sub.unsubscribe();
      this._provisionsService.newDestroy(provision._id.toString(), provision.user._id).subscribe( provUpdated => {
        this._alertService.showAlert({
          type: 'alert-dark', 
          text: `Provision of scenario <b>${provision.scenario}</b> is going to be destroyed`
        });
        provision.destroy = provUpdated.destroy;
      })
    });
  }

  openConfirmDeleteModal(provision) {
      var modalRef = this.modalService.show(ModalConfirmComponent, {
        class: 'modal-sm modal-notify modal-danger',
        containerClass: '',
        data: {
          info: {
            title: 'Confirm delete?',
            icon: 'trash-alt'
          }
        }
    } );

    var sub = modalRef.content.action.subscribe( (result: any) => { 
      sub.unsubscribe();
      this._provisionsService.delProvision(provision._id, provision.user._id).subscribe( res => {
        this.elements = this.elements.filter(e=>{
          return e._id.toString() !== provision._id.toString();
        });
        this._initElements();
        this._alertService.showAlert({
          type: 'alert-dark', 
          text: `Provision entry <b>${provision.scenario}</b> was deleted from History.`
        });
      });
    });
  }

  refreshData() { 
    this.elements = [];
    this.loading = true;
    this.searchText = "";
    var instantSubs = this._provisionsService.getProvisionsAdmin(this.filterParams).subscribe( provisions=>{
      instantSubs.unsubscribe();
      this.totalCount = provisions.total;
      this.loading = false;  
      this._process(provisions.results);    
    });
  }

  onCheckValue() : void {
    this.filterParams = {};
    if ( !this.filter.showDestroyed ) {
      this.filterParams.isDestroyed = false;
    }
    this.refreshData();
  }

  openConfirmExtendModal(provision) {
    var modalRef = this.modalService.show(ModalConfirmComponent, {
      class: 'modal-sm modal-notify modal-info',
      containerClass: '',
      data: {
        info: {
          title: `Renew 24x7 period?`,
          icon: 'redo-alt',
          buttonColor: 'grey'
        }
      }
    } );

    var sub = modalRef.content.action.subscribe( (result: any) => { 
      sub.unsubscribe();

      this._provisionsService.extend(provision._id.toString(), provision.user._id).subscribe( res => {
        provision.countExtend = res.countExtend;
        provision.timeRunning = res.timeRunning;
        provision.runningFrom = res.runningFrom;
        this._alertService.showAlert({
          type: 'alert-dark', 
          text: `Running period extended another ${provision._scenarioDoc.allowed24x7RunningDays} days (from now) for provision <b>${provision.scenario}</b>`
        });
      })
    });
  }

}