/*
    Парус 8 - Панели мониторинга - Редактор панелей
    Компоненты: Форма (представление)
*/

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

import React, { useEffect, useState, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Paper, Stack, Typography, Icon, TextField, IconButton, InputAdornment } from "@mui/material"; //Интерфейсные элементы
import { ApplicationCtx } from "../../../../context/application"; //Контекст приложения
import { P8P_COMPONENT_INLINE_MESSAGE, P8PComponentInlineMessage } from "../../../../components/editors/p8p_component_inline_message"; //Информационное сообщение внутри компонента
import { ITEM_SHAPE, ITEMS_INITIAL, ORIENTATION } from "./common"; //Общие ресурсы и константы формы
import { APP_STYLES } from "../../../../../app.styles";

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

//Стили
const STYLES = {
    CONTAINER: { overflow: "auto", ...APP_STYLES.SCROLL }
};

//Иконка компонента
const COMPONENT_ICON = "fact_check";

//Наименование компонента
const COMPONENT_NAME = "Форма";

//------------------------------------
//Вспомогательные функции и компоненты
//------------------------------------

//Элемент формы
const FormItem = ({ item = null, fullWidth = false, value = "", onChange = null } = {}) => {
    //Подключение к контексту приложения
    const { pOnlineShowDictionary } = useContext(ApplicationCtx);

    //При изменении значения элемента
    const handleChange = e => onChange && onChange(e.target.id, e.target.value);

    //При очистке значения элемента
    const handleClear = () => onChange(item.name, "");

    //При выборе значения из словаря
    const handleDictionary = () =>
        item.unitCode &&
        item.showMethod &&
        pOnlineShowDictionary({
            unitCode: item.unitCode,
            showMethod: item.showMethod,
            inputParameters: [{ name: item.inputParameter, value }],
            callBack: res => res.success && onChange && onChange(item.name, res.outParameters[item.outputParameter])
        });

    //Формирование представления
    return (
        item && (
            <TextField
                fullWidth={fullWidth}
                type={"text"}
                variant={"standard"}
                value={value}
                label={item.caption}
                id={item.name}
                onChange={handleChange}
                {...(item.unitCode && {
                    InputLabelProps: { shrink: true },
                    InputProps: {
                        readOnly: true,
                        endAdornment: (
                            <InputAdornment position="end">
                                <IconButton onClick={handleClear}>
                                    <Icon>clear</Icon>
                                </IconButton>
                                <IconButton onClick={handleDictionary}>
                                    <Icon>list</Icon>
                                </IconButton>
                            </InputAdornment>
                        )
                    }
                })}
            />
        )
    );
};

//Контроль свойств - элемент формы
FormItem.propTypes = {
    item: ITEM_SHAPE,
    fullWidth: PropTypes.bool,
    value: PropTypes.any,
    onChange: PropTypes.func
};

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

//Форма (представление)
const Form = ({ title = null, orientation = ORIENTATION.V, autoApply = false, items = ITEMS_INITIAL, values = {}, onValuesChange = null } = {}) => {
    //Собственное состояние - значения элементов
    const [selfValues, setSelfValues] = useState({});

    //При изменении состава элементов или значений
    useEffect(() => setSelfValues(items.reduce((sV, item) => ({ ...sV, [item.name]: values[item.name] }), {})), [items, values]);

    //При изменении значения элемента формы
    const handleItemChange = (name, value) => {
        setSelfValues(pv => ({ ...pv, [name]: value }));
        autoApply && onValuesChange && onValuesChange({ ...selfValues, [name]: value });
    };

    //При подтверждении изменений формы
    const handleOkClick = () => onValuesChange && onValuesChange({ ...selfValues });

    //Флаг настроенности формы
    const haveConfing = items && Array.isArray(items) && items.length > 0;

    //Формирование представления
    return (
        <Paper className={`component-view__container ${!haveConfing && "component-view__container__empty"}`} sx={STYLES.CONTAINER} elevation={6}>
            {haveConfing ? (
                <Stack direction={"column"}>
                    <Stack direction={"row"} justifyContent={"space-between"} alignItems={"center"}>
                        {title && (
                            <Typography align={"left"} color={"text.primary"} variant={"subtitle2"} noWrap={true}>
                                {title}
                            </Typography>
                        )}
                        {!autoApply && (
                            <IconButton onClick={handleOkClick}>
                                <Icon>done</Icon>
                            </IconButton>
                        )}
                    </Stack>
                    <Stack direction={orientation == ORIENTATION.V ? "column" : "row"} spacing={1} pt={1} pb={1}>
                        {items.map((item, i) => (
                            <FormItem
                                key={i}
                                item={item}
                                value={selfValues?.[item.name] || ""}
                                onChange={handleItemChange}
                                fullWidth={orientation == ORIENTATION.V}
                            />
                        ))}
                    </Stack>
                </Stack>
            ) : (
                <P8PComponentInlineMessage icon={COMPONENT_ICON} name={COMPONENT_NAME} message={P8P_COMPONENT_INLINE_MESSAGE.NO_SETTINGS} />
            )}
        </Paper>
    );
};

//Контроль свойств компонента - Форма (представление)
Form.propTypes = {
    id: PropTypes.string.isRequired,
    title: PropTypes.string,
    orientation: PropTypes.oneOf(Object.values(ORIENTATION)),
    autoApply: PropTypes.bool,
    items: PropTypes.arrayOf(ITEM_SHAPE),
    values: PropTypes.object,
    onValuesChange: PropTypes.func
};

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

export default Form;
