// TODO remove libs reexport

// React stuff
import React from 'react';
import PropTypes from 'prop-types';
import ReactUpdate from 'immutability-helper';
import ReactDOM from 'react-dom';
import * as ReactRouter from 'react-router';
import * as ReactRouterBootstrap from 'react-router-bootstrap';

import History from 'history';
import md5 from 'md5';

import * as Redux from 'redux';
import * as ReactRedux from 'react-redux';

export {
    React,
    PropTypes,
    ReactUpdate,
    ReactDOM,
    ReactRouter,
    ReactRouterBootstrap,
    History,
    md5,
    Redux,
    ReactRedux
};

import {Popup} from './ui/popups/Popup';
import {Notification} from './ui/Notification';
import {Filter} from './ui/Filter';
import {Menu} from './ui/Menu';
import {MenuItem} from './ui/MenuItem';
import {TabPanel} from './ui/TabPanel';
import {TabPanelOverflowContainer} from './ui/TabPanelOverflowContainer';
import {TabItem} from './ui/TabItem';
import {Button} from './ui/Button';
import {Spinner} from './ui/Spinner/Spinner';
import {Loader} from './ui/Loader';
import {GlobalLoader} from './ui/GlobalLoader';
import {SplitButton} from './ui/SplitButton';
import {CTAContainer} from './ui/CTAContainer';
import {CTAControl} from './ui/CTAControl';
import {Form} from './ui/form/Form';
import {TextInput} from './ui/form/TextInput';
import {TextArea} from './ui/form/TextArea';
import {PureCheckbox} from './ui/form/PureCheckbox';
import {Checkbox} from './ui/form/Checkbox';
import {CheckboxGroup} from './ui/form/CheckboxGroup';
import {Radio} from './ui/form/Radio';
import {Select} from './ui/form/Select';
import {FormGroup} from './ui/form/FormGroup'; //FIXME Remove legacy declaration
import {FormControl} from './ui/form/FormControl'; //FIXME Remove legacy declaration
import {FormErrorAutoFocusContainer} from './ui/form/FormErrorAutoFocusContainer'; //FIXME Remove legacy declaration
import {TextInputControl} from './ui/form/TextInputControl';
import {TextAreaControl} from './ui/form/TextAreaControl';
import {CheckboxControl} from './ui/form/CheckboxControl';
import {RadioControl} from './ui/form/RadioControl';
import {SelectControl} from './ui/form/SelectControl';
import {MultiSelect} from './ui/form/MultiSelect';
import {TreeFilterControl} from './ui/form/TreeFilterControl';
import {InputCounter} from './ui/form/InputCounter';
import {Autosuggest} from './ui/form/Autosuggest';
import {AutosuggestControl} from './ui/form/AutosuggestControl';
import {Translate} from './ui/Translate';
import {DangerousHTML} from './ui/DangerousHTML';
import {ListControlCheckbox} from './ui/list/withStore/ListControlCheckbox';
import {ListHighlight} from './ui/list/withStore/ListHighlight';
import {ListSorter} from './ui/list/withStore/ListSorter';
import {ListRow} from './ui/list/ListRow';
import {GridSorter} from './ui/list/withStore/GridSorter';
import {GridHeaderCell} from './ui/list/withStore/GridHeaderCell';
import {GridCell} from './ui/list/withStore/GridCell';
import {GridRowActions} from './ui/GridRowActions';
import {CollapsibleList} from './ui/CollapsibleList';
import {CollapsibleToolbar} from './ui/CollapsibleToolbar';
import {Icon} from './ui/Icon';
import {HeaderIcon} from './ui/HeaderIcon';
import {Panel} from './ui/Panel';
import {Block} from './ui/Block';
import {Dropdown} from './ui/Dropdown';
import {DropdownButton} from './ui/DropdownButton';
import {Row} from './ui/Row';
import {Col} from './ui/Col';
import {Message} from './ui/Message';
import {Wizard} from './ui/Wizard';
import {Tooltip} from './ui/Tooltip';
import {BorderedList, BorderedListItem} from './ui/BorderedList';
import {BrandedImage} from './ui/BrandedImage';
import {MoreButton} from './ui/MoreButton';
import {Pagination} from './ui/list/withStore/Pagination';
import {HeaderToolbar} from './ui/HeaderToolbar';
import {Highlighter} from './ui/Highlighter';
import {Note} from './ui/Note';
import {StoreCounterText} from './ui/list/withStore/StoreCounterText';
import {SelectedRecordsSwitcher} from './ui/SelectedRecordsSwitcher';
import {List} from './ui/list/withStore/List';
import {ListLayout} from './ui/list/withStore/ListLayout';
import {WizardStep} from './ui/WizardStep';
import {Alert} from './ui/popups/Alert';
import {Confirm} from './ui/popups/Confirm';
import {DismissibleAlert} from './ui/DismissibleAlert';
import {TiledGrid} from './ui/TiledGrid';
import {Banner} from './ui/Banner';
import {AudioPlayer} from './ui/media/AudioPlayer';
import {AudioRecorder} from './ui/media/AudioRecorder';
import {Static} from './ui/form/Static';
import {Toggle} from './ui/form/Toggle';
import {ToggleControl} from './ui/form/ToggleControl';
import {FileUploadControl} from './ui/form/FileUploadControl';
import {FileUpload} from './ui/form/FileUpload';
import {PrintArea} from './ui/PrintArea';
import {NoPrint} from './ui/NoPrint';
import {ColumnTreeView} from './ui/ColumnTreeView';
import {BreadCrumbs} from './ui/BreadCrumbs';
import {Dropzone} from './ui/Dropzone';
import {KeyDownable} from './ui/KeyDownable';
import {NavDropdown} from './ui/NavDropdown';
import {FlexBlock, FlexBlockItem} from './ui/flexBlock';
import {TestAutomationPanel} from './ui/TestAutomationPanel/TestAutomationPanel';
import {TreeList} from './ui/list/TreeList';
import {SingleDatePickerInputControl as DatePickerControl} from './ui/form/DateTimePicker/SingleDatePickerInputControl';
import {SingleDatePicker as DatePicker} from './ui/form/DateTimePicker/SingleDatePicker';
import {DayRangePickerControl as DateRangePickerControl} from './ui/form/DateTimePicker/DayRangePickerControl';
import {DayRangePicker as DateRangePicker} from './ui/form/DateTimePicker/DayRangePicker';
import {Accordion, AccordionItem} from './ui/accordion';
import {DateRangePickerWithPresets} from './ui/form/DateRangePickerWithPresets';
import {
    CatalogItemIcon,
    CatalogListItem,
    CatalogGridItem,
    CatalogListDetails,
    CatalogGridDetails,
    CatalogSearchResultItem,
    CatalogSimplePrice
} from './ui/catalog';
import {Search} from './ui/Search';

