import React, { useEffect, useState, useCallback, ReactElement } from 'react';
import { ProgressDropdown } from '@ohif/ui';

const workflowStepsToDropdownOptions = (steps = []) =>
  steps.map(step => ({
    label: step.name,
    value: step.id,
    info: step.info,
    activated: false,
    completed: false,
  }));

export function ProgressDropdownWithService({ servicesManager }: withAppTypes): ReactElement {
  const { workflowStepsService } = servicesManager.services;
  const [activeStepId, setActiveStepId] = useState(workflowStepsService.activeWorkflowStep?.id);

  const [dropdownOptions, setDropdownOptions] = useState(
    workflowStepsToDropdownOptions(workflowStepsService.workflowSteps)
  );

  const setCurrentAndPreviousOptionsAsCompleted = useCallback(currentOption => {
    if (currentOption.completed) {
      return;
    }

    setDropdownOptions(prevOptions => {
      const newOptionsState = [...prevOptions];
      const startIndex = newOptionsState.findIndex(option => option.value === currentOption.value);

      for (let i = startIndex; i >= 0; i--) {
        const option = newOptionsState[i];

        if (option.completed) {
          break;
        }

        newOptionsState[i] = {
          ...option,
          completed: true,
        };
      }

      return newOptionsState;
    });
  }, []);

  const handleDropdownChange = useCallback(
    ({ selectedOption }) => {
      if (!selectedOption) {
        return;
      }

      // TODO: Steps should be marked as completed after user has
      // completed some action when required (not implemented)
      setCurrentAndPreviousOptionsAsCompleted(selectedOption);
      setActiveStepId(selectedOption.value);
    },
    [setCurrentAndPreviousOptionsAsCompleted]
  );

  useEffect(() => {
    let timeoutId;

    if (activeStepId) {
      // We've used setTimeout to give it more time to update the UI since
      // create3DFilterableFromDataArray from Texture.js may take 600+ ms to run
      // when there is a new series to load in the next step but that resulted
      // in the followed React error when updating the content from left/right panels
      // and all component states were being lost:
      //   Error: Can't perform a React state update on an unmounted component
      workflowStepsService.setActiveWorkflowStep(activeStepId);
    }

    return () => clearTimeout(timeoutId);
  }, [activeStepId, workflowStepsService]);

  useEffect(() => {
    const { unsubscribe: unsubStepsChanged } = workflowStepsService.subscribe(
      workflowStepsService.EVENTS.STEPS_CHANGED,
      () => setDropdownOptions(workflowStepsToDropdownOptions(workflowStepsService.workflowSteps))
    );

    const { unsubscribe: unsubActiveStepChanged } = workflowStepsService.subscribe(
      workflowStepsService.EVENTS.ACTIVE_STEP_CHANGED,

      () => setActiveStepId(workflowStepsService.activeWorkflowStep.id)
    );

    return () => {
      unsubStepsChanged();
      unsubActiveStepChanged();
    };
  }, [servicesManager, workflowStepsService]);

  return (
    <ProgressDropdown
      options={dropdownOptions}
      value={activeStepId}
      onChange={handleDropdownChange}
    />
  );
}
