/*
    Парус 8 - Панели мониторинга
    Компонент: Сообщение
*/

//---------------------
//Подключение библиотек
//---------------------

import React, { useState } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import Dialog from "@mui/material/Dialog"; //базовый класс диалога Material UI
import DialogTitle from "@mui/material/DialogTitle"; //Заголовок диалога
import DialogContent from "@mui/material/DialogContent"; //Содержимое диалога
import DialogContentText from "@mui/material/DialogContentText"; //Текст содержимого диалога
import DialogActions from "@mui/material/DialogActions"; //Область действий диалога
import Typography from "@mui/material/Typography"; //Текст
import Button from "@mui/material/Button"; //Кнопки
import Container from "@mui/material/Container"; //Контейнер
import Box from "@mui/material/Box"; //Обёртка
import { BUTTONS, STATE } from "../../app.text"; //Типовые текстовые ресурсы и константы
import { APP_COLORS } from "../../app.styles"; //Типовые стили

//---------
//Константы
//---------

//Варианты исполнения
const P8P_APP_MESSAGE_VARIANT = {
    INFO: STATE.INFO,
    WARN: STATE.WARN,
    ERR: STATE.ERR
};

//Стили
const STYLES = {
    DEFAULT: {
        wordBreak: "break-word"
    },
    INFO: {
        titleText: {
            color: APP_COLORS[STATE.INFO].contrColor
        },
        bodyText: {
            color: APP_COLORS[STATE.INFO].contrColor
        }
    },
    WARN: {
        titleText: {
            color: APP_COLORS[STATE.WARN].contrColor
        },
        bodyText: {
            color: APP_COLORS[STATE.WARN].contrColor
        }
    },
    ERR: {
        titleText: {
            color: APP_COLORS[STATE.ERR].contrColor
        },
        bodyText: {
            color: APP_COLORS[STATE.ERR].contrColor
        }
    },
    INLINE_MESSAGE: {
        with: "100%",
        textAlign: "center"
    },
    FULL_ERROR_TEXT_BUTTON: {
        color: APP_COLORS[STATE.WARN].contrColor
    }
};

//-----------
//Тело модуля
//-----------

//Сообщение
const P8PAppMessage = ({
    variant,
    title,
    titleText,
    cancelBtn,
    onCancel,
    cancelBtnCaption,
    okBtn,
    onOk,
    okBtnCaption,
    open,
    text,
    fullErrorText,
    showErrMoreCaption,
    hideErrMoreCaption
}) => {
    //Состояние подробной информации об ошибке
    const [showFullErrorText, setShowFullErrorText] = useState(false);

    //Подбор стиля и ресурсов
    let style = STYLES.INFO;
    switch (variant) {
        case P8P_APP_MESSAGE_VARIANT.INFO: {
            style = STYLES.INFO;
            break;
        }
        case P8P_APP_MESSAGE_VARIANT.WARN: {
            style = STYLES.WARN;
            break;
        }
        case P8P_APP_MESSAGE_VARIANT.ERR: {
            style = STYLES.ERR;
            break;
        }
    }

    //Заголовок
    let titlePart;
    if (title && titleText) titlePart = <DialogTitle style={{ ...style.DEFAULT, ...style.titleText }}>{titleText}</DialogTitle>;

    //Кнопка Отмена
    let cancelBtnPart;
    if (cancelBtn && cancelBtnCaption && variant === P8P_APP_MESSAGE_VARIANT.WARN)
        cancelBtnPart = <Button onClick={() => (onCancel ? onCancel() : null)}>{cancelBtnCaption}</Button>;

    //Кнопка OK
    let okBtnPart;
    if (okBtn && okBtnCaption)
        okBtnPart = (
            <Button onClick={() => (onOk ? onOk() : null)} autoFocus>
                {okBtnCaption}
            </Button>
        );

    //Кнопка Подробнее
    let fullErrorTextBtn;
    if (fullErrorText && showErrMoreCaption && hideErrMoreCaption && variant === P8P_APP_MESSAGE_VARIANT.ERR)
        fullErrorTextBtn = (
            <Button onClick={() => setShowFullErrorText(!showFullErrorText)} sx={STYLES.FULL_ERROR_TEXT_BUTTON} autoFocus>
                {!showFullErrorText ? showErrMoreCaption : hideErrMoreCaption}
            </Button>
        );

    //Все действия
    let actionsPart;
    if (cancelBtnPart || okBtnPart)
        actionsPart = (
            <DialogActions>
                {fullErrorTextBtn}
                {okBtnPart}
                {cancelBtnPart}
            </DialogActions>
        );

    //Генерация содержимого
    return (
        <Dialog open={open || false} onClose={() => (onCancel ? onCancel() : null)}>
            {titlePart}
            <DialogContent>
                <DialogContentText style={style.bodyText}>{!showFullErrorText ? text : fullErrorText}</DialogContentText>
            </DialogContent>
            {actionsPart}
        </Dialog>
    );
};