import {PureList} from './ui/list/PureList';
import {PurePagination} from './ui/list/PurePagination';
import {CounterText} from './ui/list/CounterText';
import {ListManager, passedListManagerPropsTypes} from './ui/list/ListManager';
import {PureListSorter} from './ui/list/PureListSorter';
import {PureListHighlight} from './ui/list/PureListHighlight';
import {PureListLayout} from './ui/list/PureListLayout';
import {PurePaginationWithCounter} from './ui/list/PurePaginationWithCounter';
import {Switcher} from './ui/switcher/Switcher';
import {SwitcherItem} from './ui/switcher/SwitcherItem';
import {withSelectedIds, passedWithSelectedIdsPropsTypes} from './ui/HOCs/withSelectedIds';
import {ExternalLink} from './ui/ExternalLink';
import {ToolsMenu, ToolsDropdown} from './ui/ToolsMenu';

// Utils
import formatMessage from 'format-message';
import validator from 'validator';
import _ from 'lodash';
import moment from 'moment';

export {formatMessage, validator, _, moment};

import classnames from 'classnames';
import TinyEmitter from 'tiny-emitter';

export {classnames, TinyEmitter};

// React Bootstrap Non-Wrapped
import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar';
import ButtonGroup from 'react-bootstrap/lib/ButtonGroup';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import Overlay from 'react-bootstrap/lib/Overlay';
import Popover from 'react-bootstrap/lib/Popover';
import Navbar from 'react-bootstrap/lib/Navbar';
import NavItem from 'react-bootstrap/lib/NavItem';
import Nav from 'react-bootstrap/lib/Nav';
import Table from 'react-bootstrap/lib/Table';
import Collapse from 'react-bootstrap/lib/Collapse';
import StaticControl from 'react-bootstrap/lib/FormControlStatic';
import BootstrapAlert from 'react-bootstrap/lib/Alert';
import ControlLabel from 'react-bootstrap/lib/ControlLabel';
import HelpBlock from 'react-bootstrap/lib/HelpBlock';
import InputGroup from 'react-bootstrap/lib/InputGroup';
import InputGroupAddon from 'react-bootstrap/lib/InputGroupAddon';
import InputGroupButton from 'react-bootstrap/lib/InputGroupButton';
import Media from 'react-bootstrap/lib/Media';
import ProgressBar from 'react-bootstrap/lib/ProgressBar';
import FormControlFeedback from 'react-bootstrap/lib/FormControlFeedback';

export {
    ButtonToolbar,
    ButtonGroup,
    OverlayTrigger,
    Overlay,
    Popover,
    Navbar,
    NavItem,
    Nav,
    Table,
    Collapse,
    StaticControl,
    BootstrapAlert,
    ControlLabel,
    HelpBlock,
    InputGroup,
    InputGroupAddon,
    InputGroupButton,
    Media,
    ProgressBar,
    FormControlFeedback
};

// Data
import Transport from './data/Transport';
import {Store} from './data/Store';
import {ColumnsStore} from './data/ColumnsStore';
import * as TreeItemHelpers from './data/TreeItemMap';
import {TreeStore} from './data/TreeStore';

export {Transport, Store, ColumnsStore, TreeItemHelpers, TreeStore};

// Utils
import EventBus from './utils/EventBus';
import BrandedFileLoader from './utils/BrandedFileLoader';

