/*********************************************************************
 * Copyright (c) 2011 Boeing
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Boeing - initial API and implementation
 **********************************************************************/

package org.eclipse.osee.ats.ide.editor.tab.workflow.header;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.window.Window;
import org.eclipse.osee.ats.api.AtsApi;
import org.eclipse.osee.ats.api.IAtsWorkItem;
import org.eclipse.osee.ats.api.data.AtsArtifactTypes;
import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
import org.eclipse.osee.ats.api.user.AtsUser;
import org.eclipse.osee.ats.api.util.IAtsChangeSet;
import org.eclipse.osee.ats.api.workdef.IAtsStateDefinition;
import org.eclipse.osee.ats.api.workdef.StateOption;
import org.eclipse.osee.ats.api.workflow.hooks.IAtsTransitionHook;
import org.eclipse.osee.ats.api.workflow.hooks.IAtsWorkItemHook;
import org.eclipse.osee.ats.api.workflow.transition.ITransitionHelper;
import org.eclipse.osee.ats.api.workflow.transition.TransitionData;
import org.eclipse.osee.ats.api.workflow.transition.TransitionResults;
import org.eclipse.osee.ats.core.workflow.transition.TransitionHelperAdapter;
import org.eclipse.osee.ats.ide.editor.WorkflowEditor;
import org.eclipse.osee.ats.ide.internal.Activator;
import org.eclipse.osee.ats.ide.internal.AtsApiService;
import org.eclipse.osee.ats.ide.util.AtsUtilClient;
import org.eclipse.osee.ats.ide.util.UserCheckTreeDialog;
import org.eclipse.osee.ats.ide.util.widgets.dialog.CancelledReasonEnumDialog;
import org.eclipse.osee.ats.ide.workflow.AbstractWorkflowArtifact;
import org.eclipse.osee.ats.ide.workflow.transition.TransitionResultsUi;
import org.eclipse.osee.ats.ide.workflow.transition.TransitionToOperation;
import org.eclipse.osee.framework.core.operation.Operations;
import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
import org.eclipse.osee.framework.jdk.core.util.Collections;
import org.eclipse.osee.framework.jdk.core.util.Strings;
import org.eclipse.osee.framework.logging.OseeLevel;
import org.eclipse.osee.framework.logging.OseeLog;
import org.eclipse.osee.framework.ui.plugin.util.AWorkbench;
import org.eclipse.osee.framework.ui.plugin.util.ListSelectionDialogNoSave;
import org.eclipse.osee.framework.ui.skynet.widgets.XComboDam;
import org.eclipse.osee.framework.ui.skynet.widgets.dialog.EntryDialog;
import org.eclipse.osee.framework.ui.swt.Displays;
import org.eclipse.osee.framework.ui.swt.FontManager;
import org.eclipse.osee.framework.ui.swt.Widgets;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Hyperlink;

/**
 * @author Donald G. Dunne
 */
public class WfeTransitionHeader extends Composite {

   private final Label transitionAssigneesLabel;
   private final AbstractWorkflowArtifact workItem;
   private final WorkflowEditor editor;
   private IAtsStateDefinition userSelectedTransitionToState;
   private final boolean isEditable;
   private final Hyperlink transitionLabelLink;
   private final Hyperlink stateLabelLink;

