package com.airlock.iam.servicecontainer.app.infrastructure.webapp.view;

import com.airlock.iam.servicecontainer.api.domain.model.task.Task;
import com.airlock.iam.servicecontainer.app.application.configuration.TaskSchedule;
import com.airlock.iam.servicecontainer.app.infrastructure.webapp.presenter.TaskSchedulerServicePresenter;
import com.airlock.iam.servicecontainer.app.infrastructure.webapp.util.ServiceContainerVaadinTranslator;
import com.vaadin.ui.AbstractLayout;
import java.util.List;
import org.apache.commons.lang3.time.FastDateFormat;

public class TaskRepresentation {
   private static final FastDateFormat DATE_FORMAT = FastDateFormat.getInstance("dd.MM.yyyy HH:mm:ss");
   private final TaskSchedulerServicePresenter taskSchedulerServicePresenter;
   private final TaskSchedule taskSchedule;
   private boolean shouldBeRemoved;
   private final TaskRepresentationUI taskUI;

   public TaskRepresentation(TaskSchedulerServicePresenter taskSchedulerServicePresenter, TaskSchedule taskSchedule) {
      this.taskSchedulerServicePresenter = taskSchedulerServicePresenter;
      this.taskSchedule = taskSchedule;
      this.taskUI = new TaskRepresentationUI(taskSchedulerServicePresenter, taskSchedule);
      this.updateLastExecutionHeader();
      this.updateStatus();
      this.updateLastExecutionVisibility();
   }

   void updateUI() {
      this.updateLastExecutionHeader();
      this.updateProgress();
      if (this.taskUI.isInfoTableAttached()) {
         this.updateInfoTable();
      }

      if (this.taskUI.isLastExecutionTableAttached()) {
         this.updateLastExecutionTable();
      }

      if (this.taskUI.isStartStopButAttached()) {
         this.updateStatus();
      }
   }

   private void updateStatus() {
      this.taskUI.setServiceRunnable(this.taskSchedulerServicePresenter.isRunning());
      if (this.taskSchedule.isRunning()) {
         this.taskUI.setStatusRunning();
      } else {
         this.taskUI.setStatusIdle();
      }
   }

   private void updateInfoTable() {
      this.taskUI.updateInfoTable();
   }

   private void updateProgress() {
      if (this.taskSchedulerServicePresenter.isTaskRunning(this.taskSchedule)) {
         int progressPercentage = this.taskSchedulerServicePresenter.getProgressPercentage(this.taskSchedule);
         this.taskUI.updateProgress(progressPercentage);
      } else {
         this.taskUI.disableProgress();
      }
   }

   private void updateLastExecutionTable() {
      List<Task.ExecutionResult> lastExecutions = this.taskSchedulerServicePresenter.getLastExecutions(this.taskSchedule);
      int visibleEntries = this.taskUI.getNumberOfVisibleExecutionEntires();
      if (lastExecutions.size() > visibleEntries || lastExecutions.size() == 5) {
         this.taskUI.clearLatestExecutionTable();

         for (Task.ExecutionResult executionResult : lastExecutions) {
            String result = executionResult.isResult() ? "taskschedulerservice.ok" : "taskschedulerservice.not-ok";
            String translatedResult = ServiceContainerVaadinTranslator.translate(result);
            this.taskUI.addLatestExecutionItem(DATE_FORMAT.format(executionResult.getDate()), translatedResult);
         }
      }

      this.updateLastExecutionVisibility();
   }

   private void updateLastExecutionHeader() {
      List<Task.ExecutionResult> lastExecutions = this.taskSchedulerServicePresenter.getLastExecutions(this.taskSchedule);
      if (!lastExecutions.isEmpty()) {
         Task.ExecutionResult executionResult = lastExecutions.getLast();
         String result = executionResult.isResult() ? "taskschedulerservice.ok" : "taskschedulerservice.not-ok";
         this.taskUI.setLatestExecutionItemForHeader(ServiceContainerVaadinTranslator.translate(DATE_FORMAT.format(executionResult.getDate())), result);
         this.updateLastExecutionTable();
         this.updateInfoTable();
      }
   }

   private void updateLastExecutionVisibility() {
      boolean showLastExecutions = this.taskUI.getNumberOfVisibleExecutionEntires() != 0;
      this.taskUI.setLastExecutionVisible(showLastExecutions);
   }

   void setShouldBeRemoved(boolean remove) {
      this.shouldBeRemoved = remove;
   }

   boolean shouldBeRemoved() {
      return this.shouldBeRemoved;
   }

   AbstractLayout getLayout() {
      return this.taskUI.getLayout();
   }
}
