/*
    Парус 8 - Панели мониторинга - УДП - Доски задач
    Компонент панели: Диалог формы события
*/

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

import React, { useState, useCallback, useContext, useEffect } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { useClientEvent } from "./hooks/task_dialog_hooks"; //Хук для события
import { useDocsProps } from "./hooks/task_dialog_hooks"; //Хук для получения доп. свойств раздела "События"
import { TaskForm } from "./components/task_form"; //Форма события
import { BackEndCtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { object2Base64XML } from "../../core/utils"; //Вспомогательные функции
import { hasValue } from "../../core/utils"; //Вспомогательные процедуры и функции
import { P8PDialog } from "../../components/p8p_dialog"; //Типовой диалог

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

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

//Диалог формы события
const TaskDialog = ({ taskRn, taskType, editable, onTasksReload, onClose }) => {
    //Собственное состояние
    const [task, setTask] = useClientEvent(taskRn, taskType);

    //Состояние допустимых дополнительных свойств
    const [docProps] = useDocsProps(taskType);

    //Состояние заполненности всех обязательных доп. свойств
    const [docPropsReady, setDocPropsReady] = useState(false);

    //Подключение к контексту взаимодействия с сервером
    const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndCtx);

    //При изменении информации о задаче
    const handleTaskChange = useCallback(
        newTaskValues => {
            setTask(pv => ({ ...pv, ...newTaskValues }));
        },
        [setTask]
    );

    //При добавлении события
    const handleInsertTask = async callBack => {
        await executeStored({
            stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_INSERT",
            args: {
                SCRN: task.sCrn,
                SPREF: task.sPrefix,
                SNUMB: task.sNumber,
                STYPE: task.sType,
                SSTATUS: task.sStatus,
                SPLAN_DATE: task.dPlanDate,
                SINIT_PERSON: task.sInitClnperson,
                SCLIENT_CLIENT: task.sClntClients,
                SCLIENT_PERSON: task.sClntClnperson,
                SDESCRIPTION: task.sDescription,
                SREASON: task.sInitReason,
                CPROPS: {
                    VALUE: object2Base64XML(
                        [
                            Object.fromEntries(
                                Object.entries(task.docProps)
                                    // eslint-disable-next-line no-unused-vars
                                    .filter(([_, v]) => v != (null || ""))
                            )
                        ],
                        {
                            arrayNodeName: "props"
                        }
                    ),
                    SDATA_TYPE: SERV_DATA_TYPE_CLOB
                }
            }
        });
        callBack();
    };

    //При исправлении события
    const handleUpdateEvent = async callBack => {
        await executeStored({
            stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_UPDATE",
            args: {
                NCLNEVENTS: task.nRn,
                SCLIENT_CLIENT: task.sClntClients,
                SCLIENT_PERSON: task.sClntClnperson,
                SDESCRIPTION: task.sDescription,
                CPROPS: {
                    // eslint-disable-next-line no-unused-vars
                    VALUE: object2Base64XML([Object.fromEntries(Object.entries(task.docProps).filter(([_, v]) => v != (null || "")))], {
                        arrayNodeName: "props"
                    }),
                    SDATA_TYPE: SERV_DATA_TYPE_CLOB
                }
            }
        });
        callBack();
    };

    //При считывании следующего номера события
    const handleEventNextNumbGet = useCallback(async () => {
        //Считываем данные
        const data = await executeStored({
            stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_NEXTNUMB_GET",
            args: {
                SPREFIX: task.sPrefix
            }
        });
        //Если данные есть
        if (data) {
            //Устанавливаем номер
            setTask(pv => ({ ...pv, sNumber: data.SEVENT_NUMB }));
        }
    }, [executeStored, setTask, task.sPrefix]);

    //Проверка заполненности всех обязательных доп. свойств
    useEffect(() => {
        //Если доп. свойства загрузились
        if (docProps.loaded) {
            //Проверяем остались ли обязательные незаполненные свойства
            let notFilled = docProps.props.some(docProp => docProp.BREQUIRE === true && !hasValue(task.docProps[docProp.SFORMATTED_ID]));
            //Если незаполненных обязательных доп. свойств не осталось - доп. свойства готовы, иначе не готовы
            setDocPropsReady(!notFilled);
        } else {
            //Доп. свойства не готовы
            setDocPropsReady(false);
        }
    }, [docProps.loaded, docProps.props, task.docProps]);

    //Генерация содержимого
    return (
        <>
            {!task.init && docProps.loaded && (
                <P8PDialog
                    title={task.nRn ? `Исправление события${task.nClosed ? " [аннулировано]" : ""}` : "Добавление события"}
                    fullWidth={true}
                    onOk={() => (taskRn ? handleUpdateEvent(onClose).then(onTasksReload) : handleInsertTask(onClose).then(onTasksReload))}
                    onClose={onClose ? onClose : null}
                    okDisabled={taskRn ? task.updateDisabled || !editable || !docPropsReady : task.insertDisabled || !docPropsReady}
                    scrollContent={false}
                >
                    <TaskForm
                        task={task}
                        taskType={taskType}
                        editable={!taskRn || editable ? true : false}
                        docProps={docProps.props}
                        onTaskChange={handleTaskChange}
                        onEventNextNumbGet={handleEventNextNumbGet}
                    />
                </P8PDialog>
            )}
        </>
    );
};

//Контроль свойств - Диалог формы события
TaskDialog.propTypes = {
    taskRn: PropTypes.number,
    taskType: PropTypes.string.isRequired,
    editable: PropTypes.bool,
    onTasksReload: PropTypes.func.isRequired,
    onClose: PropTypes.func.isRequired
};

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

export { TaskDialog };
