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

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

import React, { useState, useContext, useMemo } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Stack, List, ListItem, ListItemButton, ListItemText, Typography } from "@mui/material"; //Интерфейсные элементы
import { P8PDialog } from "./p8p_dialog"; //Типовой диалог
import { deepCopyObject } from "../core/utils"; //Вспомогательные функции
import { ApplicationCtx } from "../context/application"; //Контекст приложения
import { P8P_DATA_TYPES } from "../core/data_types"; //Типы данных

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

//Стили
const STYLES = {
    LIST: { width: "510px", bgcolor: "background.paper", overflowY: "auto" },
    TYPOGRAPHY_VALUE: { maxWidth: "200px" },
    TEXT_FIELD_STR_VALUE: { minWidth: "400px" }
};

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

//Диалог изменения параметра
const P8PSettingChangeDialog = ({ initSetting, onSave, onClose }) => {
    //Собственное состояние - параметр
    const [setting, setSetting] = useState(deepCopyObject(initSetting));

    //Собственное состояние - доступность выбора из словаря
    const isDictionary = useMemo(() => {
        //Проверяем наличие обязательных настроек
        return (
            setting.options &&
            setting.options?.unitcode &&
            setting.options?.showMethod &&
            setting.options?.inParameter &&
            setting.options?.outParameter
        );
    }, [setting.options]);

    //Подключение к контексту приложения
    const { pOnlineShowDictionary } = useContext(ApplicationCtx);

    //При закрытии диалога
    const handleClose = () => onClose && onClose();

    //При нажатии "ОК"
    const handleOk = () => onSave && onSave(setting);

    //При изменении значения параметра
    const handleSettingChange = (name, value) => {
        setSetting(pv => ({ ...pv, [name]: value }));
    };

    //При выборе значения из справочника
    const handleDictionarySelect = (currentFormValues, setFormValues) => {
        //Открываем справочник с учетом параметров
        pOnlineShowDictionary({
            unitCode: initSetting.options.unitcode,
            showMethod: initSetting.options.showMethod,
            inputParameters: [{ name: initSetting.options.inParameter, value: currentFormValues.value }],
            callBack: res => {
                res.success === true ? setFormValues([{ name: "value", value: res.outParameters[initSetting.options.outParameter] }]) : null;
            }
        });
    };

    //Формирование представления
    return (
        <P8PDialog
            title={setting.name}
            width="xs"
            fullWidth
            onCancel={handleClose}
            onOk={handleOk}
            inputs={[
                {
                    name: "value",
                    value: setting.value,
                    label: "Значение",
                    dictionary: isDictionary ? handleDictionarySelect : null,
                    type: setting.dataType === P8P_DATA_TYPES.NUMB ? "number" : setting.dataType === P8P_DATA_TYPES.DATE ? "date" : "text"
                }
            ]}
            onInputChange={handleSettingChange}
        />
    );
};

//Контроль свойств компонента - Диалог изменения параметра
P8PSettingChangeDialog.propTypes = {
    initSetting: PropTypes.object,
    onSave: PropTypes.func,
    onClose: PropTypes.func
};

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

//Список параметров
const P8PSettingsList = ({ settings, onSettingChange }) => {
    //Собственное состояние - изменяемый параметр
    const [changingSetting, setChangingSetting] = useState(null);

    //При нажатии на параметр
    const handleSettingClick = settingCode => setChangingSetting(settingCode);

    //При очистки изменяемого параметра
    const handleChangingSettingClear = () => setChangingSetting(null);

    //При изменении значения параметра
    const handleSettingChange = newSetting => {
        //Вызываем изменение параметра
        onSettingChange && onSettingChange(changingSetting, newSetting);
        //Очищаем изменяемый параметр
        handleChangingSettingClear();
    };

    //Формирование представления
    return (
        <>
            <List sx={STYLES.LIST}>
                {Object.keys(settings).map((setting, i) => {
                    return (
                        <ListItem key={i}>
                            <ListItemButton onClick={() => handleSettingClick(setting)}>
                                <ListItemText
                                    primary={settings[setting].name}
                                    secondaryTypographyProps={{ component: "div" }}
                                    secondary={
                                        <Stack direction={"row"} justifyContent={"space-between"} gap={2}>
                                            <Typography
                                                variant={"caption"}
                                                noWrap={true}
                                                title={settings[setting].desc ? settings[setting].desc : "Описание отсутствует"}
                                            >{`${settings[setting].desc ? settings[setting].desc : "Описание отсутствует"}`}</Typography>
                                            <Typography
                                                variant={"caption"}
                                                sx={STYLES.TYPOGRAPHY_VALUE}
                                                noWrap={true}
                                                title={settings[setting].value}
                                            >{`${settings[setting].value}`}</Typography>
                                        </Stack>
                                    }
                                />
                            </ListItemButton>
                        </ListItem>
                    );
                })}
            </List>
            {changingSetting ? (
                <P8PSettingChangeDialog initSetting={settings[changingSetting]} onSave={handleSettingChange} onClose={handleChangingSettingClear} />
            ) : null}
        </>
    );
};

//Контроль свойств компонента - Список параметров
P8PSettingsList.propTypes = {
    settings: PropTypes.object,
    onSettingChange: PropTypes.func
};

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

export { P8PSettingsList };
