'use strict';

exports.__esModule = true;
exports.PermissionContext = undefined;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

exports.default = TutorialModal;

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _debounce = require('lodash/debounce');

var _debounce2 = _interopRequireDefault(_debounce);

var _components = require('../../components');

var _2 = require('./..');

var _TutorialEditor = require('./components/TutorialEditor');

var _TutorialEditor2 = _interopRequireDefault(_TutorialEditor);

var _TutorialStep = require('./components/TutorialStep');

var _TutorialStep2 = _interopRequireDefault(_TutorialStep);

var _TutorialStepNav = require('./components/TutorialStepNav');

var _TutorialStepNav2 = _interopRequireDefault(_TutorialStepNav);

var _TutorialResponse = require('./components/TutorialResponse');

var _TutorialResponse2 = _interopRequireDefault(_TutorialResponse);

var _TutorialReview = require('./components/TutorialReview');

var _TutorialReview2 = _interopRequireDefault(_TutorialReview);

var _stepDefaults = require('./constants/stepDefaults');

var _tutorials = require('./proptypes/tutorials');

var _apiActions = require('./apiActions');

var ApiActions = _interopRequireWildcard(_apiActions);

var _useReadmeApi2 = require('../../../core/hooks/useReadmeApi');

var _useReadmeApi3 = _interopRequireDefault(_useReadmeApi2);

var _styleModule = require('./style.module.scss');

var _styleModule2 = _interopRequireDefault(_styleModule);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } // 3rd-Party Libraries


// Components


// Constants


// Internals


// Style


// Permissions
var PermissionContext = exports.PermissionContext = _react2.default.createContext(true);

