/*
    Парус 8 - Панели мониторинга - ТОиР - Прогнозирование технического состояния
    Корневая панель прогнозирования технического состояния: дополнительная разметка и вёрстка клиентских элементов
*/

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

import React, { useState, useEffect } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import {
    Box,
    Stack,
    Icon,
    Input,
    InputAdornment,
    FormControl,
    Select,
    InputLabel,
    MenuItem,
    IconButton,
    Autocomplete,
    TextField
} from "@mui/material"; //Интерфейсные компоненты

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

//Режимы работы панели
const MODES = {
    FORECAST: 1,
    ADMIN: 2
};

//Высота главного меню
const APP_BAR_HEIGHT = "64px";

//Высота закладок
const TABS_HEIGHT = "49px";

//Высота кнопки "Ещё"
const TABLE_MORE_HEIGHT = "49px";

//Высота фильтров таблицы
const TABLE_FILTERS_HEIGHT = "48px";

//Стиль скролов
const SCROLL_STYLES = {
    "&::-webkit-scrollbar": {
        height: "8px",
        width: "8px"
    },
    "&::-webkit-scrollbar-track": {
        borderRadius: "8px",
        backgroundColor: "#EBEBEB"
    },
    "&::-webkit-scrollbar-thumb": {
        borderRadius: "8px",
        backgroundColor: "#b4b4b4"
    },
    "&::-webkit-scrollbar-thumb:hover": {
        backgroundColor: "#808080"
    }
};

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

//Формирование значения для колонки "Состояние" модели класса оборудования выборки данных
const formatModelStateValue = (theme, value, err) => {
    const [text, icon, color] =
        value == 0
            ? ["Зарегистрирована", "app_registration", null]
            : value == 1
            ? ["Обучается", "manage_history", theme.palette.warning.main]
            : value == 2
            ? ["Обучена", "check_circle", theme.palette.primary.main]
            : [`Ошибка обучения: ${err}`, "error", theme.palette.error.main];
    return (
        <Stack direction="row" gap={0.5} alignItems="center" justifyContent="left" color={color}>
            <Icon title={text}>{icon}</Icon>
            {text}
        </Stack>
    );
};

//Выбор класса оборудования из словаря
const selectEqobjKind = (showDictionary, name, callBack) => {
    showDictionary({
        unitCode: "EquipObjectKinds",
        callBack: res => callBack(res.success ? [{ name, value: res.outParameters.out_FULLCODE }] : null)
    });
};

//Выбор единица измерения из словаря
const selectMeasureUnit = (showDictionary, name, callBack) => {
    showDictionary({
        unitCode: "MeasureUnits",
        callBack: res => callBack(res.success ? [{ name, value: res.outParameters.out_MEAS_MNEMO }] : null)
    });
};

//Выбор процедуры формирования из словаря
const selectUserProcsData = (showDictionary, name, callBack) => {
    showDictionary({
        unitCode: "UserProcedures",
        callBack: res => callBack(res.success ? [{ name, value: res.outParameters.out_CODE }] : null)
    });
};

//Выбор функции обмена для выгрузки данных
const selectServiceFn = (showDictionary, name, callBack) => {
    showDictionary({
        unitCode: "EXSService",
        callBack: res =>
            callBack(
                res.success
                    ? [
                          { name, value: res.outParameters.out_FN_CODE },
                          {
                              name:
                                  name == "exsServiceFnUpload"
                                      ? "exsServiceUpload"
                                      : name == "exsServiceFnSendMd"
                                      ? "exsServiceSendMd"
                                      : name == "exsServiceFnSendMdCb"
                                      ? "exsServiceSendMdCb"
                                      : name == "exsServiceFnSendRq"
                                      ? "exsServiceSendRq"
                                      : name == "exsServiceFnSendRqCb"
                                      ? "exsServiceSendRqCb"
                                      : "exsServiceForecastMd",
                              value: res.outParameters.out_CODE
                          }
                      ]
                    : null
            )
    });
};