   public WfeTransitionHeader(Composite parent, final WorkflowEditor editor, final boolean isEditable) {
      super(parent, SWT.NONE);
      this.editor = editor;
      this.isEditable = isEditable;

      workItem = editor.getWorkItem();
      setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      GridLayout layout = new GridLayout(editor.getWorkFlowTab().getHeader().isShowTargetedVersion() ? 7 : 5, false);
      layout.verticalSpacing = 0;
      layout.marginWidth = 0;
      layout.marginHeight = 0;
      setLayout(layout);
      editor.getWorkFlowTab().getManagedForm().getToolkit().adapt(this);

      transitionLabelLink = editor.getToolkit().createHyperlink(this, "Transition", SWT.NONE);
      transitionLabelLink.addHyperlinkListener(new HyperlinkAdapter() {
         @Override
         public void linkActivated(HyperlinkEvent e) {
            if (editor.isDirty()) {
               editor.doSave(null);
            }
            transitionLabelLink.setEnabled(false);
            handleTransitionButtonSelection();
         }
      });
      transitionLabelLink.setFont(FontManager.getCourierNew12Bold());
      transitionLabelLink.setToolTipText("Select to transition workflow to the default or selected state");

      Label transitionToLabel = editor.getToolkit().createLabel(this, "To");
      transitionToLabel.setLayoutData(new GridData());

      String toStateName = getToState() == null ? "<not set>" : getToState().getName();
      stateLabelLink = editor.getToolkit().createHyperlink(this, toStateName, SWT.NONE);
      stateLabelLink.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      stateLabelLink.addHyperlinkListener(new HyperlinkAdapter() {
         @Override
         public void linkActivated(HyperlinkEvent e) {
            try {
               IAtsStateDefinition selState = handleChangeTransitionToState(workItem, isEditable, getToState());
               if (selState != null) {
                  userSelectedTransitionToState = selState;
                  handleTransitionButtonSelection();
               }
            } catch (Exception ex) {
               OseeLog.log(Activator.class, Level.SEVERE, ex);
            }
         }
      });

      Hyperlink assigneesLabelLink = editor.getToolkit().createHyperlink(this, "Next State Assignee(s)", SWT.NONE);
      assigneesLabelLink.addHyperlinkListener(new HyperlinkAdapter() {
         @Override
         public void linkActivated(HyperlinkEvent e) {
            try {
               handleChangeTransitionAssignees(workItem);
            } catch (Exception ex) {
               OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
            }
         }
      });
      transitionAssigneesLabel =
         editor.getToolkit().createLabel(this, Strings.truncate(workItem.getTransitionAssigneesStr(), 100, true));
      transitionAssigneesLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      transitionAssigneesLabel.setToolTipText("Select to change assignee(s) upon transition to next state.");

   }

   public static IAtsStateDefinition handleChangeTransitionToState(AbstractWorkflowArtifact awa, final boolean isEditable, IAtsStateDefinition toStateDef) {
      List<IAtsStateDefinition> states = AtsApiService.get().getWorkItemService().getAllToStates(awa);
      ListSelectionDialogNoSave dialog =
         new ListSelectionDialogNoSave(Collections.castAll(states), Displays.getActiveShell().getShell(),
            "Select Transition-To State", null, "Select the state to transition to.\n\n" //
               + "Transition will happen upon selection and Transition button.\n\n" //
               + "Double-click will select, close and transition.",
            2, new String[] {"Transition", "Cancel"}, 0);

      if (dialog.open() == Window.OK) {
         Object obj = dialog.getSelected();
         return (IAtsStateDefinition) obj;
      }

      return null;
   }

   public void handleTransitionButtonSelection() {
      final IAtsStateDefinition toStateDef = getToState();
      if (toStateDef == null) {
         AWorkbench.popup("Must select state to transition.");
         refresh();
         return;
      }
      if (editor.isDirty()) {
         editor.doSave(null);
      }
      editor.getWorkFlowTab().setLoading(true);
      handleTransitionButtonSelection(workItem, isEditable, toStateDef, editor, this);
   }

