/**
 * @module @unitybase/adminui-vue
 */
/* global SystemJS, UB */
const throttleDebounce = require('throttle-debounce')
const formHelpers = require('../utils/Form/helpers')
const uDialogs = require('../utils/uDialogs')
const storeManager = require('./extUBPolyfills/storeManager')

const IS_SYSTEM_JS = typeof SystemJS !== 'undefined'

if (IS_SYSTEM_JS && !SystemJS.has('throttle-debounce')) SystemJS.set('throttle-debounce', SystemJS.newModule(throttleDebounce))

// add $dialog* to Vue prototype
UB.setErrorReporter(uDialogs.errorReporter)

module.exports = {
  storeManager,

  /**
   * Creates a new instance of UI module. See {@link module:Form.Form}
   */
  Form: require('../utils/Form/Form').Form,
  /**
   * Helper functions for forms. See {@link module:formHelpers}.
   * `mapInstanceFields` and `computedVuex` are aliased into `@unitybase/adminui-vue`
   * @type {module:formHelpers}
   */
  formHelpers,
  /**
   * See {@link module:formHelpers.mapInstanceFields}
   */
  mapInstanceFields: formHelpers.mapInstanceFields,
  /**
   * See {@link module:formHelpers.computedVuex}
   */
  computedVuex: formHelpers.computedVuex,
  SET: formHelpers.SET,

  /**
   * Escape special HTML characters in the given string of text.
   *
   * @param  {string} string The string to escape for inserting into HTML
   * @returns {string}
   * @function
   */
  // NOTE: (AndreyS) where we use this export? commented out because it's not used anywhere
  // escapeHtml: require('../utils/escapeHtml'),

  /**
   * Mount a Vue based component as a navbar tab, a modal form or inside other component (as a container).
   * See {@link module:mountUtils mountUtils} module documentation for samples.
   *
   * @type {module:mountUtils}
   */
  mountUtils: require('../utils/Form/mount'),

  /**
   * Open files using WebDav protocol (require @ub-e/web-daw to be added into application)
   *
   * @type {module:webDav}
   */
  webDav: require('../utils/webDav'),
  /**
   * MagicLinks instance. adminui-vue registers the following commands (using addCommand):
   *   - showList: runs an $App.doCommand({cmdType: 'showList', ...}
   *   - showForm: runs an $App.doCommand({cmdType: 'showForm', ...}
   *   - showReport: runs an $App.doCommand({cmdType: 'showReport', ...}
   *   - setFocus: sets a focus to specified HTML element
   *
   *   Usage of setFocus: `<a href="#" data-cmd-type="setFocus" data-elm-id="my-html-element-id">focus other</a>`
   *
   *   For usage examples for showList/Form/Repost see {@link module:magicLinks magicLinks} module documentation
   *
   * @type {module:magicLinks}
   */

  magicLink: require('../utils/magicLinks'),
  // ------------- throttle-debounce --------------------

  /**
   * throttle-debounce see <a href=https://github.com/niksy/throttle-debounce>original doc</a>
   * @type {{throttle: Function, debounce: Function}}
   */
  throttleDebounce,

  /**
   * Mixin for using in forms with own single-form validation. Mixin automatically creates
   * and passes a validator instance for use in nested controls (UFormRow for example).
   */
  validationMixin: require('../utils/Form/validation').validationMixin,

  /**
   * Mixin for `USelectEntity`/`USelectMultiple` like components to close options dropdown
   * on click outside
   */
  clickOutsideDropdownMixin: require('../components/controls/mixins/clickOutsideDropdown'),

  /**
   * Mixin for reusing common logic needed for registering custom `UTableEntity` filter templates components
   */
  filterTemplateMixin: require('../components/UTableEntity/filter-templates/mixinForFilter'),

  // ------------------ uDialogs -----------------
  /**
   * Modal uDialogs (message boxes) for showing errors, information and confirmation
   * For usage examples see {@link module:uDialogs uDialogs} module documentation
   *
   * @type {module:uDialogs}
   */
  uDialogs,
  /**
   * Show modal dialog with 3 optional button and text/html content, see {@link module:uDialogs.dialog uDialogs.dialog}
   * @type {uDialogs.dialog}
   */
  dialog: uDialogs.dialog,
  /**
   * Error dialog, see {@link module:uDialogs.dialogError uDialogs.dialogError}
   * @type {uDialogs.dialogError}
   */
  dialogError: uDialogs.dialogError,
  /**
   * Information dialog, see {@link module:uDialogs.dialogInfo uDialogs.dialogInfo}
   * @type {uDialogs.dialogInfo}
   */
  dialogInfo: uDialogs.dialogInfo,
  /**
   * Confirmation dialog, see {@link module:uDialogs.dialogYesNo uDialogs.dialogYesNo}
   * @type {uDialogs.dialogYesNo}
   */
  dialogYesNo: uDialogs.dialogYesNo,
  /**
   * Error reporter dialog, see {@link module:uDialogs.errorReporter uDialogs.errorReporter}
   * @type {uDialogs.errorReporter}
   */
  errorReporter: uDialogs.errorReporter,

  // ---------------- lookups --------------------
  /**
   * A reactive (in terms of Vue reactivity) entities data cache.
   * See examples in {@link module:lookups lookups} module documentation
   * @type {module:lookups}
   */
  lookups: require('../utils/lookups'),

  // ---------------- fileActions --------------------
  /**
   * Helper functions for creating files in a specific way: with dictaphone or webcam help
   *
   * @type {module:fileActions}
   */
  fileActions: require('../components/controls/UFile/helpers/file-actions'),

  // ----------- UI Settings Storage -----------
  /**
   * Storage for User Interface settings. Wrapper around `localStorage`
   * @example
   * // inside vue can be used as this.$uiSettings
   * this.videoRatio = this.$uiSettings.get('UFileWebcamButton', 'videoRatio') ?? this.videoRatios[0]
   * this.$uiSettings.put(this.videoRatios[0], 'UFileWebcamButton', 'videoRatio')
   *
   * // or from adminui-vue exports
   * const App = require('@unitybase/adminui-vue')
   * const isCollapsed = App.uiSettings.get('sidebar', 'isCollapsed')
   * @type {module:uiSettings}
   */
  uiSettings: require('../utils/uiSettingsStorage'),

  /**
   * Function for synchronizing between sidebar size and EXT body width
   * needed if need to override sidebar component
   */
  syncIsCollapsedWithExt: require('../utils/extUtils').syncIsCollapsedWithExt,

  // ---------------- Column Templates ------------------
  /**
   * The module provides column settings, cell templates,s and filter templates by
   * UB data types or by the `customSettings.columnTemplate` value. Different types
   * can have the same templates or settings.
   *
   * Entity attributes with `Text`, `BLOB`, `TimeLog` dataTypes do not have a default
   * render template. If you need to render attributes values with these data types,
   * register a custom column template for them or use column slots. You should decide
   * to display this column type with great caution because this column can create large
   * server requests
   *
   * @type {module:columnTemplates}
   */
  columnTemplates: require('../components/UTableEntity/column-template-provider'),

  /**
   * The module provides the ability to extend default CSS styles, fonts, .etc for
   * the rich text editor (tinymce)
   *
   * @type {module:richTextEditorConfigurator}
   */
  richTextEditorConfigurator: require('../components/controls/URichTextEditor/rich-text-editor-configurator'),

  // ---------------- Sanitize library ------------------

  /**
   * Basic sanitize config for the sanitize-html library
   * @type {object}
   */
  BASIC_SANITIZE_CONFIG: require('../directives/sanitize').BASIC_SANITIZE_CONFIG,

  /**
   * Sanitize-html library with pre-defined basic config if not passed as second argument
   * @function
   * @param {string} value HTML code to e sanitized
   * @param {object} [config] `sanitize-html` config. Default is BASIC_SANITIZE_CONFIG
   */
  sanitizeHtml: require('../directives/sanitize').sanitizeHtml
}