export {EventBus, BrandedFileLoader};

export {
    getSilentRouterHistory,
    setDocumentTitle,
    isReactComponent,
    isReactElement,
    mountComponent,
    isSafeStringValue,
    OS,
    fillBrandName,
    extendFormState,
    cleanFormState,
    wait,
    filterKeyCodes
} from './utils/functions';

export {scrollToNode} from './ui/utils';

export {FocusHelper} from './utils/FocusHelper';

import {validate, stripErrors} from './utils/ValidationUtils';
export const ValidationUtils = {
    validate,
    stripErrors
};

export {
    showPopup,
    showAlert,
    showConfirmation,
    showNotification,
    scrollToTop,
    playMessage
} from './ui/functions';

export {
    Popup,
    Filter,
    Menu,
    MenuItem,
    TabPanel,
    TabPanelOverflowContainer,
    TabItem,
    Button,
    Spinner,
    Loader,
    GlobalLoader,
    SplitButton,
    Form,
    TextInput,
    TextArea,
    PureCheckbox,
    Checkbox,
    CheckboxGroup,
    DateRangePicker,
    DateRangePickerWithPresets,
    DatePicker,
    Toggle,
    Radio,
    Select,
    FormGroup,
    FormGroup as Input,
    FormControl,
    FormControl as FormInput,
    FormErrorAutoFocusContainer,
    TextInputControl,
    TextAreaControl,
    CheckboxControl,
    DateRangePickerControl,
    DatePickerControl,
    RadioControl,
    SelectControl,
    FileUploadControl,
    FileUpload,
    ToggleControl,
    MultiSelect,
    InputCounter,
    Autosuggest,
    AutosuggestControl,
    Translate,
    DangerousHTML,
    ListControlCheckbox,
    ListHighlight,
    ListSorter,
    ListRow,
    GridSorter,
    GridCell,
    GridHeaderCell,
    GridRowActions,
    CollapsibleList,
    CollapsibleToolbar,
    Icon,
    HeaderIcon,
    Panel,
    Block,
    Dropdown,
    DropdownButton,
    Row,
    Col,
    Message,
    Wizard,
    Tooltip,
    BorderedList,
    BorderedListItem,
    BrandedImage,
    MoreButton,
    Pagination,
    HeaderToolbar,
    Highlighter,
    Note,
    StoreCounterText,
    SelectedRecordsSwitcher,
    List,
    ListLayout,
    CTAContainer,
    CTAControl,
    WizardStep,
    Alert,
    Confirm,
    DismissibleAlert,
    TiledGrid,
    Banner,
    AudioPlayer,
    AudioRecorder,
    Static,
    PrintArea,
    NoPrint,
    Notification,
    ColumnTreeView,
    BreadCrumbs,
    Dropzone,
    KeyDownable,
    NavDropdown,
    FlexBlock,
    FlexBlockItem,
    TestAutomationPanel,
    TreeList,
    TreeFilterControl,
    PureList,
    CounterText,
    ListManager,
    passedListManagerPropsTypes,
    PurePagination,
    PureListSorter,
    PureListHighlight,
    PureListLayout,
    withSelectedIds,
    passedWithSelectedIdsPropsTypes,
    Accordion,
    AccordionItem,
    CatalogItemIcon,
    CatalogListItem,
    CatalogGridItem,
    PurePaginationWithCounter,
    CatalogListDetails,
    CatalogGridDetails,
    CatalogSearchResultItem,
    CatalogSimplePrice,
    Switcher,
    SwitcherItem,
    Search,
    ExternalLink,
    ToolsMenu,
    ToolsDropdown
};

let showLoader = function() {};
let hideLoader = function() {};

export function loadPackage(modules, callback, errback?) {
    if (!Array.isArray(modules)) {
        modules = [modules];
    }

    showLoader();

    // guard against Webpack context parser
    //TODO Try ro require('requirejs')
    window['require'](
        modules.map(function(p) {
            return p.indexOf('app/') !== -1 && p.indexOf('/index') !== -1
                ? p
                : 'app/' + p + '/index'; //TODO Make app prefix configurable
        }),
        function() {
            hideLoader();
            callback.apply(null, arguments);
        },
        function() {
            hideLoader();

            if (errback) {
                errback.apply(null, arguments);
            } else {
                // eslint-disable-next-line
                if (arguments[0] && arguments[0].stack) console.error(arguments[0].stack);
                // eslint-disable-next-line
                console.error(arguments);
            }
        }
    );
}

export function bootstrap(options) {
    showLoader = options.showLoader || showLoader;
    hideLoader = options.hideLoader || hideLoader;

    // @ts-ignore
    setup(options.config, options.locale);

    loadPackage(['app/lang/common/index-en_US'], function(langCommon) {
        let skin = options.skin || options.config.brandId;

        loadPackage(['app/core/all/index-' + skin], options.done, function() {
            // eslint-disable-next-line
            console.warn('Skin for', skin, 'cannot be loaded, fallback to default');

            loadPackage(['app/core/all/index-default'], options.done);
        });
    });
}
