import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import get from 'lodash/get';
import { withStyles } from '@material-ui/core/styles';
import withWidth from '@material-ui/core/withWidth';
import { grey } from '@material-ui/core/colors';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import Typography from '@material-ui/core/Typography';
import Grid from '@material-ui/core/Grid';
import MenuItem from '@material-ui/core/MenuItem';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import Icon from '@material-ui/core/Icon';
import Tooltip from '@material-ui/core/Tooltip';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Switch from '@material-ui/core/Switch';
import { t, translationExists } from 'Framework/i18n';
import AnalyticsWrapper from 'App/Shared/Components/Analytics/AnalyticsWrapper';
import InformationTag from 'App/Shared/Components/InformationTag/InformationTag';
import customClassName from 'App/Utils/customClassName';
import { withPopupArea } from '../../Layouts/PopupAreaProvider';
import ColorPalettes from '../../Containers/ColorPalettes';
import Select from '../Select';
import ObjectTools from '../ObjectTools';
import { TextFormatIcon } from './TextFormatIcon';

const styles = theme => ({
    card: {
        borderTop: '7px solid ' + theme.palette.primary.main,
        position: 'relative',
        overflow: 'visible',
    },
    cardUnboxed: {
        borderTop: 'none',
        boxShadow: 'none',
        borderRadius: 0,
    },
    CardContentWrapper: {
        padding: 8,
        [theme.breakpoints.down('xs')]: {
            '&:last-child': {
                paddingBottom: 8,
            },
        },
    },
    listItemText: {
        textAlign: 'left',
    },
    fontFamilyList: {
        height: 40,
        [theme.breakpoints.down('xs')]: {
            height: 56,
        },
    },
    listFontItemText: {
        fontSize: '12px',
        color: theme.palette.text.secondary,
        textAlign: 'center',
        lineHeight: 2.1,
        cursor: 'default',
    },
    GridItemXS: {
        padding: '0 2px',
        [theme.breakpoints.down('xs')]: {
            display: 'flex',
        },
    },
    disabledIncrementButton: {
        opacity: 0.2,
    },
    disabledDecrementButton: {
        opacity: 0.2,
    },
    activeIncrementButton: {
        opacity: 1,
        cursor: 'pointer',
        color: theme.palette.text.secondary,
    },
    activeDecrementButton: {
        opacity: 1,
        cursor: 'pointer',
        color: theme.palette.text.secondary,
    },
    textToolButton: {
        width: 40,
        height: 40,
        minWidth: 30,
        minHeight: 30,
        margin: '16px 8px 0 0',
        [theme.breakpoints.down('xs')]: {
            width: 42,
            height: 42,
            marginRight: 8,
            marginTop: 8,
        },
    },
    textToolButtonPressed: {
        background: '#ddd',
    },
    textToolButtonAlignment: {
        margin: '16px 8px 0 0',
        [theme.breakpoints.down('xs')]: {
            margin: 0,
            marginRight: 8,
        },
    },
    textControlboxIconsGrid: {
        display: 'inline-flex',
        '@media only screen and (min-device-width: 568px) and (max-device-width : 725px) and  (orientation: portrait)': {
            '& div': {
                flexWrap: 'wrap',
            },
        },
        [theme.breakpoints.between('xs', 'sm')]: {
            '& div': {
                display: 'flex',
            },
        },
        [theme.breakpoints.down('xs')]: {
            '& button:last-child': {
                marginRight: 0,
            },
            justifyContent: 'space-around',
            '& .object-btn': {
                marginRight: 8,
                width: 42,
                height: 42,
            },
        },
    },
    WrapperAlignment: {
        textAlign: 'end',
        [theme.breakpoints.between('xs', 'sm')]: {
            textAlign: 'start',
        },
        [theme.breakpoints.down('xs')]: {
            textAlign: 'end',
        },
    },
    textToolButtonAlign: {
        margin: '15px 0',
        '&.Mui-disabled': {
            opacity: 0.5,
        },
        [theme.breakpoints.down('xs')]: {
            marginTop: 8,
        },
    },
    inputTextfield: {
        padding: '11.5px 14px',
    },
    colorSwitchBase: {
        color: grey[100],
        '&$colorChecked': {
            color: '#ED1C29',
            '& + $colorBar': {
                backgroundColor: '#FA9798',
            },
        },
    },
    colorBar: {},
    colorChecked: {},
    textEditor: {
        marginBottom: 16,
        '& > div': {
            height: '56px',
        },
    },
    switchRoot: {
        margin: '0 5px 0 15px',
    },
    switchLabel: {
        '& > span': {
            fontSize: 15,
        },
    },
    cardContentRoot: {
        [theme.breakpoints.down('xs')]: {
            padding: 0,
            '&:last-child': {
                paddingBottom: 24,
            },
        },
        padding: 8,
    },
    icon: {
        height: 16,
        padding: 4,
    },
});