   public static void handleTransitionButtonSelection(AbstractWorkflowArtifact awa, final boolean isEditable, IAtsStateDefinition toStateDef, final WorkflowEditor editor, final WfeTransitionHeader transitionHeader) {
      ITransitionHelper helper = new TransitionHelperAdapter(AtsApiService.get()) {

         @Override
         public String getToStateName() {
            return toStateDef.getName();
         }

         @Override
         public Collection<AtsUser> getToAssignees(IAtsWorkItem workItem) {
            AbstractWorkflowArtifact awa =
               (AbstractWorkflowArtifact) AtsApiService.get().getQueryService().getArtifact(workItem);
            return awa.getTransitionAssignees();
         }

         @Override
         public String getName() {
            return "Workflow Editor Transition";
         }

         @Override
         public TransitionData getCancellationReason(final TransitionData transitionData) {
            Displays.ensureInDisplayThread(new Runnable() {

               @Override
               public void run() {
                  IAtsStateDefinition toStateDef;
                  try {
                     toStateDef =
                        AtsApiService.get().getWorkDefinitionService().getStateDefinitionByName(awa, getToStateName());
                     if (toStateDef.getStateType().isCancelledState()) {
                        EntryDialog cancelDialog;
                        boolean useCancelledReasonEnumDialog =
                           toStateDef.getStateOptions().contains(StateOption.USE_CANCELLED_REASON_ENUM_DIALOG);
                        if (useCancelledReasonEnumDialog) {
                           cancelDialog = new CancelledReasonEnumDialog("Cancellation Reason",
                              "Select cancellation reason.  If other, please specify with details.");
                        } else {
                           cancelDialog = new EntryDialog("Cancellation Reason", "Enter cancellation reason.");
                        }
                        if (cancelDialog.open() != 0) {
                           transitionData.setDialogCancelled(true);
                           return;
                        }
                        if (useCancelledReasonEnumDialog) {
                           transitionData.setCancellationReason(((CancelledReasonEnumDialog) cancelDialog).getEntry());
                           transitionData.setCancellationReasonAttrType(AtsAttributeTypes.CancelledReasonEnum);
                           transitionData.setCancellationReasonDetails(
                              ((CancelledReasonEnumDialog) cancelDialog).getCancelledDetails());
                        } else {
                           transitionData.setCancellationReason(cancelDialog.getEntry());
                           transitionData.setCancellationReasonAttrType(AtsAttributeTypes.CancelledReason);
                        }
                     }
                  } catch (OseeCoreException ex) {
                     OseeLog.log(Activator.class, Level.SEVERE, ex);
                  }
               }
            }, true);
            return transitionData;
         }

         @Override
         public Collection<IAtsWorkItem> getWorkItems() {
            return Arrays.asList(awa);
         }

         @Override
         public IAtsChangeSet getChangeSet() {
            return null;
         }

         @Override
         public Collection<IAtsTransitionHook> getTransitionListeners() {
            try {
               return AtsApiService.get().getWorkItemService().getTransitionHooks();
            } catch (OseeCoreException ex) {
               OseeLog.log(Activator.class, Level.SEVERE, ex);
            }
            return java.util.Collections.emptyList();
         }

         @Override
         public AtsApi getServices() {
            return AtsApiService.get();
         }

         @Override
         public String getCancellationReasonDetails() {
            return null;
         }

         @Override
         public String getCancellationReason() {
            return null;
         }

      };
      final TransitionToOperation operation = new TransitionToOperation(helper);
      Operations.executeAsJob(operation, true, Job.SHORT, new JobChangeAdapter() {

         @Override
         public void done(IJobChangeEvent event) {
            TransitionResults results = operation.getResults();
            if (results != null) {
               results.setAtsApi(AtsApiService.get());
               if (results.isErrors()) {
                  TransitionResultsUi.reportDialog("Transition Failed", results);
                  AtsUtilClient.logExceptions(results);
               }
            }
            editor.getWorkFlowTab().setLoading(false);
            transitionHeader.refresh();
         }

      });
   }