//Закладка
const TabPanel = ({ mode, value, children }) => <Box hidden={mode != value}>{children}</Box>;

//Контроль свойств - Закладка
TabPanel.propTypes = {
    mode: PropTypes.number.isRequired,
    value: PropTypes.number.isRequired,
    children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)])
};

//Поле ввода формы
const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dictionary, list, type, freeSolo = false, ...other }) => {
    //Значение элемента
    const [value, setValue] = useState(elementValue);

    //При получении нового значения из вне
    useEffect(() => {
        setValue(elementValue);
    }, [elementValue]);

    //Выбор значения из словаря
    const handleDictionaryClick = () =>
        dictionary ? dictionary(res => (res ? res.map(i => handleChange({ target: { name: i.name, value: i.value } })) : null)) : null;

    //Изменение значения элемента (по событию)
    const handleChange = e => {
        setValue(e.target.value);
        if (onChange) onChange(e.target.name, e.target.value);
    };

    //Изменение значения элемента (по имени и значению)
    const handleChangeByName = (name, value) => {
        setValue(value);
        if (onChange) onChange(name, value);
    };

    //Генерация содержимого
    return (
        <Box p={1}>
            <FormControl variant="standard" fullWidth {...other}>
                {list ? (
                    freeSolo ? (
                        <Autocomplete
                            id={elementCode}
                            name={elementCode}
                            freeSolo
                            inputValue={value ? value : ""}
                            onChange={(event, newValue) => handleChangeByName(elementCode, newValue)}
                            onInputChange={(event, newInputValue) => handleChangeByName(elementCode, newInputValue)}
                            options={list}
                            renderInput={params => <TextField {...params} label={labelText} name={elementCode} variant={"standard"} />}
                        />
                    ) : (
                        <>
                            <InputLabel id={`${elementCode}Lable`} shrink>
                                {labelText}
                            </InputLabel>
                            <Select
                                labelId={`${elementCode}Lable`}
                                id={elementCode}
                                name={elementCode}
                                label={labelText}
                                value={value ? value : ""}
                                onChange={handleChange}
                                displayEmpty
                            >
                                {list.map((item, i) => (
                                    <MenuItem key={i} value={item.value ? item.value : ""}>
                                        {item.name}
                                    </MenuItem>
                                ))}
                            </Select>
                        </>
                    )
                ) : (
                    <>
                        <InputLabel {...(type == "date" ? { shrink: true } : {})} htmlFor={elementCode}>
                            {labelText}
                        </InputLabel>
                        <Input
                            id={elementCode}
                            name={elementCode}
                            value={value ? value : ""}
                            endAdornment={
                                dictionary ? (
                                    <InputAdornment position="end">
                                        <IconButton aria-label={`${elementCode} select`} onClick={handleDictionaryClick} edge="end">
                                            <Icon>list</Icon>
                                        </IconButton>
                                    </InputAdornment>
                                ) : null
                            }
                            {...(type ? { type } : {})}
                            onChange={handleChange}
                        />
                    </>
                )}
            </FormControl>
        </Box>
    );
};

//Контроль свойств - Поле ввода формы
IUDFormTextField.propTypes = {
    elementCode: PropTypes.string.isRequired,
    elementValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.instanceOf(Date)]),
    labelText: PropTypes.string.isRequired,
    onChange: PropTypes.func,
    dictionary: PropTypes.func,
    list: PropTypes.array,
    type: PropTypes.string,
    freeSolo: PropTypes.bool
};

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

export {
    MODES,
    APP_BAR_HEIGHT,
    TABS_HEIGHT,
    TABLE_MORE_HEIGHT,
    TABLE_FILTERS_HEIGHT,
    SCROLL_STYLES,
    formatModelStateValue,
    selectEqobjKind,
    selectMeasureUnit,
    selectUserProcsData,
    selectServiceFn,
    TabPanel,
    IUDFormTextField
};
