/*
    Парус 8 - Панели мониторинга - Редакторы панелей
    Компонент: Диалог настройки источника данных
*/

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

import React, { useState, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Stack, IconButton, Icon, TextField, InputAdornment, MenuItem, Menu } from "@mui/material"; //Интерфейсные элементы
import { ApplicationCtx } from "../../context/application"; //Контекст приложения
import { TITLES, CAPTIONS } from "../../../app.text"; //Общие текстовые ресурсы
import { P8PConfigDialog } from "./p8p_config_dialog"; //Типовой диалог настройки
import { P8P_DATA_SOURCE_TYPE, P8P_DATA_SOURCE_SHAPE, P8P_DATA_SOURCE_ARGUMENT_INITIAL, P8P_DATA_SOURCE_INITIAL } from "./p8p_data_source_common"; //Общие ресурсы компонента "Источник данных"
import { useUserProcDesc } from "./p8p_data_source_hooks"; //Хуки источников данных
import { P8PDataSourceQuerySelector } from "./p8p_data_source_query_selector"; //Диалог выбора записи редактора запросов
import { hasValue } from "../../core/utils"; //Вспомогательные функции

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

//Диалог настройки источника данных
const P8PDataSourceConfigDialog = ({ dataSource = null, valueProviders = {}, onOk = null, onCancel = null } = {}) => {
    //Собственное состояние - параметры элемента формы
    const [state, setState] = useState({ ...P8P_DATA_SOURCE_INITIAL, ...dataSource });

    //Собственное состояние - флаги обновление данных
    const [refresh, setRefresh] = useState({ userProcDesc: 0 });

    //Собственное состояние - элемент привязки меню выбора источника
    const [valueProvidersMenuAnchorEl, setValueProvidersMenuAnchorEl] = useState(null);

    //Описание выбранной пользовательской процедуры
    const [userProcDesc] = useUserProcDesc({ code: state.userProc, refresh: refresh.userProcDesc });

    //Собственное состояние - отображение диалога выбора запроса
    const [openQuerySelector, setOpenQuerySelector] = useState(false);

    //Собственное состояние - доступность полей выбора источника
    const [disabledFields, setDisabledFields] = useState({ query: false, userProc: false });

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

    //Установка значения/привязки аргумента
    const setArgumentValueSource = (index, value, valueSource) =>
        setState(pv => ({
            ...pv,
            arguments: pv.arguments.map((argument, i) => ({ ...argument, ...(i == index ? { value, valueSource } : {}) }))
        }));

    //Открытие/сокрытие меню выбора источника
    const toggleValueProvidersMenu = target => setValueProvidersMenuAnchorEl(target instanceof Element ? target : null);

    //При нажатии на очистку наименования пользовательской процедуры
    const handleUserProcClearClick = () => setState({ ...P8P_DATA_SOURCE_INITIAL });

    //При нажатии на выбор пользовательской процедуры в качестве источника данных
    const handleUserProcSelectClick = () => {
        pOnlineShowDictionary({
            unitCode: "UserProcedures",
            showMethod: "main",
            inputParameters: [{ name: "in_CODE", value: state.userProc }],
            callBack: res => {
                if (res.success) {
                    setState(pv => ({ ...pv, type: P8P_DATA_SOURCE_TYPE.USER_PROC, userProc: res.outParameters.out_CODE }));
                    setRefresh(pv => ({ ...pv, userProcDesc: pv.userProcDesc + 1 }));
                }
            }
        });
    };

    //При закрытии дилога с сохранением
    const handleOk = () => onOk && onOk({ ...state });

    //При закртии диалога отменой
    const handleCancel = () => onCancel && onCancel();

    //При очистке значения/связывания аргумента
    const handleArgumentClearClick = index => setArgumentValueSource(index, "", "");

    //При отображении меню связывания аргумента с поставщиком данных
    const handleArgumentLinkMenuClick = e => setValueProvidersMenuAnchorEl(e.currentTarget);

    //При выборе элемента меню связывания аргумента с поставщиком данных
    const handleArgumentLinkClick = valueSource => {
        setArgumentValueSource(valueProvidersMenuAnchorEl.id, "", valueSource);
        toggleValueProvidersMenu();
    };

    //При вводе значения аргумента
    const handleArgumentChange = (index, value) => setArgumentValueSource(index, value, "");

    //Открытие диалога выбора запроса
    const handleOpenQuerySelector = () => setOpenQuerySelector(true);

    //Закрытие диалога выбора запроса
    const handleCancelQuerySelector = () => setOpenQuerySelector(false);

    //При нажатии на очистку мнемокода запроса
    const handleQueryClearClick = () => setState({ ...P8P_DATA_SOURCE_INITIAL });

    //При нажатии на выбор запроса в качестве источника данных
    const handleQuerySelectClick = query => {
        setState(pv => ({ ...pv, type: P8P_DATA_SOURCE_TYPE.QUERY, query: query.code }));
        handleCancelQuerySelector();
    };

    //При изменении описания пользовательской процедуры
    useEffect(() => {
        if (userProcDesc)
            setState(pv => ({
                ...pv,
                stored: userProcDesc?.stored?.name,
                respArg: userProcDesc?.stored?.respArg,
                arguments: (userProcDesc?.arguments || []).map(argument => ({ ...P8P_DATA_SOURCE_ARGUMENT_INITIAL, ...argument }))
            }));
    }, [userProcDesc]);

    //При изменении источника
    useEffect(() => {
        /*
          Если выбран запрос - блокируем выбор процедуры
          Если выбрана процедура - блокируем выбор запроса
          Ничего не выбрано - доступны все варианты
        */
        hasValue(state.query)
            ? setDisabledFields({ query: false, userProc: true })
            : hasValue(state.userProc)
              ? setDisabledFields({ query: true, userProc: false })
              : setDisabledFields({ query: false, userProc: false });
    }, [state.query, state.userProc]);

    //Список значений
    const values = Object.keys(valueProviders);

    //Наличие значений
    const isValues = values && values.length > 0 ? true : false;

    //Меню привязки к поставщикам значений
    const valueProvidersMenu = isValues && (
        <Menu anchorEl={valueProvidersMenuAnchorEl} open={Boolean(valueProvidersMenuAnchorEl)} onClose={toggleValueProvidersMenu}>
            {values.map((value, i) => (
                <MenuItem key={i} onClick={() => handleArgumentLinkClick(value)}>
                    {value}
                </MenuItem>
            ))}
        </Menu>
    );

    //Доступность сохранения настройки источника данных
    const okDisabled = !state.query && !state.userProc ? true : false;

    //Формирование представления
    return (
        <>
            {openQuerySelector ? (
                <P8PDataSourceQuerySelector current={state.query} onSelect={handleQuerySelectClick} onCancel={handleCancelQuerySelector} />
            ) : null}
            <P8PConfigDialog title={TITLES.DATA_SOURCE_CONFIG} onOk={handleOk} onCancel={handleCancel} okDisabled={okDisabled}>
                <Stack direction={"column"} spacing={1}>
                    {valueProvidersMenu}
                    {/* ДОРАБАТЫВАТЬ ПОСЛЕ РЕАЛИЗАЦИИ ЗАПРОСОВ */}
                    <TextField
                        type={"text"}
                        variant={"standard"}
                        value={state.query}
                        label={CAPTIONS.QUERY}
                        InputLabelProps={{ shrink: true }}
                        InputProps={{
                            readOnly: true,
                            endAdornment: (
                                <InputAdornment position="end">
                                    <IconButton onClick={handleQueryClearClick} disabled={disabledFields.query}>
                                        <Icon>clear</Icon>
                                    </IconButton>
                                    <IconButton onClick={handleOpenQuerySelector} disabled={disabledFields.query}>
                                        <Icon>list</Icon>
                                    </IconButton>
                                </InputAdornment>
                            )
                        }}
                        disabled={disabledFields.query}
                    />
                    <TextField
                        type={"text"}
                        variant={"standard"}
                        value={state.userProc}
                        label={CAPTIONS.USER_PROC}
                        InputLabelProps={{ shrink: true }}
                        InputProps={{
                            readOnly: true,
                            endAdornment: (
                                <InputAdornment position="end">
                                    <IconButton onClick={handleUserProcClearClick} disabled={disabledFields.userProc}>
                                        <Icon>clear</Icon>
                                    </IconButton>
                                    <IconButton onClick={handleUserProcSelectClick} disabled={disabledFields.userProc}>
                                        <Icon>list</Icon>
                                    </IconButton>
                                </InputAdornment>
                            )
                        }}
                        disabled={disabledFields.userProc}
                    />
                    {Array.isArray(state?.arguments) &&
                        state.arguments.map((argument, i) => (
                            <TextField
                                key={i}
                                type={"text"}
                                variant={"standard"}
                                value={argument.value || argument.valueSource}
                                label={argument.caption}
                                onChange={e => handleArgumentChange(i, e.target.value)}
                                InputLabelProps={{ shrink: true }}
                                InputProps={{
                                    endAdornment: (
                                        <InputAdornment position="end">
                                            <IconButton onClick={() => handleArgumentClearClick(i)}>
                                                <Icon>clear</Icon>
                                            </IconButton>
                                            {isValues && (
                                                <IconButton id={i} onClick={handleArgumentLinkMenuClick}>
                                                    <Icon>settings_ethernet</Icon>
                                                </IconButton>
                                            )}
                                        </InputAdornment>
                                    )
                                }}
                            />
                        ))}
                </Stack>
            </P8PConfigDialog>
        </>
    );
};

//Контроль свойств компонента - Диалог настройки источника данных
P8PDataSourceConfigDialog.propTypes = {
    dataSource: P8P_DATA_SOURCE_SHAPE,
    valueProviders: PropTypes.object,
    onOk: PropTypes.func,
    onCancel: PropTypes.func
};

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

export { P8PDataSourceConfigDialog };
