import {Injectable} from '@angular/core';
import {ServiceInfoModel, ServiceInfoUiModel} from '../shared/server/serviceInfo/serviceInfo.model';
import * as _ from 'lodash';
import {Observable} from 'rxjs/Observable';
import {NgRedux} from "@angular-redux/store";
import {AppState} from "../shared/store/reducers";
import {AaiService} from "../shared/services/aaiService/aai.service";
import {ServiceModel} from "../shared/models/serviceModel";
import {FeatureFlagsService, Features} from "../shared/services/featureFlag/feature-flags.service";
import {DrawingBoardModes} from "../drawingBoard/service-planning/drawing-board.modes";
import {updateDrawingBoardStatus} from "../shared/storeUtil/utils/global/global.actions";
import {Router, UrlTree} from "@angular/router";
import {of} from "rxjs";
import {MsoService} from "../shared/services/msoService/mso.service";
export let PENDING : string = "pending";
export let INPROGRESS : string = "in_progress";
export let PAUSE : string = "pause";
export let X_O : string = "x-circle-o";
export let SUCCESS_CIRCLE : string = "success-circle-o";
export let STOPED : string = "stop";
export let COMPLETED_WITH_ERRORS : string = "success_with_warning";


@Injectable()
export class InstantiationStatusComponentService {
  constructor( private _aaiService: AaiService,
               private _msoService: MsoService,
               private _router : Router,
               private _store: NgRedux<AppState>) {
  }

  generateServiceInfoDataMapping(arr: ServiceInfoModel[]) : { [serviceInstanceId: string]: ServiceInfoModel[]}{
    let serviceInfoData: { [serviceInstanceId: string]: ServiceInfoModel[]; } = {};
    for(let item of arr){
      if(_.isNil(serviceInfoData[item.templateId])){
        serviceInfoData[item.templateId] = [item];
      }else {
        serviceInfoData[item.templateId].push(item);
      }
    }
    return serviceInfoData;
  }

  convertObjectToArray(arr: ServiceInfoModel[]) : Observable<ServiceInfoUiModel[]>{
    const obj = this.generateServiceInfoDataMapping(arr);
    let index:number = 0;
    let result = [];
    for(let item in obj) {
      obj[item].map(item => {
        item['serviceStatus'] = this.getStatus(item.jobStatus);
        item['serviceIndex'] = index;
      });
      index++;
      result = result.concat(obj[item]);
    }

    console.log(result);
    return of(result);
  }

  isDrawingBoardViewEdit(serviceModel: ServiceModel): boolean {
    if (!_.isNil(serviceModel.vidNotions) && !_.isNil(serviceModel.vidNotions.viewEditUI)
      && serviceModel.vidNotions.viewEditUI !== 'legacy'){
      return true;
    }
    return false;
  }

  open(item: ServiceInfoModel): void {
    if (FeatureFlagsService.getFlagState(Features.FLAG_1902_VNF_GROUPING, this._store)) {
      this._aaiService.getServiceModelById(item['serviceModelId']).subscribe((result)=>{
        const serviceModel =  new ServiceModel(result);

        if (this.isDrawingBoardViewEdit(serviceModel)) {
          this.navigateToNewViewEdit(item, DrawingBoardModes.EDIT);
          return;
        }

        this.navigateToNewViewOnlyOrOldEditView(item);

      });
    }

    /*this else is here only to save time in case we don't need to retrieve service model
    it can be removed once it service model is always needed, and it doesn't save time*/
    else {
      this.navigateToNewViewOnlyOrOldEditView(item);
    }
  }

  navigateToNewViewOnlyOrOldEditView(item: ServiceInfoModel) {
    if (FeatureFlagsService.getFlagState(Features.FLAG_1902_NEW_VIEW_EDIT, this._store)) {
      this.navigateToNewViewEdit(item, DrawingBoardModes.VIEW);
    }
    else {
      this.navigateToOldViewEdit(item);
    }
  }

  navigateToOldViewEdit(item: ServiceInfoModel) {
    let query =
      `subscriberId=${item.subscriberId}&` +
      `subscriberName=${item.subscriberName}&` +
      `serviceType=${item.serviceType}&` +
      `serviceInstanceId=${item.serviceInstanceId}`;

    this._store.dispatch(updateDrawingBoardStatus(DrawingBoardModes.OLD_VIEW_EDIT));
    window.parent.location.assign('../../serviceModels.htm#/instantiate?' + query);
  }

  navigateToNewViewEdit(item: ServiceInfoModel, mode: DrawingBoardModes): void{
    this._store.dispatch(updateDrawingBoardStatus(mode));
    const viewEditUrlTree:UrlTree = this.getNewViewEditUrlTree(item, mode);
    this._router.navigateByUrl(viewEditUrlTree);
    window.parent.location.assign(this.getViewEditUrl(viewEditUrlTree));
  }

  getNewViewEditUrlTree(item: ServiceInfoModel, mode: DrawingBoardModes): UrlTree {
    return this._router.createUrlTree(
      ['/servicePlanning/' + mode],
      {
        queryParams:
          {
            serviceModelId: item.serviceModelId,
            serviceInstanceId: item.serviceInstanceId,
            serviceType : item.serviceType,
            subscriberId : item.subscriberId,
            jobId: item.jobId
          }
      });
  }

  getViewEditUrl(viewEditUrlTree:UrlTree): string {
    return '../../serviceModels.htm#' + viewEditUrlTree.toString();

  }

  getStatus(status : string) : ServiceStatus {
    switch(status.toUpperCase()) {
      case  'PENDING' :
        return new ServiceStatus(PENDING, 'primary', 'Pending: The action required will be sent as soon as possible.');
      case  'IN_PROGRESS' :
        return new ServiceStatus(INPROGRESS, 'primary', 'In-progress: the service is in process of the action required.');
      case  'PAUSED' :
        return new ServiceStatus(PAUSE, 'primary', 'Paused: Service has paused and waiting for your action.\n Select actions from the menu to the right.');
      case  'FAILED' :
        return new ServiceStatus(X_O, 'error', 'Failed: All planned actions have failed.');
      case  'COMPLETED' :
        return new ServiceStatus(SUCCESS_CIRCLE, 'success', 'Completed successfully: Service is successfully instantiated, updated or deleted.');
      case  'STOPPED' :
        return new ServiceStatus(STOPED, 'error', 'Stopped: Due to previous failure, will not be instantiated.');
      case  'COMPLETED_WITH_ERRORS' :
        return new ServiceStatus(COMPLETED_WITH_ERRORS, 'success', 'Completed with errors: some of the planned actions where successfully committed while other have not.\n Open the service to check it out.');
    }
  }

  retry(item: ServiceInfoModel): void {
      this.navigateToNewViewEdit(item, DrawingBoardModes.RETRY_EDIT);
  }
}


export class ServiceStatus {
  iconClassName : string;
  color : string;
  tooltip : string;

  constructor(_iconClassName : string, _color : string, _tooltip : string){
    this.iconClassName = _iconClassName;
    this.color = _color;
    this.tooltip = _tooltip;
  }
}