//Контроль свойств - Сообщение
P8PAppMessage.propTypes = {
    variant: PropTypes.string.isRequired,
    title: PropTypes.bool,
    titleText: PropTypes.string,
    cancelBtn: PropTypes.bool,
    onCancel: PropTypes.func,
    cancelBtnCaption: PropTypes.string,
    okBtn: PropTypes.bool,
    onOk: PropTypes.func,
    okBtnCaption: PropTypes.string,
    open: PropTypes.bool,
    text: PropTypes.string,
    fullErrorText: PropTypes.string,
    showErrMoreCaption: PropTypes.string,
    hideErrMoreCaption: PropTypes.string
};

//Встроенное сообщение
const P8PAppInlineMessage = ({ variant, text, okBtn, onOk, okBtnCaption }) => {
    //Генерация содержимого
    return (
        <Container style={STYLES.INLINE_MESSAGE}>
            <Box p={1}>
                <Typography
                    color={
                        variant === P8P_APP_MESSAGE_VARIANT.ERR
                            ? APP_COLORS[STATE.ERR].contrColor
                            : variant === P8P_APP_MESSAGE_VARIANT.WARN
                            ? APP_COLORS[STATE.WARN].contrColor
                            : APP_COLORS[STATE.INFO].contrColor
                    }
                >
                    {text}
                </Typography>
                {okBtn && okBtnCaption ? (
                    <Box pt={1}>
                        <Button onClick={() => (onOk ? onOk() : null)} autoFocus>
                            {okBtnCaption}
                        </Button>
                    </Box>
                ) : null}
            </Box>
        </Container>
    );
};

//Контроль свойств - Встроенное сообщение
P8PAppInlineMessage.propTypes = {
    variant: PropTypes.string.isRequired,
    text: PropTypes.string.isRequired,
    okBtn: PropTypes.bool,
    onOk: PropTypes.func,
    okBtnCaption: PropTypes.string
};

//Формирование типового сообщения
const buildVariantMessage = (props, variant) => {
    //Извлекаем необходимые свойства
    let { open, titleText } = props;

    //Генерация содержимого
    return <P8PAppMessage {...props} variant={variant} open={open === undefined ? true : open} title={titleText ? true : false} okBtn={true} />;
};

//Формирование типового встроенного сообщения
const buildVariantInlineMessage = (props, variant) => {
    //Генерация содержимого
    return <P8PAppInlineMessage {...props} variant={variant} />;
};

//Сообщение об ошибке
const P8PAppMessageErr = props => buildVariantMessage(props, P8P_APP_MESSAGE_VARIANT.ERR);

//Сообщение предупреждения
const P8PAppMessageWarn = props => buildVariantMessage(props, P8P_APP_MESSAGE_VARIANT.WARN);

//Сообщение информации
const P8PAppMessageInfo = props => buildVariantMessage(props, P8P_APP_MESSAGE_VARIANT.INFO);

//Встраиваемое сообщение об ошибке
const P8PAppInlineError = props => buildVariantInlineMessage(props, P8P_APP_MESSAGE_VARIANT.ERR);

//Встраиваемое cообщение предупреждения
const P8PAppInlineWarn = props => buildVariantInlineMessage(props, P8P_APP_MESSAGE_VARIANT.WARN);

//Встраиваемое сообщение информации
const P8PAppInlineInfo = props => buildVariantInlineMessage(props, P8P_APP_MESSAGE_VARIANT.INFO);

//Диалог подсказки
const P8PHintDialog = ({ title, hint, onOk }) => {
    return (
        <Dialog open={true} onClose={e => (onOk ? onOk(e) : null)}>
            <DialogTitle>{title}</DialogTitle>
            <DialogContent>
                <div dangerouslySetInnerHTML={{ __html: hint }}></div>
            </DialogContent>
            <DialogActions>
                <Button onClick={e => (onOk ? onOk(e) : null)}>{BUTTONS.OK}</Button>
            </DialogActions>
        </Dialog>
    );
};

//Контроль свойств - Диалог подсказки
P8PHintDialog.propTypes = {
    title: PropTypes.string.isRequired,
    hint: PropTypes.string.isRequired,
    onOk: PropTypes.func
};

//----------------
//Интерфейс модуля
//----------------

export {
    P8P_APP_MESSAGE_VARIANT,
    P8PAppMessage,
    P8PAppMessageErr,
    P8PAppMessageWarn,
    P8PAppMessageInfo,
    P8PAppInlineMessage,
    P8PAppInlineError,
    P8PAppInlineWarn,
    P8PAppInlineInfo,
    P8PHintDialog
};
