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

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

import { useState, useEffect, useContext } from "react"; //Классы React
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { deepCopyObject, object2Base64XML } from "../../core/utils"; //Вспомогательные функции

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

//Размер страницы данных
const DATA_GRID_PAGE_SIZE = 50;

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

//Поиск элемента в дереве
const findTreeItem = (tree, id) => {
    for (let i = 0; i < tree.length; i++) {
        if (tree[i].id == id) return tree[i];
        if (Array.isArray(tree[i].children)) {
            let childRes = findTreeItem(tree[i].children, id);
            if (childRes) return childRes;
        }
    }
};

//Проверка необходимости загрузки уровня для указанного родителя
const needLoadLevel = (tree, parent) => {
    let item = findTreeItem(tree, parent);
    return !item ? false : item.children && item.children.length == 1 && item.children[0].id.endsWith("loader") ? true : false;
};

//Встраивание уровня в указанного родителя
const appendLevel = (tree, parent, children) => {
    let item = findTreeItem(tree, parent);
    if (item) item.children = children;
};

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

//Загрузка ветки дерева состава оборудования
const useEqConfigTree = parent => {
    //Собственное состояние - флаг загрузки
    const [isLoading, setLoading] = useState(false);

    //Собственное состояние - данные дерева
    const [tree, setTree] = useState([]);

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

    //Загрузка данных при изменении зависимостей
    useEffect(() => {
        const loadData = async () => {
            try {
                setLoading(true);
                const data = await executeStored({
                    stored: "UDO_PKG_EQUIPTCF.EQCONFIG_HIER",
                    args: {
                        NEQPARENT: parent
                    },
                    respArg: "COUT",
                    isArray: name => ["children"].includes(name),
                    attributeValueProcessor: (name, val) => (["id"].includes(name) ? undefined : val),
                    loader: false
                });
                setTree(prevTree => {
                    if (prevTree.length == 0) return data.children;
                    else {
                        let newTree = deepCopyObject(prevTree);
                        appendLevel(newTree, parent, data.children);
                        return newTree;
                    }
                });
            } finally {
                setLoading(false);
            }
        };
        if (parent == 0 || parent) loadData();
    }, [parent, executeStored]);

    //Вернём данные
    return { eQconfigTree: tree, eQconfigTreeIsLoading: isLoading };
};

//Загрузка списка технических объектов
const useEqConfigTechObjTable = (parent, filters, orders, pageNumber, refresh) => {
    //Собственное состояние - флаг загрузки
    const [isLoading, setLoading] = useState(false);

    //Собственное состояние - таблица данных
    const [data, setData] = useState({
        init: false,
        columnsDef: [],
        rows: [],
        morePages: true
    });

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

    //Загрузка данных при изменении зависимостей
    useEffect(() => {
        const loadData = async () => {
            try {
                setLoading(true);
                const data = await executeStored({
                    stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_LIST",
                    args: {
                        NEQPARENT: parent,
                        CFILTERS: { VALUE: object2Base64XML(filters, { arrayNodeName: "filters" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB },
                        CORDERS: { VALUE: object2Base64XML(orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB },
                        NPAGE_NUMBER: pageNumber,
                        NPAGE_SIZE: DATA_GRID_PAGE_SIZE,
                        NINCLUDE_DEF: pageNumber == 1 ? 1 : 0
                    },
                    respArg: "COUT",
                    loader: true
                });
                setData(pv => ({
                    ...pv,
                    columnsDef: data.XDATA_GRID.columnsDef ? [...data.XDATA_GRID.columnsDef] : pv.columnsDef,
                    rows: pageNumber == 1 ? [...(data.XDATA_GRID.rows || [])] : [...pv.rows, ...(data.XDATA_GRID.rows || [])],
                    morePages: DATA_GRID_PAGE_SIZE == 0 ? false : (data.XDATA_GRID.rows || []).length >= DATA_GRID_PAGE_SIZE,
                    init: true
                }));
            } finally {
                setLoading(false);
            }
        };
        if (parent) loadData();
    }, [parent, filters, orders, pageNumber, refresh, executeStored, SERV_DATA_TYPE_CLOB]);

    //Вернём данные
    return { techObjsDataGrid: data, techObjsDataGridIsLoading: isLoading };
};

//Загрузка карточки технического объекта
const useEqConfigTechObjCard = (id, refresh) => {
    //Собственное состояние - флаг загрузки
    const [isLoading, setLoading] = useState(false);

    //Собственное состояние - данные карточки
    const [card, setCard] = useState({});

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

    //Загрузка данных при изменении зависимостей
    useEffect(() => {
        const loadData = async () => {
            try {
                setLoading(true);
                const data = await executeStored({
                    stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_CARD",
                    args: { NEQCONFIG: id },
                    respArg: "COUT",
                    loader: true
                });
                setCard(data.techObj ? data.techObj : {});
            } finally {
                setLoading(false);
            }
        };
        if (id) loadData();
    }, [id, refresh, executeStored]);

    //Вернём данные
    return { techObjCard: card, techObjCardIsLoading: isLoading };
};

//Загрузка списка моделей единицы оборудования
const useTechObjModelsList = (id, refresh) => {
    //Собственное состояние - флаг загрузки
    const [isLoading, setLoading] = useState(false);

    //Собственное состояние - таблица данных
    const [data, setData] = useState({
        init: false,
        columnsDef: [],
        rows: []
    });

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

    //Загрузка данных при изменении зависимостей
    useEffect(() => {
        const loadData = async () => {
            try {
                setLoading(true);
                const data = await executeStored({
                    stored: "UDO_PKG_EQUIPDS.CMML_LIST_BY_EQCONFIG",
                    args: { NEQCONFIG: id },
                    respArg: "COUT",
                    loader: false
                });
                setData(pv => ({
                    ...pv,
                    columnsDef: [...data.XDATA_GRID.columnsDef],
                    rows: [...(data.XDATA_GRID.rows || [])],
                    init: true
                }));
            } finally {
                setLoading(false);
            }
        };
        if (id) loadData();
    }, [id, refresh, executeStored]);

    //Вернём данные
    return { techObjModelsList: data, techObjModelsListIsLoading: isLoading };
};

//Загрузка истории запросов к модели единицы оборудования
const useTechObjForecastHistList = (id, refresh) => {
    //Собственное состояние - флаг загрузки
    const [isLoading, setLoading] = useState(false);

    //Собственное состояние - таблица данных
    const [data, setData] = useState({
        init: false,
        columnsDef: [],
        rows: []
    });

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

    //Загрузка данных при изменении зависимостей
    useEffect(() => {
        const loadData = async () => {
            try {
                setLoading(true);
                const data = await executeStored({
                    stored: "UDO_PKG_EQUIPDS.CMMLH_LIST_BY_EQCONFIG",
                    args: { NEQCONFIG: id },
                    respArg: "COUT",
                    loader: false
                });
                setData(pv => ({
                    ...pv,
                    columnsDef: [...data.XDATA_GRID.columnsDef],
                    rows: [...(data.XDATA_GRID.rows || [])],
                    init: true
                }));
            } finally {
                setLoading(false);
            }
        };
        if (id) loadData();
    }, [id, refresh, executeStored]);

    //Вернём данные
    return { techObjForecastHistList: data, techObjForecastHistListIsLoading: isLoading };
};

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

export {
    useEqConfigTree,
    useEqConfigTechObjTable,
    useEqConfigTechObjCard,
    findTreeItem,
    needLoadLevel,
    useTechObjModelsList,
    useTechObjForecastHistList
};
