/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import { Component, OnInit, OnDestroy, Inject, ViewChild } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Subscription } from 'rxjs';
import { ToastrService } from 'ngx-toastr';

import { ProjectDataService } from './project-data.service';
import {HealthStatusService, ProjectService } from '../../core/services';
import { NotificationDialogComponent } from '../../shared/modal-dialog/notification-dialog';
import { ProjectListComponent } from './project-list/project-list.component';
import { EnvironmentsDataService } from '../management/management-data.service';

export interface Endpoint {
  name: string;
  status: string;
  edgeInfo: any;
}

export interface Project {
  name: string;
  endpoints: any;
  tag: string;
  groups: string[];
  shared_image_enabled?: boolean;
  areStoppedNode?: boolean;
  areTerminatedNode?: boolean;
  areRunningNode?: boolean;
}

@Component({
  selector: 'datalab-project',
  templateUrl: './project.component.html'
})

export class ProjectComponent implements OnInit, OnDestroy {
  projectList: Project[] = [];
  healthStatus: any;
  activeFiltering: boolean = false;
  resources: any = [];
  noPermissionMessage: string = 'You are not assigned to any project.';

  private subscriptions: Subscription = new Subscription();

  @ViewChild(ProjectListComponent) list: ProjectListComponent;

  constructor(
    public dialog: MatDialog,
    public toastr: ToastrService,
    private projectService: ProjectService,
    private projectDataService: ProjectDataService,
    private healthStatusService: HealthStatusService,
    private environmentsDataService: EnvironmentsDataService
  ) { }

  ngOnInit() {
    this.getEnvironmentHealthStatus();
    this.subscriptions.add(this.projectDataService._projects
      .subscribe((value: Project[]) => {
        if (value) this.projectList = value;
      })
    );
    this.refreshGrid();
    this.getResources();
  }

  ngOnDestroy() {
    this.subscriptions.unsubscribe();
  }

  private getResources() {
    this.environmentsDataService.getEnvironmentDataDirect()
      .subscribe((data: any) => {
        this.resources = data;
      });
  }

  refreshGrid() {
    this.projectDataService.updateProjects();
    this.activeFiltering = false;
  }

  createProject() {
    if (this.projectList.length)
      this.dialog.open(EditProjectComponent, { data: { action: 'create', item: null }, panelClass: 'modal-xl-s' })
        .afterClosed().subscribe(() => {
          this.getEnvironmentHealthStatus();
        });
  }

  public toggleFiltering(): void {
    this.activeFiltering = !this.activeFiltering;
    this.activeFiltering ? this.list.showActiveInstances() : this.projectDataService.updateProjects();
  }

  public editProject($event) {
    this.dialog.open(EditProjectComponent, { data: { action: 'edit', item: $event }, panelClass: 'modal-xl-s' })
      .afterClosed().subscribe(() => {
        this.refreshGrid();
      });
  }

  public toggleStatus($event) {
    const data = { 
      'project_name': $event.project.name, 
      endpoint: $event.endpoint.map(endpoint => endpoint.name),
      'edge_status': $event.endpoint.map(endpoint => endpoint.status)[0]
    };
    this.toggleStatusRequest(data, $event.action, $event.oneEdge);
  }

  private toggleStatusRequest(data, action, isOnlyOneEdge?) {
    if ( action === 'terminate') {
      const projectsResources = this.resources
        .filter(resource => resource.project === data.project_name && resource.resource_type !== "edge node");

      const activeProjectsResources = projectsResources?.length ? projectsResources
        .filter(expl => expl.status !== 'terminated' && expl.status !== 'terminating' && expl.status !== 'failed') : [];
        
      const termResources = data.endpoint.reduce((res, endp) => {
        res.push(...activeProjectsResources.filter(resource => resource.endpoint === endp));
        return res;
      }, []).map(resource => resource.resource_name);

      if (termResources.length === 0 && !isOnlyOneEdge) {
        this.edgeNodeAction(data, action);
      } else {
        this.dialog.open(NotificationDialogComponent, { data: {
            type: 'terminateNode', 
            item: {action: data, resources: termResources}
          }, panelClass: 'modal-sm' })
          .afterClosed().subscribe(result => {
          result && this.edgeNodeAction(data, action);
        });
      }
    } else {
      this.edgeNodeAction(data, action);
    }
  }

  private edgeNodeAction(data, action) {
    this.projectService.toggleProjectStatus(data, action)
      .subscribe(
        () => {
          this.refreshGrid();
          this.toastr.success(`Edge node ${this.toEndpointAction(action)} is in progress!`, 'Processing!');
        }, 
        error => {
          this.toastr.error(error.message, 'Oops!');
        }
      );
  }

  private getEnvironmentHealthStatus() {
    this.healthStatusService.getEnvironmentHealthStatus()
      .subscribe((result: any) => this.healthStatus = result);
  }

  private toEndpointAction(action) {
    if (action === 'start') return 'starting';
    else if (action === 'stop') return 'stopping';
    else if (action === 'terminate') return 'terminating';
    else return action;
  }
}

@Component({
  selector: 'edit-project',
  template: `
    <div id="dialog-box" class="edit-form">
      <div class="dialog-header">
        <h4 class="modal-title">
          <span *ngIf="data?.action === 'create'">Create new project</span>
          <span *ngIf="data?.action === 'edit'">Edit {{ data.item.name }}</span>
        </h4>
        <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
      </div>
      <div mat-dialog-content class="content project-form">
        <project-form [item]="data.item" (update)="dialogRef.close(true)"></project-form>
      </div>
    </div>
  `,
  styles: [`
    .content { color: #718ba6; padding: 0; font-size: 14px; font-weight: 400; margin: 0; overflow: hidden; }
    .edit-form { height: 410px; overflow: hidden; }
  `]
})
export class EditProjectComponent {
  constructor(
    public dialogRef: MatDialogRef<EditProjectComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) { }
}
