/*
    Парус 8 - Панели мониторинга - ТОиР - Прогнозирование технического состояния
    Закладка администрирования
*/

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

import React, { useState, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Box, Grid, Stack, Icon, Button, IconButton } from "@mui/material"; //Интерфейсные компоненты
import { ApplicationСtx } from "../../context/application"; //Контекст приложения
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с серверомs
import { P8PAppInlineError } from "../../components/p8p_app_message"; //Встраиваемое сообщение об ошибке
import { DS_RN_DEFAULT, useEquipDataSelectionList } from "./eqs_tech_cond_forecast_hooks"; //Общие вспомогательные хуки
import {
    EquipDataSelectionIU,
    EquipDataSelectionList,
    EquipDataSelectionClassMachineIU,
    EquipDataSelectionClassMachineList,
    EquipDataSelectionClassMachineCard,
    EquipDataSelectionClassMachineFileSendMDDialog,
    EquipDataSelectionClassMachineModelIU
} from "./admin_tab_layout"; //Вспомогательные компоненты и вёрстка
import {
    useEquipDataSelectionClassMachineList,
    useEquipDataSelectionClassMachineCard,
    useEquipDataSelectionClassMachineFilesList,
    useEquipDataSelectionClassMachineModelsList
} from "./admin_tab_hooks"; //Вспомогательные хуки

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

//Начальное состояние флагов обновления
const REFRESH_INITIAL = {
    dataSelection: 0,
    dataSelectionClassMachine: 0,
    dataSelectionClassMachineCard: 0,
    dataSelectionClassMachineFilesList: 0,
    dataSelectionClassMachineModelsList: 0
};

//Начальное состояние диалогов
const DIALOGS_INITIAL = {
    dataSelectionIU: false,
    dataSelectionClassMachineIU: false,
    dataSelectionClassMachine: null,
    dataSelectionClassMachineFileSendMD: false,
    dataSelectionClassMachineModelIU: false
};

//Стили
const STYLES = {
    DATA_SELECTION_STACK: { alignItems: "center" },
    CLASS_MACHINE_ADD_BUTTON: { margin: "5px" }
};

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