class ContainerField extends React.Component {
    static propTypes = {
        children: PropTypes.object,
        editorBackgroundColor: PropTypes.string,
    };

    render() {
        const { children, editorBackgroundColor, ...otherProps } = this.props;
        return (
            <TextField
                InputProps={{
                    startAdornment: children,
                    inputComponent: () => null,
                    style: { background: editorBackgroundColor },
                }}
                {...otherProps}
            />
        );
    }
}

class TextControlbox extends React.Component {
    static propTypes = {
        classes: PropTypes.object,
        boxed: PropTypes.bool,
        textValue: PropTypes.string,
        handleChangeText: PropTypes.func,
        fontValue: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
        width: PropTypes.string,
        fonts: PropTypes.array,
        handleChangeFont: PropTypes.func,
        handleButtonMouseDown: PropTypes.func,
        handleButtonClick: PropTypes.func,
        handleObjectButtonClick: PropTypes.func,
        onChangeFontSize: PropTypes.func,
        fontSizeValue: PropTypes.number,
        minSize: PropTypes.number,
        maxSize: PropTypes.number,
        renderEditorComponent: PropTypes.func,
        toggleIsBulkName: PropTypes.func,
        isBulkName: PropTypes.bool,
        popupArea: PropTypes.object.isRequired,
        colorDisabled: PropTypes.bool,
        isBold: PropTypes.bool,
        boldDisabled: PropTypes.bool,
        isItalic: PropTypes.bool,
        italicDisabled: PropTypes.bool,
        textAlign: PropTypes.string,
        flipToFrontDisabled: PropTypes.bool,
        flipToBackDisabled: PropTypes.bool,
        isActiveBulkName: PropTypes.bool,
        selectedDesignProductionMethod: PropTypes.object,
        editorBackgroundColor: PropTypes.string,
        color: PropTypes.object,
        selectedObject: PropTypes.object,
        isPortraitMode: PropTypes.bool,
        components: PropTypes.shape({
            FontFamilySelect: PropTypes.elementType.isRequired,
        }).isRequired,
        alignVerticalCenterIcon: PropTypes.element,
        alignHorizontalCenterIcon: PropTypes.element,
        moveDownIcon: PropTypes.element,
        moveUpIcon: PropTypes.element,
        formatAlignLeftIcon: PropTypes.element,
        formatAlignCenterIcon: PropTypes.element,
        formatAlignRightIcon: PropTypes.element,
        formatAlignJustifyIcon: PropTypes.element,
        formatBoldIcon: PropTypes.element,
        formatItalicIcon: PropTypes.element,
    };

    static defaultProps = {
        components: {
            FontFamilySelect: Select,
        },
    };

    componentWillUnmount() {
        this.props.popupArea.dismiss();
    }

    onCloseColorPalettes = () => {
        this.props.popupArea.dismiss();
    };

