import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { IServiceModel } from '@fleio-api/billing/model/service.model';
import { ServicesApiService } from '@fleio-api/billing/services/service-api.service';
import { NotificationService } from '@shared/ui-api/notification.service';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { ProjectsApiService } from '@fleio-api/openstack/project/projects-api.service';
import { IAction } from '@objects-view/interfaces/actions/action';
import { DialogCallbackAction } from '@objects-view/actions/dialog-callback-action';
import { IBaseDialog } from '@shared/common-dialogs/base-dialog';

@Component({
  selector: 'app-service-change-project',
  templateUrl: './service-change-project.component.html',
  styleUrls: ['./service-change-project.component.scss']
})
export class ServiceChangeProjectComponent implements IBaseDialog, OnInit {
  changeProjectForm: UntypedFormGroup = this.formBuilder.group({
    project: ['']
  });
  dialogTitle = $localize`Change associated project for service ${this.data?.service?.id}`;
  dialogActions: Array<IAction> = [
    new DialogCallbackAction({
      name: $localize`Submit`,
      primary: true,
      callback: () => this.submit(),
    }),
  ];
  dialogForm = this.changeProjectForm;
  associatedProjectId: string;
  loading = false;
  projectSelectedPlaceholder = $localize`Project`;
  projectUnselectedPlaceholder = $localize`Select project ...`;
  projectOptionsQueryParams: Record<string, string> = {};

  constructor(
    public dialogRef: MatDialogRef<ServiceChangeProjectComponent>,
    @Inject(MAT_DIALOG_DATA) public data: { service: IServiceModel },
    private servicesApi: ServicesApiService,
    private notificationService: NotificationService,
    private formBuilder: UntypedFormBuilder,
    public projectsApiService: ProjectsApiService,
    ) {
  }

  changedAction() {
    if (this.changeProjectForm.controls.action.value === 'deleteAssociation') {
      this.changeProjectForm.controls.project.clearValidators();
      this.changeProjectForm.controls.project.updateValueAndValidity();
    } else {
      this.changeProjectForm.controls.project.setValidators(Validators.required);
      this.changeProjectForm.controls.project.updateValueAndValidity();
    }
  }

  ngOnInit(): void {
    this.loading = true;
    this.servicesApi.hasAssociatedResource(this.data.service.id).subscribe(response => {
      if (response.has_associated_resource) {
        this.associatedProjectId = response.resource_details.project_id;
        if (this.associatedProjectId) {
          this.projectOptionsQueryParams.filtering = `project_id__ne:${this.associatedProjectId}`;
        }
        this.changeProjectForm.addControl('action', this.formBuilder.control(''));
      }
      this.loading = false;
    });
  }

  submit() {
    if (this.changeProjectForm.invalid) {
      return;
    }
    if (this.changeProjectForm.contains('action') &&
      this.changeProjectForm.controls.action.value === 'deleteAssociation') {
      this.loading = true;
      this.servicesApi.removeResourceAssociation(this.data.service.id).subscribe(response => {
        this.notificationService.showMessage($localize`OpenStack project association was removed.`);
        this.dialogRef.close(true);
      }, error => {
        this.notificationService.showMessage($localize`Failed to remove OpenStack project association.`);
        this.dialogRef.close(false);
      }).add(() => {
        this.loading = false;
      });
    } else {
      this.loading = true;
      this.servicesApi.changeResourceAssociation(
        this.data.service.id,
        this.changeProjectForm.controls.project.value.id
      ).subscribe(response => {
        this.notificationService.showMessage($localize`OpenStack project association was removed.`);
        this.dialogRef.close(true);
      }, error => {
        this.notificationService.showMessage($localize`Failed to remove OpenStack project association.`);
        this.dialogRef.close(false);
      }).add(() => {
        this.loading = false;
      });
    }
  }

}