//Закладка администрирования
const AdminTab = ({ dataSelection = DS_RN_DEFAULT, dataSelectionClassMachine = null }) => {
    //Подключение к контексту взаимодействия с сервером
    const { executeStored } = useContext(BackEndСtx);

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

    //Собственное состояние - отображаемые диалоги
    const [dialogs, setDialogs] = useState(DIALOGS_INITIAL);

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

    //Собственное состояние - выбранная выборка данных
    const [equipDataSelection, setDataSelection] = useState(dataSelection);

    //Собственное состояние - выбранный класс оборудования
    const [equipDataSelectionClassMachine, setDataSelectionClassMachine] = useState(dataSelectionClassMachine);

    //Загрузка списка выборок данных
    const { equipDataSelectionList, equipDataSelectionListIsLoading, equipDataSelectionListAccess } = useEquipDataSelectionList(
        refresh.dataSelection
    );

    //Загрузка классов оборудования выбранной выборки данных
    const { equipDataSelectionClassMachineList } = useEquipDataSelectionClassMachineList(equipDataSelection, refresh.dataSelectionClassMachine);

    //Загрузка карточки класса оборудования
    const { equipDataSelectionClassMachineCard } = useEquipDataSelectionClassMachineCard(
        equipDataSelectionClassMachine,
        refresh.dataSelectionClassMachineCard
    );

    //Загрузка файлов класса оборудования
    const { equipDataSelectionClassMachineFilesList } = useEquipDataSelectionClassMachineFilesList(
        equipDataSelectionClassMachine,
        refresh.dataSelectionClassMachineFilesList
    );

    //Загрузка моделей класса оборудования
    const { equipDataSelectionClassMachineModelsList } = useEquipDataSelectionClassMachineModelsList(
        equipDataSelectionClassMachine,
        refresh.dataSelectionClassMachineModelsList
    );

    //При смене выборки данных
    const handleDataSelectionChange = (value, resetRefresh = true) => {
        setDataSelection(value);
        setDataSelectionClassMachine(null);
        if (resetRefresh) setRefresh(REFRESH_INITIAL);
    };

    //При нажатии на "Добавить выборку"
    const handleAddEquipDataSelection = () => setDialogs(pv => ({ ...pv, dataSelectionIU: true }));

    //При нажатии на "Удалить выборку"
    const handleDeleteEquipDataSelection = async () => {
        await executeStored({ stored: "UDO_PKG_EQUIPDS.DEL", args: { NRN: equipDataSelection } });
        setRefresh(pv => ({ ...pv, dataSelection: pv.dataSelection + 1 }));
        handleDataSelectionChange(DS_RN_DEFAULT, false);
    };

    //При отмене диалога IU выборки
    const handleEquipDataSelectionIUCancel = () => setDialogs(pv => ({ ...pv, dataSelectionIU: false }));

    //При сохранении диалога IU выборки
    const handleEquipDataSelectionIUOk = async values => {
        const data = await executeStored({ stored: "UDO_PKG_EQUIPDS.INS", args: { SCODE: values.code, SNAME: values.name } });
        setDialogs(pv => ({ ...pv, dataSelectionIU: false }));
        setRefresh(pv => ({ ...pv, dataSelection: pv.dataSelection + 1 }));
        handleDataSelectionChange(data.NRN, false);
    };

    //При нажатии на класс оборудования
    const handleDataSelectionClassMachineClick = value => setDataSelectionClassMachine(value);

    //При нажатии на "Добавить класс оборудования"
    const handleAddEquipDataSelectionClassMachine = () =>
        setDialogs(pv => ({ ...pv, dataSelectionClassMachineIU: true, dataSelectionClassMachine: null }));

    //При нажатии на "Изменить класс оборудования"
    const handleEditEquipDataSelectionClassMachine = equipDSCM => {
        setDialogs(pv => ({ ...pv, dataSelectionClassMachineIU: true, dataSelectionClassMachine: equipDSCM }));
    };

    //При нажатии на "Удалить класс оборудования"
    const handleDeleteEquipDataSelectionClassMachine = async equipDSCM => {
        await executeStored({ stored: "UDO_PKG_EQUIPDS.CM_DEL", args: { NRN: equipDSCM } });
        setRefresh(pv => ({ ...pv, dataSelectionClassMachine: pv.dataSelectionClassMachine + 1 }));
        setDataSelectionClassMachine(null);
    };

    //При отмене диалога IU класса оборудования
    const handleEquipDataSelectionClassMachineIUCancel = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineIU: false }));

    //При сохранении диалога IU класса оборудования
    const handleEquipDataSelectionClassMachineIUOk = async values => {
        let dataSelectionClassMachine = null;
        const args = {
            SEQOBJKIND: values.eqobjKind,
            SDICMUNTS: values.measureUnit,
            SUSERPROCS_DATA: values.userprocsData,
            SEXSSERVICE_UPLOAD: values.exsServiceUpload,
            SEXSSERVICEFN_UPLOAD: values.exsServiceFnUpload,
            SEXSSERVICE_SEND_MD: values.exsServiceSendMd,
            SEXSSERVICEFN_SEND_MD: values.exsServiceFnSendMd,
            SEXSSERVICE_SEND_MDCB: values.exsServiceSendMdCb,
            SEXSSERVICEFN_SEND_MDCB: values.exsServiceFnSendMdCb,
            SEXSSERVICE_SEND_RQ: values.exsServiceSendRq,
            SEXSSERVICEFN_SEND_RQ: values.exsServiceFnSendRq,
            SEXSSERVICE_SEND_RQCB: values.exsServiceSendRqCb,
            SEXSSERVICEFN_SEND_RQCB: values.exsServiceFnSendRqCb,
            SEXSSERVICE_FRCST_MD: values.exsServiceForecastMd,
            SEXSSERVICEFN_FRCST_MD: values.exsServiceFnForecastMd
        };
        if (dialogs.dataSelectionClassMachine) {
            await executeStored({
                stored: "UDO_PKG_EQUIPDS.CM_UPD",
                args: { NRN: dialogs.dataSelectionClassMachine, ...args }
            });
            dataSelectionClassMachine = dialogs.dataSelectionClassMachine;
            setRefresh(pv => ({ ...pv, dataSelectionClassMachineCard: pv.dataSelectionClassMachineCard + 1 }));
        } else {
            const data = await executeStored({
                stored: "UDO_PKG_EQUIPDS.CM_INS",
                args: { NPRN: equipDataSelection, ...args }
            });
            dataSelectionClassMachine = data.NRN;
        }
        setDialogs(pv => ({ ...pv, dataSelectionClassMachineIU: false, dataSelectionClassMachine: null }));
        setRefresh(pv => ({ ...pv, dataSelectionClassMachine: pv.dataSelectionClassMachine + 1 }));
        setDataSelectionClassMachine(dataSelectionClassMachine);
    };

    //Отработка результатов выполнения пользовательской процедуры формирования данных выборки
    const processMakeEquipDataSelectionClassMachineFilesResults = async (equipDSCM, dataSetIdent, dataSetConfigIdent, clear) => {
        await executeStored({
            stored: "UDO_PKG_EQUIPDS.CMFL_MAKE",
            args: {
                NEQUIPDSCM: equipDSCM,
                NDATASET_IDENT: dataSetIdent,
                NDATASET_CONFIG_IDENT: dataSetConfigIdent,
                NCLEAR: clear
            }
        });
        setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 }));
    };

    //При нажатии "Обновить" в списке файлов карточки класса оборудования
    const handleRefreshEquipDataSelectionClassMachineFiles = () =>
        setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 }));

    //При нажатии "Сформировать" в списке файлов карточки класса оборудования
    const handleMakeEquipDataSelectionClassMachineFiles = (equipDSCM, procedure, clear) => {
        pOnlineUserProcedure({
            code: procedure,
            inputParameters: [{ name: "NEQUIPDSCM", value: equipDSCM }],
            callBack: res => {
                if (res.success)
                    processMakeEquipDataSelectionClassMachineFilesResults(
                        equipDSCM,
                        res.outParameters?.NDATASET_IDENT,
                        res.outParameters?.NDATASET_CONFIG_IDENT,
                        clear
                    );
            }
        });
    };

    //При нажатии "Удалить" в списке файлов карточки класса оборудования
    const handleDeleteEquipDataSelectionClassMachineFiles = async equipDSCMFL => {
        await executeStored({ stored: "UDO_PKG_EQUIPDS.CMFL_DEL", args: { NRN: equipDSCMFL } });
        setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 }));
    };

    //При нажатии "Загрузить на сервер" в списке файлов карточки класса оборудования
    const handleUploadEquipDataSelectionClassMachineFiles = async equipDSCM => {
        await executeStored({ stored: "UDO_PKG_EQUIPDS.CMFL_UPLOAD", args: { NEQUIPDSCM: equipDSCM } });
        setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 }));
    };

    //При нажатии "Передать внешней системе" в списке файлов карточки класса оборудования
    const handleSendMdEquipDataSelectionClassMachineFiles = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineFileSendMD: true }));

    //При нажатии на "Обновить модели класса оборудования"
    const handleRefreshEquipDataSelectionClassMachineModel = () =>
        setRefresh(pv => ({ ...pv, dataSelectionClassMachineModelsList: pv.dataSelectionClassMachineModelsList + 1 }));

    //При нажатии на "Добавить модель класса оборудования"
    const handleAddEquipDataSelectionClassMachineModel = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineModelIU: true }));

    //При нажатии на "Удалить модель класса оборудования"
    const handleDeleteEquipDataSelectionClassMachineModel = async equipDSCMML => {
        await executeStored({ stored: "UDO_PKG_EQUIPDS.CMML_DEL", args: { NRN: equipDSCMML } });
        setRefresh(pv => ({ ...pv, dataSelectionClassMachineModelsList: pv.dataSelectionClassMachineModelsList + 1 }));
    };

    //При отмене диалога отправки файла данных фреймворку
    const handleEquipDataSelectionClassMachineFileSendMDCancel = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineFileSendMD: false }));

    //При сохранении диалога отправки файла данных фреймворку
    const handleEquipDataSelectionClassMachineFileSendMDOk = async values => {
        await executeStored({
            stored: "UDO_PKG_EQUIPDS.CMFL_SEND_MD",
            args: { NEQUIPDSCM: equipDataSelectionClassMachine, NDATASET_ID: values.dataset ? parseInt(values.dataset) : null }
        });
        setDialogs(pv => ({ ...pv, dataSelectionClassMachineFileSendMD: false }));
        setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 }));
    };

    //При отмене диалога IU модели класса оборудования
    const handleEquipDataSelectionClassMachineModelIUCancel = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineModelIU: false }));

    //При сохранении диалога IU модели класса оборудования
    const handleEquipDataSelectionClassMachineModelIUOk = async values => {
        await executeStored({
            stored: "UDO_PKG_EQUIPDS.CMML_INS",
            args: {
                NPRN: equipDataSelectionClassMachine,
                STASK: values.task,
                NDATASET_ID: values.dataset ? parseInt(values.dataset) : null,
                SUSERPROCS_FRCST_DATA: values.userprocsForecastData
            }
        });
        setDialogs(pv => ({ ...pv, dataSelectionClassMachineModelIU: false }));
        setRefresh(pv => ({ ...pv, dataSelectionClassMachineModelsList: pv.dataSelectionClassMachineModelsList + 1 }));
    };

    //При нажатии "Обучить" в списке моделей карточки класса оборудования
    const handleSendRqEquipDataSelectionClassMachineModel = async equipDSCMML => {
        await executeStored({ stored: "UDO_PKG_EQUIPDS.CMML_SEND_RQ", args: { NEQUIPDSCMML: equipDSCMML } });
        setRefresh(pv => ({ ...pv, dataSelectionClassMachineModelsList: pv.dataSelectionClassMachineModelsList + 1 }));
    };

    //При измении выборки данных через свойства
    useEffect(() => {
        setDataSelection(dataSelection);
        setRefresh(pv => ({ ...pv, dataSelection: pv.dataSelection + 1 }));
    }, [dataSelection]);

    //При изменеии класса оборудования через свойства
    useEffect(() => {
        setDataSelectionClassMachine(dataSelectionClassMachine);
        setRefresh(pv => ({ ...pv, dataSelectionClassMachine: pv.dataSelectionClassMachine + 1 }));
    }, [dataSelectionClassMachine]);

    //Генерация содержимого
    return (
        <Box>
            {dialogs.dataSelectionIU ? (
                <EquipDataSelectionIU onOk={handleEquipDataSelectionIUOk} onCancel={handleEquipDataSelectionIUCancel} />
            ) : null}
            {dialogs.dataSelectionClassMachineIU ? (
                <EquipDataSelectionClassMachineIU
                    classMachine={dialogs.dataSelectionClassMachine}
                    onOk={handleEquipDataSelectionClassMachineIUOk}
                    onCancel={handleEquipDataSelectionClassMachineIUCancel}
                />
            ) : null}
            {dialogs.dataSelectionClassMachineFileSendMD ? (
                <EquipDataSelectionClassMachineFileSendMDDialog
                    classMachine={equipDataSelectionClassMachine}
                    onOk={handleEquipDataSelectionClassMachineFileSendMDOk}
                    onCancel={handleEquipDataSelectionClassMachineFileSendMDCancel}
                />
            ) : null}
            {dialogs.dataSelectionClassMachineModelIU ? (
                <EquipDataSelectionClassMachineModelIU
                    classMachine={equipDataSelectionClassMachine}
                    onOk={handleEquipDataSelectionClassMachineModelIUOk}
                    onCancel={handleEquipDataSelectionClassMachineModelIUCancel}
                />
            ) : null}
            <Grid container>
                {equipDataSelectionListIsLoading ? null : !equipDataSelectionListAccess ? (
                    <Grid item xs={12}>
                        <P8PAppInlineError text="У вас нет прав доступа для обучения моделей. Обратитесь к администратору." />
                    </Grid>
                ) : (
                    <>
                        <Grid item xs={12}>
                            <Stack direction="row" spacing={2} p={2} sx={STYLES.DATA_SELECTION_STACK}>
                                <EquipDataSelectionList
                                    list={equipDataSelectionList}
                                    value={equipDataSelection}
                                    onChange={handleDataSelectionChange}
                                />
                                <Stack direction="row" spacing={0}>
                                    <IconButton onClick={handleAddEquipDataSelection}>
                                        <Icon>add</Icon>
                                    </IconButton>
                                    {equipDataSelection != DS_RN_DEFAULT ? (
                                        <IconButton onClick={handleDeleteEquipDataSelection}>
                                            <Icon>delete</Icon>
                                        </IconButton>
                                    ) : null}
                                </Stack>
                            </Stack>
                        </Grid>
                        <Grid item xs={12}>
                            <Grid container>
                                <Grid item xs={3} hidden={equipDataSelection == DS_RN_DEFAULT}>
                                    <Button
                                        fullWidth
                                        startIcon={<Icon>add</Icon>}
                                        sx={STYLES.CLASS_MACHINE_ADD_BUTTON}
                                        onClick={handleAddEquipDataSelectionClassMachine}
                                    >
                                        Класс
                                    </Button>
                                    <EquipDataSelectionClassMachineList
                                        list={equipDataSelectionClassMachineList}
                                        value={equipDataSelectionClassMachine}
                                        onClick={handleDataSelectionClassMachineClick}
                                    />
                                </Grid>
                                <Grid item xs={9} hidden={equipDataSelectionClassMachine == null}>
                                    <EquipDataSelectionClassMachineCard
                                        card={equipDataSelectionClassMachineCard}
                                        filesList={equipDataSelectionClassMachineFilesList}
                                        modelsList={equipDataSelectionClassMachineModelsList}
                                        onCardEdit={handleEditEquipDataSelectionClassMachine}
                                        onCardDelete={handleDeleteEquipDataSelectionClassMachine}
                                        onClassMachineFilesRefresh={handleRefreshEquipDataSelectionClassMachineFiles}
                                        onClassMachineFilesMake={handleMakeEquipDataSelectionClassMachineFiles}
                                        onClassMachineFilesDelete={handleDeleteEquipDataSelectionClassMachineFiles}
                                        onClassMachineFilesUpload={handleUploadEquipDataSelectionClassMachineFiles}
                                        onClassMachineFilesSendMd={handleSendMdEquipDataSelectionClassMachineFiles}
                                        onClassMachineModelRefresh={handleRefreshEquipDataSelectionClassMachineModel}
                                        onClassMachineModelAdd={handleAddEquipDataSelectionClassMachineModel}
                                        onClassMachineModelDelete={handleDeleteEquipDataSelectionClassMachineModel}
                                        onClassMachineModelSendRq={handleSendRqEquipDataSelectionClassMachineModel}
                                    />
                                </Grid>
                            </Grid>
                        </Grid>
                    </>
                )}
            </Grid>
        </Box>
    );
};

//Контроль свойств - Закладка администрирования
AdminTab.propTypes = {
    dataSelection: PropTypes.number,
    dataSelectionClassMachine: PropTypes.number
};

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

export { AdminTab };
