import _extends from "@babel/runtime/helpers/extends";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
var _excluded = ["children", "className"];

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

/* eslint-disable react/jsx-props-no-spreading */

/* eslint-disable default-case */
import React, { useState, useLayoutEffect, useReducer, useCallback, useMemo } from "react";
import cx from "classnames";
import { SlotsProvider } from "nano-slots";
import useMediaQuery from "../../styles/useMediaQuery";
import getClasses from "./styles";
import LayoutContext, { modes } from "./LayoutContext";
import { mediaBreakpointDownLg, mediaBreakpointUpMd } from "../../styles/breakpoints";
var breakpoints = {
  mobile: "MOBILE",
  desktop: "DESKTOP",
  largeDesktop: "LARGE_DESKTOP"
};
var initialState = {
  collapseNav: true,
  openCollapsedNav: false,
  enableCollapseNav: false,
  automatedCloseNav: false,
  openSidebar: false,
  breakpoint: breakpoints.mobile,
  preferMode: undefined,
  mode: modes.popover,
  nav: false,
  sidebar: false,
  enableCollapse: false,
  enableClickAway: true
};
var SET_BREAKPOINT_DESKTOP_LARGE = "SET_BREAKPOINT_DESKTOP_LARGE";
var SET_BREAKPOINT_DESKTOP = "SET_BREAKPOINT_DESKTOP";
var SET_BREAKPOINT_MOBILE = "SET_BREAKPOINT_MOBILE";
var OPEN_SIDEBAR = "OPEN_SIDEBAR";
var CLOSE_SIDEBAR = "CLOSE_SIDEBAR";
var OPEN_NAV = "OPEN_NAV";
var CLOSE_NAV = "CLOSE_NAV";
var SET_MODE = "SET_MODE";
var SET_PREFER_MODE = "SET_PREFER_MODE";
var SET_CLICK_AWAY = "SET_CLICK_AWAY";

function reducer(state, action) {
  switch (action.type) {
    case SET_BREAKPOINT_DESKTOP_LARGE:
      return _objectSpread(_objectSpread({}, state), {}, {
        mode: state.preferMode !== modes.popover ? modes.sidebar : modes.popover,
        breakpoint: breakpoints.largeDesktop,
        enableCollapse: true
      });

    case SET_BREAKPOINT_DESKTOP:
      return _objectSpread(_objectSpread({}, state), {}, {
        mode: state.preferMode !== modes.popover ? modes.sidebar : modes.popover,
        breakpoint: breakpoints.desktop,
        enableCollapse: !state.sidebar
      });

    case SET_BREAKPOINT_MOBILE:
      return _objectSpread(_objectSpread({}, state), {}, {
        mode: modes.popover,
        breakpoint: breakpoints.mobile,
        enableCollapse: false
      });

    case OPEN_SIDEBAR:
      return _objectSpread(_objectSpread({}, state), {}, {
        sidebar: true,
        mode: state.preferMode === modes.popover || state.breakpoint !== breakpoints.largeDesktop ? modes.popover : modes.sidebar,
        enableCollapse: state.breakpoint === breakpoints.largeDesktop
      });

    case CLOSE_SIDEBAR:
      return _objectSpread(_objectSpread({}, state), {}, {
        sidebar: false,
        mode: state.preferMode !== modes.popover && state.breakpoint !== breakpoints.mobile ? modes.sidebar : modes.popover,
        enableCollapse: state.breakpoint !== breakpoints.mobile
      });

    case OPEN_NAV:
      if (state.nav) {
        break;
      } else {
        return _objectSpread(_objectSpread({}, state), {}, {
          nav: true
        });
      }

    case CLOSE_NAV:
      if (!state.nav) {
        break;
      } else {
        return _objectSpread(_objectSpread({}, state), {}, {
          nav: false
        });
      }

    case SET_MODE:
      return _objectSpread(_objectSpread({}, state), {}, {
        nav: false,
        mode: action.payload,
        preferMode: action.payload
      });

    case SET_CLICK_AWAY:
      if (state.enableClickAway === action.payload) {
        break;
      } else {
        return _objectSpread(_objectSpread({}, state), {}, {
          enableClickAway: action.payload
        });
      }

    case SET_PREFER_MODE:
      if (action.payload === modes.popover) {
        return _objectSpread(_objectSpread({}, state), {}, {
          nav: false,
          mode: action.payload,
          preferMode: action.payload
        });
      }

      if (state.breakpoint === breakpoints.largeDesktop || state.breakpoint === breakpoints.desktop && !state.sidebar) {
        return _objectSpread(_objectSpread({}, state), {}, {
          nav: false,
          mode: action.payload,
          preferMode: action.payload
        });
      }

      return _objectSpread(_objectSpread({}, state), {}, {
        preferMode: action.payload
      });
  }

  return state;
}