   public void updateTransitionToAssignees() {
      Collection<AtsUser> assignees = null;
      // Determine if the is an override set of assignees
      for (IAtsWorkItemHook item : AtsApiService.get().getWorkItemService().getWorkItemHooks()) {
         String decisionValueIfApplicable = "";
         if (workItem.isOfType(
            AtsArtifactTypes.DecisionReview) && editor.getWorkFlowTab().getCurrentStateSection().getPage().getLayoutData(
               AtsAttributeTypes.Decision.getName()) != null) {
            XComboDam xWidget = (XComboDam) editor.getWorkFlowTab().getCurrentStateSection().getPage().getLayoutData(
               AtsAttributeTypes.Decision.getName()).getXWidget();
            if (xWidget != null) {
               decisionValueIfApplicable = xWidget.get();
            }
         }
         assignees = item.getOverrideTransitionToAssignees(workItem, decisionValueIfApplicable);
         if (assignees != null) {
            break;
         }
      }
      // If override set and isn't the same as already selected, update
      if (assignees != null && !workItem.getTransitionAssignees().equals(assignees)) {
         workItem.setTransitionAssignees(assignees);
         editor.onDirtied();
      }
      refresh();
   }

   public IAtsStateDefinition getToState() {
      IAtsStateDefinition state = AtsApiService.get().getWorkItemService().getDefaultToState(workItem);
      if (userSelectedTransitionToState != null) {
         return userSelectedTransitionToState;
      }
      // Determine if there is a transitionToStateOverride for this page
      String transitionStateOverride = null;
      for (IAtsTransitionHook item : AtsApiService.get().getWorkItemService().getTransitionHooks()) {
         transitionStateOverride = item.getOverrideTransitionToStateName(editor.getWorkItem());
         if (transitionStateOverride != null) {
            break;
         }
      }
      if (transitionStateOverride != null) {
         // Return if override state is same as selected
         if (AtsApiService.get().getWorkItemService().getDefaultToState(workItem).getName().equals(
            transitionStateOverride)) {
            state = AtsApiService.get().getWorkItemService().getDefaultToState(workItem);
         }
         // Find page corresponding to override state name
         for (IAtsStateDefinition toState : workItem.getStateDefinition().getToStates()) {
            if (toState.getName().equals(transitionStateOverride)) {
               state = toState;
               break;
            }
         }
      }
      return state;
   }

   public void refresh() {
      Displays.ensureInDisplayThread(new Runnable() {

         @Override
         public void run() {
            if (Widgets.isAccessible(transitionAssigneesLabel)) {
               IAtsStateDefinition toState = userSelectedTransitionToState;
               if (toState == null) {
                  toState = AtsApiService.get().getWorkItemService().getDefaultToState(workItem);
               }
               if (toState == null) {
                  stateLabelLink.setText("<Not Set>");
               } else {
                  stateLabelLink.setText(toState.getName());
               }
               stateLabelLink.getParent().layout();

               transitionLabelLink.setEnabled(true);

               transitionAssigneesLabel.setText(workItem.getTransitionAssigneesStr());
               transitionAssigneesLabel.getParent().layout();

               userSelectedTransitionToState = null;
            }
         }
      });
   }

   private void handleChangeTransitionAssignees(AbstractWorkflowArtifact aba) {
      userSelectedTransitionToState = getToState();
      if (userSelectedTransitionToState == null) {
         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "No Transition State Selected");
         return;
      }
      if (userSelectedTransitionToState.getStateType().isCompletedOrCancelledState()) {
         AWorkbench.popup("ERROR", "No Assignees in Completed and Cancelled states");
         return;
      }
      UserCheckTreeDialog uld = new UserCheckTreeDialog();
      uld.setInitialSelections(aba.getTransitionAssignees());
      if (workItem.getParentTeamWorkflow() != null) {
         uld.setTeamMembers(AtsApiService.get().getTeamDefinitionService().getMembersAndLeads(
            workItem.getParentTeamWorkflow().getTeamDefinition()));
      }
      if (uld.open() != 0) {
         return;
      }
      Collection<AtsUser> users = uld.getUsersSelected();
      if (users.isEmpty()) {
         AWorkbench.popup("ERROR", "Must have at least one assignee");
         return;
      }
      workItem.setTransitionAssignees(users);
      refresh();
      editor.onDirtied();
   }

   public boolean isSelected() {
      return userSelectedTransitionToState != null;
   }

}
