import classNames from "classnames";
import { connect } from "react-redux";
import { FormattedMessage, injectIntl } from "react-intl";
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
import PropTypes from "prop-types";
import React from "react";
import Box from "../box/box.jsx";
import bindAll from "lodash.bindall";

import styles from "./gui.css";
import tabStyles from "react-tabs/style/react-tabs.css";

import addExtensionIcon from "./icon--extensions.svg";
import codeIcon from "./icon--code.svg";
import costumesIcon from "./icon--costumes.svg";
import soundsIcon from "./icon--sounds.svg";
import filesIcon from "./icon--files.svg";

import Blocks from "../../containers/blocks.jsx";
import CostumeTab from "../../containers/costume-tab.jsx";
import SoundTab from "../../containers/sound-tab.jsx";
import FilesTab from "../../containers/files-tab.jsx";
import Watermark from "../../containers/watermark.jsx";

const safeJSONParse = (json, defaul, mustBeArray) => {
    try {
        const parsed = JSON.parse(json);
        if (mustBeArray && !Array.isArray(parsed)) throw "Not array";
        return parsed;
    } catch {
        return defaul;
    }
};

class OrganizedTabs extends React.Component {
    constructor(props) {
        super(props);
        // bindAll(this, [
        //     'handleMessageEvent',
        //     'wrapperEventHandler',
        //     'onUploadProject'
        // ]);
    }
    componentDidMount() {
        window.addEventListener("message", this.wrapperEventHandler);
    }
    componentWillUnmount() {
        window.removeEventListener("message", this.wrapperEventHandler);
    }
    shouldComponentUpdate(nextProps, nextState) {
        return this.props.stageSize !== nextProps.stageSize;
    }

    render() {
        const {
            activeTabIndex,
            onActivateTab,
            targetIsStage,
            canUseCloud,
            basePath,
            stageSize,
            vm,
            intl,
            messages,
            isDark,
            onActivateCostumesTab,
            onActivateSoundsTab,
            onExtensionButtonClick,
            blocksTabVisible,
            costumesTabVisible,
            soundsTabVisible,
        } = this.props;

        const tabClassNames = {
            tabs: styles.tabs,
            tab: classNames(tabStyles.reactTabsTab, styles.tab),
            tabList: classNames(tabStyles.reactTabsTabList, styles.tabList),
            tabPanel: classNames(tabStyles.reactTabsTabPanel, styles.tabPanel),
            tabPanelSelected: classNames(
                tabStyles.reactTabsTabPanelSelected,
                styles.isSelected
            ),
            tabSelected: classNames(
                tabStyles.reactTabsTabSelected,
                styles.isSelected
            ),
        };

        const organizedTabs = (() => {
            const tabOrderStr =
                localStorage.getItem("pm:taborder") ||
                '["code", "costume", "sound"]';
            const tabOrder = safeJSONParse(tabOrderStr, [], true);

            const codeTab = (
                <Tab className={tabClassNames.tab}>
                    <img draggable={false} src={codeIcon} />
                    <FormattedMessage
                        defaultMessage="Code"
                        description="Button to get to the code panel"
                        id="gui.gui.codeTab"
                    />
                </Tab>
            );
            const costumesTab = (
                <Tab
                    className={tabClassNames.tab}
                    onClick={onActivateCostumesTab}
                >
                    <img draggable={false} src={costumesIcon} />
                    {targetIsStage ? (
                        <FormattedMessage
                            defaultMessage="Backdrops"
                            description="Button to get to the backdrops panel"
                            id="gui.gui.backdropsTab"
                        />
                    ) : (
                        <FormattedMessage
                            defaultMessage="Costumes"
                            description="Button to get to the costumes panel"
                            id="gui.gui.costumesTab"
                        />
                    )}
                </Tab>
            );
            const soundsTab = (
                <Tab
                    className={tabClassNames.tab}
                    onClick={onActivateSoundsTab}
                >
                    <img draggable={false} src={soundsIcon} />
                    <FormattedMessage
                        defaultMessage="Sounds"
                        description="Button to get to the sounds panel"
                        id="gui.gui.soundsTab"
                    />
                </Tab>
            );

            const tabPairs = {
                code: codeTab,
                costume: costumesTab,
                sound: soundsTab,
            };

            const enabledTabs = [];
            for (const tabId of tabOrder) {
                enabledTabs.push(tabPairs[tabId] || codeTab);
            }

            return enabledTabs;
        })();

        return (
            <Tabs
                forceRenderTabPanel
                className={tabClassNames.tabs}
                selectedIndex={activeTabIndex}
                selectedTabClassName={tabClassNames.tabSelected}
                selectedTabPanelClassName={tabClassNames.tabPanelSelected}
                onSelect={onActivateTab}
            >
                <TabList className={tabClassNames.tabList}>
                    {organizedTabs}
                </TabList>
                <TabPanel className={tabClassNames.tabPanel}>
                    <Box className={styles.blocksWrapper}>
                        <Blocks
                            canUseCloud={canUseCloud}
                            grow={1}
                            isVisible={blocksTabVisible}
                            options={{
                                media: `${basePath}static/blocks-media/`,
                            }}
                            stageSize={stageSize}
                            vm={vm}
                        />
                    </Box>
                    <Box className={styles.extensionButtonContainer}>
                        <button
                            className={styles.extensionButton}
                            title={intl.formatMessage(messages.addExtension)}
                            onClick={onExtensionButtonClick}
                        >
                            <img
                                className={styles.extensionButtonIcon}
                                draggable={false}
                                src={addExtensionIcon}
                            />
                        </button>
                    </Box>
                    <Box className={styles.watermark}>
                        <Watermark />
                    </Box>
                </TabPanel>
                <TabPanel className={tabClassNames.tabPanel}>
                    {costumesTabVisible ? (
                        <CostumeTab vm={vm} isDark={isDark} />
                    ) : null}
                </TabPanel>
                <TabPanel className={tabClassNames.tabPanel}>
                    {soundsTabVisible ? <SoundTab vm={vm} /> : null}
                </TabPanel>
            </Tabs>
        );
    }
}

OrganizedTabs.propTypes = {
    activeTabIndex: PropTypes.any,
    onActivateTab: PropTypes.any,
    targetIsStage: PropTypes.any,
    canUseCloud: PropTypes.any,
    basePath: PropTypes.any,
    stageSize: PropTypes.any,
    vm: PropTypes.any,
    intl: PropTypes.any,
    messages: PropTypes.any,
    isDark: PropTypes.any,
    onActivateCostumesTab: PropTypes.any,
    onActivateSoundsTab: PropTypes.any,
    onExtensionButtonClick: PropTypes.any,
    blocksTabVisible: PropTypes.any,
    costumesTabVisible: PropTypes.any,
    soundsTabVisible: PropTypes.any,
};

export default injectIntl(OrganizedTabs);