var Layout = function Layout(_ref) {
  var children = _ref.children,
      _ref$className = _ref.className,
      className = _ref$className === void 0 ? "" : _ref$className,
      props = _objectWithoutProperties(_ref, _excluded);

  var classes = getClasses();

  var _useReducer = useReducer(reducer, initialState),
      _useReducer2 = _slicedToArray(_useReducer, 2),
      state = _useReducer2[0],
      dispatch = _useReducer2[1];

  var _useState = useState(""),
      _useState2 = _slicedToArray(_useState, 2),
      sidebarContent = _useState2[0],
      setSidebarContent = _useState2[1]; // media queries


  var isDesktop = useMediaQuery("(min-width: ".concat(mediaBreakpointUpMd, ")"));
  var isExtraLarge = useMediaQuery("(min-width: ".concat(mediaBreakpointDownLg, ")"));
  useLayoutEffect(function () {
    if (isExtraLarge) {
      dispatch({
        type: SET_BREAKPOINT_DESKTOP_LARGE
      });
    } else if (isDesktop) {
      dispatch({
        type: SET_BREAKPOINT_DESKTOP
      });
    } else {
      dispatch({
        type: SET_BREAKPOINT_MOBILE
      });
    }
  }, [isDesktop, isExtraLarge]);
  var openNav = useCallback(function () {
    return dispatch({
      type: OPEN_NAV
    });
  }, [dispatch]);
  var closeNav = useCallback(function () {
    return dispatch({
      type: CLOSE_NAV
    });
  }, [dispatch]);
  var openSidebar = useCallback(function () {
    return dispatch({
      type: OPEN_SIDEBAR
    });
  }, [dispatch]);
  var closeSidebar = useCallback(function () {
    return dispatch({
      type: CLOSE_SIDEBAR
    });
  }, [dispatch]);
  var setMode = useCallback(function (payload) {
    return dispatch({
      type: SET_MODE,
      payload: payload
    });
  }, [dispatch]);
  var serPreferMode = useCallback(function (payload) {
    return dispatch({
      type: SET_PREFER_MODE,
      payload: payload
    });
  }, [dispatch]);
  var navCloseOnClickAway = useCallback(function (payload) {
    return dispatch({
      type: SET_CLICK_AWAY,
      payload: payload
    });
  }, [dispatch]);
  var contextValue = useMemo(function () {
    return {
      // sidebar
      sidebar: state.sidebar,
      openSidebar: openSidebar,
      closeSidebar: closeSidebar,
      sidebarContent: sidebarContent,
      setSidebarContent: setSidebarContent,
      // nav
      mode: state.mode,
      nav: state.nav,
      enableClickAway: state.enableClickAway,
      enableCollapse: state.enableCollapse,
      openNav: openNav,
      closeNav: closeNav,
      setMode: setMode,
      serPreferMode: serPreferMode,
      navCloseOnClickAway: navCloseOnClickAway
    };
  }, [closeNav, closeSidebar, navCloseOnClickAway, openNav, openSidebar, serPreferMode, setMode, sidebarContent, state.enableClickAway, state.enableCollapse, state.mode, state.nav, state.sidebar]);
  return /*#__PURE__*/React.createElement(SlotsProvider, null, /*#__PURE__*/React.createElement(LayoutContext.Provider, {
    value: contextValue
  }, /*#__PURE__*/React.createElement("div", _extends({
    className: cx(classes.root, className)
  }, props), children, state.sidebar && sidebarContent)));
};

export default Layout;