function TutorialModal(_ref) {
  var action = _ref.action,
      baseUrl = _ref.baseUrl,
      closeTutorialModal = _ref.closeTutorialModal,
      endpointOnboarding = _ref.endpointOnboarding,
      referenceEnabled = _ref.referenceEnabled,
      requestDataRefresh = _ref.requestDataRefresh,
      target = _ref.target,
      tutorial = _ref.tutorial,
      props = _objectWithoutProperties(_ref, ['action', 'baseUrl', 'closeTutorialModal', 'endpointOnboarding', 'referenceEnabled', 'requestDataRefresh', 'target', 'tutorial']);

  var modalRef = _react2.default.createRef();
  var tutorialForm = (0, _react.useRef)(false);
  // Modal interaction state

  var _useState = (0, _react.useState)(props.open),
      open = _useState[0],
      setOpenState = _useState[1];

  var _useState2 = (0, _react.useState)(0),
      selectedStep = _useState2[0],
      setSelectedStep = _useState2[1];

  var _useState3 = (0, _react.useState)(0),
      selectedTab = _useState3[0],
      setSelectedTab = _useState3[1];

  var _useState4 = (0, _react.useState)(false),
      tutorialReview = _useState4[0],
      setTutorialReview = _useState4[1];

  var _useState5 = (0, _react.useState)(false),
      tutorialCreated = _useState5[0],
      setTutorialCreated = _useState5[1];
  // Modal data state


  var _useState6 = (0, _react.useState)(tutorial.steps),
      steps = _useState6[0],
      setSteps = _useState6[1];

  var _useState7 = (0, _react.useState)(tutorial.snippet),
      snippet = _useState7[0],
      setSnippet = _useState7[1];

  var _useState8 = (0, _react.useState)(tutorial),
      tutorialShell = _useState8[0],
      setTutorialShell = _useState8[1];
  // Indirect request handling (via API)


  var _useState9 = (0, _react.useState)([]),
      endpoints = _useState9[0],
      setEndpoints = _useState9[1];

  var _useReadmeApi = (0, _useReadmeApi3.default)(baseUrl),
      response = _useReadmeApi.response,
      error = _useReadmeApi.error,
      setError = _useReadmeApi.setError,
      initRequest = _useReadmeApi.initRequest;

  // Applying outer props to modal component ref


  (0, _react.useEffect)(function () {
    if (props.open !== open) {
      setOpenState(props.open);
      modalRef.current.toggle(props.open);

      if (props.open) {
        setTutorialCreated(false);
        setTutorialReview(false);
      }
    }
  });

  /* Start: Applying Hub2 API request data to state */
  (0, _react.useEffect)(function () {
    if (action !== 'View' && !endpoints.length) ApiActions.getEndpoints(initRequest);
  }, [open]);

  (0, _react.useEffect)(function () {
    if (response.endpoints) setEndpoints(response.endpoints);
  }, [response.endpoints]);

  (0, _react.useEffect)(function () {
    if (response.tutorial) {
      setTutorialShell(_extends({}, response.tutorial));
      setSnippet(_extends({}, response.tutorial.snippet));
      requestDataRefresh();
      setError(null);
      // Notifications -> Error/Success or Published Successfully
      // If in creation flow, show success modal
      if (action === 'Create' && response.tutorial.published) {
        setTutorialCreated(true);
        setTutorialReview(false);
        // Otherwise, flash notification
      } else {
        closeTutorialModal();
      }
    }
  }, [response.tutorial]);

  (0, _react.useEffect)(function () {
    if (response.snippet) setSnippet(response.snippet);
  }, [response.snippet]);

  (0, _react.useEffect)(function () {
    if (response.codeString) {
      setSnippet(function (prevSnippet) {
        var _response$codeString = response.codeString,
            code = _response$codeString.code,
            index = _response$codeString.index;

        prevSnippet.codeOptions[index].code = code;
        return _extends({}, prevSnippet);
      });
    }
  }, [response.codeString]);
  /* End: Applying Hub2 API request data to state */

  /* Start: Applying new prop data to state */
  (0, _react.useEffect)(function () {
    setSelectedStep(0);
    tutorial.steps[0].isOpen = true;
    setSteps([].concat(tutorial.steps));
  }, [tutorial.steps]);

  (0, _react.useEffect)(function () {
    setSelectedTab(0);
    setSnippet(_extends({}, tutorial.snippet));
  }, [tutorial.snippet]);

  (0, _react.useEffect)(function () {
    setTutorialShell(_extends({}, tutorial));
  }, [tutorial]);
  /* End: Applying new prop data to state */

  /* Start Syncing States */
  // Syncing Step and Snippet states to parent tutorial
  (0, _react.useEffect)(function () {
    setTutorialShell(function (prevTutorial) {
      return _extends({}, prevTutorial, {
        stepCount: steps.length,
        steps: steps,
        snippet: snippet
      });
    });
  }, [steps, snippet]);
  // Syncing steps[n].lineNumbers with snippet.codeOptions
  // These are disjointed arrays which can be referenced in ./propTypes/tutorials
  // Which deal with highly related, but disparate data. We need to ensure
  // that they have the same number of elements. We can do that by reading from `codeOptions`.
  (0, _react.useEffect)(function () {
    var tabCount = snippet.codeOptions.length;

    setSteps(function (prevSteps) {
      prevSteps.forEach(function (_ref2) {
        var lineNumbers = _ref2.lineNumbers;

        if (lineNumbers.length > tabCount) lineNumbers.splice(selectedTab, 1);
        if (lineNumbers.length < tabCount) lineNumbers.push('');
      });
      return prevSteps;
    });
  }, [snippet.codeOptions.length]);
  /* End Syncing States */

  var navStep = function navStep(direction) {
    setSteps(function (prevSteps) {
      var newSelection = selectedStep + direction;

      prevSteps[selectedStep].isOpen = false;
      prevSteps[newSelection].isOpen = true;
      setSelectedStep(newSelection);

      return [].concat(prevSteps);
    });
  };

  var validateStep = function validateStep() {
    return tutorialForm.current.reportValidity();
  };

  var selectStep = function selectStep(index) {
    if (validateStep()) {
      setSelectedStep(index);
      setSteps(function (prevSteps) {
        var step = prevSteps[index];
        var previousStep = prevSteps.find(function (s) {
          return s.isOpen;
        });

        previousStep.isOpen = false;
        step.isOpen = true;

        return [].concat(prevSteps);
      });
    }
  };

  var shiftStepOrder = function shiftStepOrder(index, direction) {
    setSteps(function (prevSteps) {
      var swap = index + direction;
      // https://stackoverflow.com/a/872317
      // Acts a means to swap indices without assigning to a temp variable
      var _ref3 = [prevSteps[swap], prevSteps[index]];
      prevSteps[index] = _ref3[0];
      prevSteps[swap] = _ref3[1];


      var updatedSelection = _lodash2.default.findIndex(steps, function (s) {
        return s.isOpen;
      });
      setSelectedStep(updatedSelection);

      return [].concat(prevSteps);
    });
  };

  var createStep = function createStep() {
    if (validateStep()) {
      setSelectedStep(steps.length);
      setSteps(function (prevSteps) {
        var prevOpen = prevSteps.find(function (s) {
          return s.isOpen;
        });
        prevOpen.isOpen = false;

        return [].concat(prevSteps, [_extends({}, _lodash2.default.cloneDeep(_stepDefaults.DEFAULT_STEP), {
          lineNumbers: snippet.codeOptions.map(function () {
            return '';
          })
        })]);
      });
    }
  };

  var updateStep = function updateStep(data) {
    var _Object$entries$ = Object.entries(data)[0],
        key = _Object$entries$[0],
        value = _Object$entries$[1];


    setSteps(function (prevSteps) {
      var step = prevSteps[selectedStep];
      step[key] = value;
      return [].concat(prevSteps);
    });
  };

  var deleteStep = function deleteStep(index) {
    setSelectedStep(0);
    setSteps(function (prevSteps) {
      prevSteps.splice(index, 1);
      prevSteps[0].isOpen = true;

      return [].concat(prevSteps);
    });
  };

  var updateSnippet = function updateSnippet(data) {
    setSnippet(function (prevSnippet) {
      return _extends({}, prevSnippet, data);
    });
  };

  var clearSnippetSelection = function clearSnippetSelection() {
    setSelectedTab(0);
    setSnippet(_lodash2.default.cloneDeep(_stepDefaults.DEFAULT_SNIPPET));
  };

  var updateTutorial = function updateTutorial(data) {
    setTutorialShell(function (prevShell) {
      return _extends({}, prevShell, data);
    });
  };

  var upsertTutorial = function upsertTutorial(e) {
    e.preventDefault();
    if (validateStep()) {
      if (tutorialShell._id) return ApiActions.updateTutorial(initRequest, tutorialShell);
      return ApiActions.createTutorial(initRequest, tutorialShell);
    }
    return false;
  };

  var debounceInputChange = (0, _debounce2.default)(function (inputData) {
    updateTutorial(inputData);
  }, 300);

  return _react2.default.createElement(
    PermissionContext.Provider,
    { value: action === 'View' },
    _react2.default.createElement(
      _components.Modal,
      {
        ref: modalRef,
        className: [_styleModule2.default.TutorialModal, tutorialCreated && _styleModule2.default.TutorialModal_created].join(' '),
        onClose: closeTutorialModal,
        open: !!open,
        target: target
      },
      !tutorialReview && !tutorialCreated && _react2.default.createElement(
        _react2.default.Fragment,
        null,
        _react2.default.createElement(
          _components.Flex,
          { align: 'center', className: _styleModule2.default['TutorialModal-Nav'], justify: 'between' },
          action === 'View' && _react2.default.createElement(
            _components.Title,
            { className: _styleModule2.default['TutorialStepNav-Title'], level: 4 },
            tutorialShell.title
          ),
          action !== 'View' && _react2.default.createElement(
            _components.Flex,
            { align: 'center' },
            _react2.default.createElement(
              'button',
              { className: _styleModule2.default['TutorialModal-Nav-Tab'] + ' ' + _styleModule2.default['TutorialModal-Nav-Tab_active'] },
              _react2.default.createElement('i', { className: _styleModule2.default['TutorialModal-Nav-Tab-Icon'] + ' fa fa-cog' }),
              'Configure'
            ),
            _react2.default.createElement(
              'button',
              {
                className: _styleModule2.default['TutorialModal-Nav-Tab'],
                form: 'tutorialForm',
                onClick: function onClick(e) {
                  e.preventDefault();
                  if (validateStep()) setTutorialReview(true);
                }
              },
              _react2.default.createElement('i', { className: _styleModule2.default['TutorialModal-Nav-Tab-Icon'] + ' fa fa-paint-brush' }),
              'Appearance'
            )
          ),
          _react2.default.createElement(
            _components.Flex,
            { align: 'center' },
            action !== 'View' && _react2.default.createElement(
              _components.Button,
              { bem: { slate: true }, form: 'tutorialForm', onClick: function onClick(e) {
                  return upsertTutorial(e);
                }, type: 'submit' },
              'Save & Close'
            ),
            _react2.default.createElement(
              'button',
              { className: _styleModule2.default['TutorialModal-Nav-Close'], onClick: closeTutorialModal, type: 'button' },
              _react2.default.createElement('i', { className: 'icon icon-readme-remove' })
            )
          )
        ),
        _react2.default.createElement(
          'div',
          { className: _styleModule2.default['TutorialModal-Row'] },
          _react2.default.createElement(
            'form',
            {
              ref: tutorialForm,
              className: [_styleModule2.default['TutorialModal-Col'], _styleModule2.default['TutorialModal-Col_steps']].join(' '),
              id: 'tutorialForm'
            },
            action !== 'View' && _react2.default.createElement(_components.Input, {
              className: _styleModule2.default['TutorialModal-Col-Input'],
              onChange: function onChange(e) {
                return debounceInputChange({ title: e.target.value });
              },
              placeholder: 'Tutorial Title',
              required: true,
              value: tutorialShell.title
            }),
            _react2.default.createElement(
              _TutorialStepNav2.default,
              { createStep: createStep },
              steps && steps.map(function (step, index) {
                return _react2.default.createElement(_TutorialStep2.default, {
                  key: 'tutorial-step-' + index,
                  action: action,
                  deleteStep: deleteStep,
                  handleClick: function handleClick() {
                    return selectStep(index);
                  },
                  index: index,
                  lastIndex: steps.length - 1,
                  navStep: navStep,
                  shiftOrder: function shiftOrder(direction) {
                    return shiftStepOrder(index, direction);
                  },
                  step: step,
                  updateStep: updateStep
                });
              })
            )
          ),
          _react2.default.createElement(
            'div',
            {
              className: [_styleModule2.default['TutorialModal-Col'], !(action !== 'View' || action === 'View' && !!tutorialShell.response.length) && _styleModule2.default['TutorialModal-Col_singleEditor']].join(' ')
            },
            _react2.default.createElement(_TutorialEditor2.default, {
              key: 'tutorial-editor-' + selectedStep,
              baseUrl: baseUrl,
              clearSnippetSelection: clearSnippetSelection,
              endpointOnboarding: endpointOnboarding,
              endpoints: endpoints,
              getCode: function getCode(data) {
                return ApiActions.getCodeString(initRequest, data);
              },
              handleSnippetSelection: function handleSnippetSelection(data) {
                return ApiActions.getCodeSnippets(initRequest, data);
              },
              lineNumbers: steps[selectedStep].lineNumbers,
              referenceEnabled: referenceEnabled,
              requestDataRefresh: requestDataRefresh,
              selectedTab: selectedTab,
              setSelectedTab: setSelectedTab,
              snippet: snippet,
              updateSnippet: updateSnippet,
              updateStep: updateStep
            }),
            (action !== 'View' || action === 'View' && tutorialShell.response && !!tutorialShell.response.length) && _react2.default.createElement(_TutorialResponse2.default, {
              key: 'tutorial-result-' + selectedStep,
              response: tutorialShell.response,
              updateTutorial: updateTutorial
            })
          )
        )
      ),
      tutorialReview && _react2.default.createElement(
        _react2.default.Fragment,
        null,
        _react2.default.createElement(
          _components.Flex,
          { align: 'center', className: _styleModule2.default['TutorialModal-Nav'], justify: 'between' },
          _react2.default.createElement(
            _components.Flex,
            { align: 'center' },
            _react2.default.createElement(
              'button',
              {
                className: _styleModule2.default['TutorialModal-Nav-Tab'],
                form: 'tutorialForm',
                onClick: function onClick(e) {
                  e.preventDefault();
                  if (validateStep()) setTutorialReview(false);
                }
              },
              _react2.default.createElement('i', { className: _styleModule2.default['TutorialModal-Nav-Tab-Icon'] + ' fa fa-cog' }),
              'Configure'
            ),
            _react2.default.createElement(
              'button',
              { className: _styleModule2.default['TutorialModal-Nav-Tab'] + ' ' + _styleModule2.default['TutorialModal-Nav-Tab_active'] },
              _react2.default.createElement('i', { className: _styleModule2.default['TutorialModal-Nav-Tab-Icon'] + ' fa fa-paint-brush' }),
              'Appearance'
            )
          ),
          _react2.default.createElement(
            _components.Flex,
            { align: 'center' },
            _react2.default.createElement(
              _components.Button,
              { bem: { slate: true }, form: 'tutorialForm', onClick: function onClick(e) {
                  return upsertTutorial(e);
                }, type: 'submit' },
              'Save & Close'
            ),
            _react2.default.createElement(
              'button',
              { className: _styleModule2.default['TutorialModal-Nav-Close'], onClick: closeTutorialModal, type: 'button' },
              _react2.default.createElement('i', { className: 'icon icon-readme-remove' })
            )
          )
        ),
        _react2.default.createElement(
          'div',
          { className: _styleModule2.default['TutorialModal-Row'] },
          _react2.default.createElement(
            'form',
            {
              ref: tutorialForm,
              className: [_styleModule2.default['TutorialModal-Col'], _styleModule2.default['TutorialModal-Col_review']].join(' '),
              id: 'tutorialForm'
            },
            _react2.default.createElement(_TutorialReview2.default, {
              debounceInputChange: debounceInputChange,
              endpoints: endpoints,
              tutorial: tutorialShell,
              updateTutorial: updateTutorial
            })
          ),
          _react2.default.createElement(
            'div',
            { className: [_styleModule2.default['TutorialModal-Col'], _styleModule2.default['TutorialModal-Col_review']].join(' ') },
            _react2.default.createElement(
              _components.Flex,
              { align: 'center', className: _styleModule2.default['TutorialModal-Col-Wrapper'], justify: 'center', layout: 'col' },
              _react2.default.createElement(_2.TutorialCard, {
                className: _styleModule2.default['TutorialModal-Col-Wrapper-Card'],
                tutorial: tutorialShell,
                tutorialReview: tutorialReview
              }),
              _react2.default.createElement(
                'span',
                { className: _styleModule2.default['TutorialModal-Col-Wrapper-Caption'] },
                'Tutorial Page Preview'
              )
            ),
            _react2.default.createElement(
              _components.Flex,
              { align: 'center', className: _styleModule2.default['TutorialModal-Col-Wrapper'], justify: 'center', layout: 'col' },
              _react2.default.createElement(_2.TutorialTile, { tutorial: tutorialShell }),
              _react2.default.createElement(
                'span',
                { className: _styleModule2.default['TutorialModal-Col-Wrapper-Caption'] },
                'Guide/Reference Embed Preview'
              )
            )
          )
        )
      ),
      tutorialCreated && _react2.default.createElement(
        _2.TutorialObstacle,
        {
          body: 'You can view and update your tutorial from the dedicated tutorial page.',
          className: _styleModule2.default['TutorialModal-Obstacle'],
          closeTutorialModal: closeTutorialModal,
          heading: 'You\u2019ve published a Tutorial!',
          tutorial: tutorialShell
        },
        _react2.default.createElement(
          _components.Button,
          { onClick: closeTutorialModal },
          'View Tutorials'
        )
      ),
      action !== 'View' && error && _react2.default.createElement(
        _components.Notification,
        { color: 'red', dismissible: true, handleClick: function handleClick() {
            return setError(null);
          }, position: 'top' },
        _react2.default.createElement(
          'p',
          null,
          error
        )
      )
    )
  );
}

TutorialModal.propTypes = process.env.NODE_ENV !== "production" ? {
  action: _propTypes2.default.oneOf(['Create', 'Edit', 'View']),
  baseUrl: _propTypes2.default.string,
  closeTutorialModal: _propTypes2.default.func,
  endpointOnboarding: _propTypes2.default.bool,
  open: _propTypes2.default.bool,
  referenceEnabled: _propTypes2.default.bool,
  requestDataRefresh: _propTypes2.default.func,
  target: _propTypes2.default.string,
  tutorial: _tutorials.TutorialProp
} : {};

TutorialModal.defaultProps = {
  action: 'View',
  baseUrl: '',
  closeTutorialModal: function closeTutorialModal() {},
  open: false,
  referenceEnabled: false,
  requestDataRefresh: function requestDataRefresh() {},
  tutorial: _lodash2.default.cloneDeep(_stepDefaults.DEFAULT_TUTORIAL)
};