/*
 * 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, Output, EventEmitter, ViewEncapsulation, Inject, OnInit } from '@angular/core';
import { Validators, FormBuilder, FormGroup, FormArray } from '@angular/forms';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { DICTIONARY } from '../../../../dictionary/global.dictionary';
import { CheckUtils } from '../../../core/util';

@Component({
  selector: 'dlab-manage-env-dilog',
  templateUrl: './manage-environment-dilog.component.html',
  styleUrls: ['./manage-environment-dilog.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class ManageEnvironmentComponent implements OnInit {
  readonly DICTIONARY = DICTIONARY;
  readonly CheckUtils = CheckUtils;

  public manageUsersForm: FormGroup;
  public manageTotalsForm: FormGroup;

  @Output() manageEnv: EventEmitter<{}> = new EventEmitter();

  constructor(
    @Inject(MAT_DIALOG_DATA) public data: any,
    public dialog: MatDialog,
    public dialogRef: MatDialogRef<ManageEnvironmentComponent>,
    private _fb: FormBuilder,
  ) { }

  ngOnInit() {
    !this.manageUsersForm && this.initForm();
    this.setProjectsControl();
    this.manageUsersForm.controls['total'].setValue(this.data.total.conf_max_budget || '');
    this.onFormChange();
  }

  public onFormChange() {
    this.manageUsersForm.valueChanges.subscribe(value => {
      if ((this.getCurrentTotalValue() && this.getCurrentTotalValue() >= this.getCurrentUsersTotal())) {
        this.manageUsersForm.controls['projects']['controls'].forEach(v => {
            v.controls['budget'].setErrors(null);
        }
        );
        this.manageUsersForm.controls['total'].setErrors(null);
      }
    });
  }

  get usersEnvironments(): FormArray {
    return <FormArray>this.manageUsersForm.get('projects');
  }

  public setBudgetLimits(value) {
    if (this.getCurrentTotalValue() >= this.getCurrentUsersTotal()) {
      this.dialogRef.close(value);
    } else {
      this.manageUsersForm.controls['total'].setErrors({ overrun: true });
    }
  }

  public applyAction(action, project) {
    const dialogRef: MatDialogRef<ConfirmActionDialogComponent> = this.dialog.open(
      ConfirmActionDialogComponent, { data: { action, project: project.value.project }, width: '550px', panelClass: 'error-modalbox' });

    dialogRef.afterClosed().subscribe(result => {
      if (result) this.manageEnv.emit({ action, project: { project_name: project.value.project } });
    });
  }

  public setProjectsControl() {
    this.manageUsersForm.setControl('projects',
      this._fb.array((this.data.projectsList || []).map((x: any) => this._fb.group({
        project: x.name,
        budget: [x.budget, [ this.userValidityCheck.bind(this)]],
        canBeStopped: x.canBeStopped,
        canBeTerminated: x.canBeTerminated
      }))));
  }

  private initForm(): void {
    this.manageUsersForm = this._fb.group({
      total: [null, [Validators.min(0), this.totalValidityCheck.bind(this)]],
      projects: this._fb.array([this._fb.group({ project: '', budget: null, status: '' })])
    });
  }

  private getCurrentUsersTotal(): number {
    return this.manageUsersForm.value.projects.reduce((memo, el) => memo += el.budget, 0);
  }

  private getCurrentTotalValue(): number {
    return this.manageUsersForm.value.total;
  }

  private totalValidityCheck(control) {
    return (control && control.value)
      ? (control.value >= this.getCurrentUsersTotal() ? null : { overrun: true })
      : null;
  }

  private userValidityCheck(control) {
    if (control && control.value) {
      return (this.getCurrentTotalValue() && this.getCurrentTotalValue() < this.getCurrentUsersTotal()) ? { overrun: true } : null;
    }
  }
}

@Component({
  selector: 'dialog-result-example-dialog',
  template: `
  <div class="dialog-header">
    <h4 class="modal-title"><span class="capitalize">{{ data.action }}</span> resource</h4>
    <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
  </div>
  <div mat-dialog-content class="content">
    <p>Environment of <span class="strong">{{ data.project }}</span> will be
      <span *ngIf="data.action === 'terminate'"> terminated.</span>
      <span *ngIf="data.action === 'stop'">stopped.</span>
    </p>
    <p class="m-top-20"><span class="strong">Do you want to proceed?</span></p>
  </div>
  <div class="text-center">
    <button type="button" class="butt" mat-raised-button (click)="dialogRef.close()">No</button>
    <button type="button" class="butt butt-success" mat-raised-button (click)="dialogRef.close(true)">Yes</button>
  </div>
  `,
  styles: []
})
export class ConfirmActionDialogComponent {
  constructor(
    public dialogRef: MatDialogRef<ConfirmActionDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) { }
}