    render() {
        const {
            classes,
            width,
            boxed,
            textValue,
            handleChangeText,
            fontValue,
            fonts,
            handleChangeFont,
            renderEditorComponent,
            handleButtonMouseDown,
            handleButtonClick,
            handleObjectButtonClick,
            popupArea,
            isBold,
            boldDisabled,
            isItalic,
            italicDisabled,
            textAlign,
            flipToFrontDisabled,
            flipToBackDisabled,
            colorDisabled,
            isActiveBulkName,
            isBulkName,
            toggleIsBulkName,
            editorBackgroundColor,
            color,
            selectedObject,
            components: { FontFamilySelect },
            isPortraitMode,
            alignVerticalCenterIcon,
            alignHorizontalCenterIcon,
            moveDownIcon,
            moveUpIcon,
            formatAlignLeftIcon,
            formatAlignCenterIcon,
            formatAlignRightIcon,
            formatAlignJustifyIcon,
            formatBoldIcon,
            formatItalicIcon,
        } = this.props;
        const textAlignFullEnabled = false;

        const renderEditor = () => {
            return renderEditorComponent ? (
                <ContainerField
                    className={classes.textEditor}
                    label={isBulkName ? '' : t('textControlbox.text')}
                    margin="normal"
                    fullWidth
                    variant="outlined"
                    translate="no"
                    multiline
                    editorBackgroundColor={editorBackgroundColor}
                >
                    {renderEditorComponent(this.props)}
                </ContainerField>
            ) : (
                <TextField
                    className={classes.textEditor}
                    label={isBulkName ? '' : t('textControlbox.text')}
                    value={textValue}
                    onChange={handleChangeText}
                    margin="normal"
                    fullWidth
                    variant="outlined"
                    translate="no"
                    multiline
                    rowsMax={2}
                    InputLabelProps={{ shrink: true }}
                />
            );
        };
        const renderBulkName = () => {
            return (
                <React.Fragment>
                    <Grid item xs={10}>
                        <FormControlLabel
                            className={classes.switchLabel}
                            control={
                                <Switch
                                    classes={{
                                        root: classes.switchRoot,
                                        switchBase: classes.colorSwitchBase,
                                        checked: classes.colorChecked,
                                        track: classes.colorBar,
                                    }}
                                    onChange={toggleIsBulkName}
                                    onClick={toggleIsBulkName}
                                    checked={isBulkName}
                                />
                            }
                            label={t('textControlbox.bulknames')}
                        />
                    </Grid>
                    <Grid item xs={2}>
                        {translationExists('bulkNameInformation') && (
                            <div className="info-btn">
                                <InformationTag infoText={t('bulkNameInformation')} />
                            </div>
                        )}
                    </Grid>
                </React.Fragment>
            );
        };
        const renderFontFamily = () => {
            return (
                <AnalyticsWrapper targetId="text_font">
                    <FontFamilySelect
                        bold
                        value={fontValue || ''}
                        autoWidth={width === 'xs'}
                        onChange={handleChangeFont}
                    >
                        {fonts.map(font => (
                            <MenuItem
                                key={font.isCustomFont ? font.customName : font.name}
                                className={classes.fontFamilyList}
                                value={font}
                                aria-label={font.name}
                            >
                                <Typography
                                    className={classes.listItemText}
                                    noWrap
                                    style={{ fontFamily: font.value }}
                                >
                                    {font.isCustomFont
                                        ? `${font.customName} (${t('textControlbox.customFont')})`
                                        : font.name}
                                </Typography>
                            </MenuItem>
                        ))}
                    </FontFamilySelect>
                </AnalyticsWrapper>
            );
        };
        const renderTextBoldItalics = () => {
            return (
                <React.Fragment>
                    <AnalyticsWrapper targetId="text_bold">
                        <Button
                            className={
                                classes.textToolButton + (isBold ? ' ' + classes.textToolButtonPressed : '')
                            }
                            variant="outlined"
                            value="bold"
                            onMouseDown={handleButtonMouseDown}
                            onClick={handleButtonClick}
                            disabled={boldDisabled}
                        >
                            <Tooltip title={t('textControlbox.tooltips.bold')}>
                                {formatBoldIcon ?? <Icon>format_bold</Icon>}
                            </Tooltip>
                        </Button>
                    </AnalyticsWrapper>
                    <AnalyticsWrapper targetId="text_italic">
                        <Button
                            className={
                                classes.textToolButton + (isItalic ? ' ' + classes.textToolButtonPressed : '')
                            }
                            variant="outlined"
                            value="italic"
                            onMouseDown={handleButtonMouseDown}
                            onClick={handleButtonClick}
                            disabled={italicDisabled}
                        >
                            <Tooltip title={t('textControlbox.tooltips.italic')}>
                                {formatItalicIcon ?? <Icon>format_italic</Icon>}
                            </Tooltip>
                        </Button>
                    </AnalyticsWrapper>
                </React.Fragment>
            );
        };
        const renderTextAlignments = () => {
            return (
                <React.Fragment>
                    <AnalyticsWrapper targetId="text_align_left">
                        <Button
                            className={
                                classes.textToolButton +
                                ' ' +
                                classes.textToolButtonAlignment +
                                (textAlign === 'left' || textAlign === 'start'
                                    ? ' ' + classes.textToolButtonPressed
                                    : '')
                            }
                            variant="outlined"
                            value="justifyLeft"
                            onMouseDown={handleButtonMouseDown}
                            onClick={handleButtonClick}
                        >
                            <Tooltip title={t('textControlbox.tooltips.alignLeft')}>
                                {formatAlignLeftIcon ?? <Icon>format_align_left</Icon>}
                            </Tooltip>
                        </Button>
                    </AnalyticsWrapper>
                    <AnalyticsWrapper targetId="text_align_center">
                        <Button
                            className={
                                classes.textToolButton +
                                ' ' +
                                classes.textToolButtonAlignment +
                                (textAlign === 'center' ? ' ' + classes.textToolButtonPressed : '')
                            }
                            variant="outlined"
                            value="justifyCenter"
                            onMouseDown={handleButtonMouseDown}
                            onClick={handleButtonClick}
                        >
                            <Tooltip title={t('textControlbox.tooltips.alignCenter')}>
                                {formatAlignCenterIcon ?? <Icon>format_align_center</Icon>}
                            </Tooltip>
                        </Button>
                    </AnalyticsWrapper>
                    <AnalyticsWrapper targetId="text_align_right">
                        <Button
                            className={
                                classes.textToolButton +
                                ' ' +
                                classes.textToolButtonAlignment +
                                (textAlign === 'right' ? ' ' + classes.textToolButtonPressed : '')
                            }
                            variant="outlined"
                            value="justifyRight"
                            onMouseDown={handleButtonMouseDown}
                            onClick={handleButtonClick}
                        >
                            <Tooltip title={t('textControlbox.tooltips.alignRight')}>
                                {formatAlignRightIcon ?? <Icon>format_align_right</Icon>}
                            </Tooltip>
                        </Button>
                    </AnalyticsWrapper>
                    {textAlignFullEnabled && (
                        <AnalyticsWrapper targetId="text_align_justify">
                            <Button
                                className={
                                    classes.textToolButton +
                                    ' ' +
                                    classes.textToolButtonAlignment +
                                    (textAlign === 'full' ? ' ' + classes.textToolButtonPressed : '')
                                }
                                variant="outlined"
                                value="justifyFull"
                                onMouseDown={handleButtonMouseDown}
                                onClick={handleButtonClick}
                            >
                                {formatAlignJustifyIcon ?? <Icon>format_align_justify</Icon>}
                            </Button>
                        </AnalyticsWrapper>
                    )}
                </React.Fragment>
            );
        };
        const renderTextColor = () => {
            return (
                <Button
                    className={classes.textToolButtonAlign + ' ' + classes.textToolButton}
                    variant="outlined"
                    value="color"
                    onClick={() =>
                        popupArea.setContent(
                            <ColorPalettes
                                isPortraitMode={isPortraitMode}
                                selectedObject={selectedObject}
                                closeColorPalettes={this.onCloseColorPalettes}
                            />,
                            { hideChildren: !(width !== 'xs' && isPortraitMode) }
                        )
                    }
                    disabled={colorDisabled}
                >
                    <Tooltip title={t('textControlbox.tooltips.color')}>
                        <TextFormatIcon
                            className={classes.icon}
                            selectedColor={get(color, 'value') || grey[900]}
                        />
                    </Tooltip>
                </Button>
            );
        };
        const renderObjectTools = () => {
            return (
                <ObjectTools
                    handleObjectButtonClick={handleObjectButtonClick}
                    flipToFrontDisabled={flipToFrontDisabled}
                    flipToBackDisabled={flipToBackDisabled}
                    alignVerticalCenterIcon={alignVerticalCenterIcon}
                    alignHorizontalCenterIcon={alignHorizontalCenterIcon}
                    moveDownIcon={moveDownIcon}
                    moveUpIcon={moveUpIcon}
                />
            );
        };

        return width === 'xs' ? (
            <Card
                id="containerTextControl"
                className={clsx(
                    boxed ? classes.card : classes.cardUnboxed,
                    customClassName('text-tools-box')
                )}
            >
                <CardContent classes={{ root: classes.cardContentRoot }}>
                    <Grid container>
                        <Grid item xs={12} className={classes.GridItemXS}>
                            {renderEditor()}
                        </Grid>
                        {isActiveBulkName && renderBulkName()}
                        <Grid item xs={6} className={classes.GridItemXS}>
                            {renderFontFamily()}
                        </Grid>
                        <Grid item xs={6} justify="flex-end" className={classes.GridItemXS}>
                            {renderTextBoldItalics()}
                            {renderTextColor()}
                        </Grid>
                        <Grid item xs={12} alignItems="flex-end" className={classes.textControlboxIconsGrid}>
                            {renderObjectTools()}
                            {renderTextAlignments()}
                        </Grid>
                    </Grid>
                </CardContent>
            </Card>
        ) : (
            <Card
                id="containerTextControl"
                className={clsx(
                    boxed ? classes.card : classes.cardUnboxed,
                    customClassName('text-tools-box')
                )}
            >
                <CardContent className={boxed ? '' : classes.CardContentWrapper}>
                    <Grid container>
                        <Grid item xs={12} md={12} lg={12} className={classes.GridItemXS}>
                            {renderEditor()}
                        </Grid>
                        {isActiveBulkName && renderBulkName()}
                        <Grid item xs={12} sm={12} md={12} lg={12} className={classes.GridItemXS}>
                            {renderFontFamily()}
                        </Grid>
                        <Grid item xs={12} md={12} lg={12} className={classes.textControlboxIconsGrid}>
                            <Grid item xs={4} md={4}>
                                {renderTextBoldItalics()}
                            </Grid>
                            <Grid item xs={6} md={6}>
                                {renderTextAlignments()}
                            </Grid>
                            <Grid item xs={2} md={2} className={classes.WrapperAlignment}>
                                {renderTextColor()}
                            </Grid>
                        </Grid>
                        {renderObjectTools()}
                    </Grid>
                </CardContent>
            </Card>
        );
    }
}

export default withWidth()(withStyles(styles, { name: 'TextControlbox' })(withPopupArea(TextControlbox)));
