import {Component, OnDestroy, OnInit} from '@angular/core';
import {Subscription} from 'rxjs';
import {ActivatedRoute, Router} from '@angular/router';

import {TaskService} from 'app/workplace/services/task.service';
import {RemoveConfirmationService} from 'app/services/remove-confirmation/remove-confirmation.service';

import {Task} from 'app/workplace/models/task';
import {ErrorModel} from 'app/models/modal-error';
import {ErrorModalService} from 'app/services/errorModal/error-modal.service';
import {RequestInProgressService} from 'app/services/requestInProgress/request-in-progress.service';
import {AlertService} from 'app/services/alert/alert.service';
import {AlertModel, AlertType} from 'app/models/alert';
import {TaskanaDate} from 'app/shared/util/taskana.date';
import {ObjectReference} from 'app/workplace/models/object-reference';
import {Workbasket} from 'app/models/workbasket';
import {WorkplaceService} from 'app/workplace/services/workplace.service';

@Component({
  selector: 'taskana-task-details',
  templateUrl: './taskdetails.component.html',
  styleUrls: ['./taskdetails.component.scss']
})
export class TaskdetailsComponent implements OnInit, OnDestroy {
  task: Task = undefined;
  taskClone: Task = undefined;
  requestInProgress = false;
  tabSelected = 'general';
  currentWorkbasket: Workbasket = undefined;
  currentId: string = undefined;

  private routeSubscription: Subscription;
  private workbasketSubscription: Subscription;

  constructor(private route: ActivatedRoute,
              private taskService: TaskService,
              private workplaceService: WorkplaceService,
              private router: Router,
              private removeConfirmationService: RemoveConfirmationService,
              private requestInProgressService: RequestInProgressService,
              private alertService: AlertService,
              private errorModalService: ErrorModalService) {
  }

  ngOnInit() {
    this.currentWorkbasket = this.workplaceService.currentWorkbasket;
    this.workbasketSubscription = this.workplaceService.getSelectedWorkbasket().subscribe(workbasket => {
      this.currentWorkbasket = workbasket;
    });
    this.routeSubscription = this.route.params.subscribe(params => {
      this.currentId = params['id'];
      // redirect if user enters through a deep-link
      if (!this.currentWorkbasket && this.currentId === 'new-task') {
        this.router.navigate(['']);
      }
      this.getTask();
    });
  }

  resetTask(): void {
    this.task = {...this.taskClone};
    this.task.customAttributes = this.taskClone.customAttributes.slice(0);
    this.task.callbackInfo = this.taskClone.callbackInfo.slice(0);
    this.task.primaryObjRef = {...this.taskClone.primaryObjRef};
    this.alertService.triggerAlert(new AlertModel(AlertType.INFO, 'Reset edited fields'));
  }

  getTask(): void {
    this.requestInProgress = true;
    if (this.currentId === 'new-task') {
      this.requestInProgress = false;
      this.task = new Task(undefined, new ObjectReference(), this.currentWorkbasket);
    } else {
      this.taskService.getTask(this.currentId).subscribe(task => {
        this.requestInProgress = false;
        this.task = task;
        this.cloneTask();
        this.taskService.selectTask(task);
      }, err => {
        this.errorModalService.triggerError(
          new ErrorModel('An error occurred while fetching the task', err));
      });
    }
  }

  onSave() {
    this.requestInProgressService.setRequestInProgress(true);
    this.currentId === 'new-task' ? this.createTask() : this.updateTask();
  }

  updateTask() {
    this.taskService.updateTask(this.task).subscribe(task => {
      this.requestInProgressService.setRequestInProgress(false);
      this.task = task;
      this.cloneTask();
      this.taskService.publishUpdatedTask(task);
      this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'Update successful!'))
    }, err => {
      this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'Update not successful!'))
    });
  }

  createTask() {
    this.addDateToTask();
    this.taskService.createTask(this.task).subscribe(task => {
      this.requestInProgressService.setRequestInProgress(false);
      this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Task ${this.currentId} was created successfully`));
      this.task = task;
      this.taskService.selectTask(this.task);
      this.taskService.publishAddedTask(task);
      this.router.navigate(['../' + task.taskId], {relativeTo: this.route});
    });
  }

  private addDateToTask() {
    const date = TaskanaDate.getDate();
    this.task.created = date;
    this.task.modified = date;
  }

  openTask() {
    this.router.navigate([{outlets: {detail: `task/${this.currentId}`}}], {relativeTo: this.route.parent});
  }

  workOnTaskDisabled(): boolean {
    return this.task ? this.task.state === 'COMPLETED' : false;
  }

  deleteTask(): void {
    this.removeConfirmationService.setRemoveConfirmation(this.deleteTaskConfirmation.bind(this),
      `You are going to delete Task: ${this.currentId}. Can you confirm this action?`);
  }

  deleteTaskConfirmation(): void {
    this.taskService.deleteTask(this.task).subscribe();
    this.taskService.publishDeletedTask(this.task);
    this.task = null;
    this.router.navigate([`/workplace/tasks`]);
  }

  selectTab(tab: string): void {
    this.tabSelected = tab;
  }

  backClicked(): void {
    this.task = undefined;
    this.taskService.selectTask(this.task);
    this.router.navigate(['./'], {relativeTo: this.route.parent});
  }

  ngOnDestroy(): void {
    if (this.routeSubscription) {
      this.routeSubscription.unsubscribe();
    }
  }

  private cloneTask() {
    this.taskClone = {...this.task};
    this.taskClone.customAttributes = this.task.customAttributes.slice(0);
    this.taskClone.callbackInfo = this.task.callbackInfo.slice(0);
    this.taskClone.primaryObjRef = {...this.task.primaryObjRef};
  }
}
