/*
    Парус 8 - Панели мониторинга - УДП - Доски задач
    Пользовательские хуки: Хуки основных данных
*/

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

import { useState, useContext, useEffect, useCallback } from "react"; //Классы React
import { BackEndCtx } from "../../../context/backend"; //Контекст взаимодействия с сервером
import { getRandomColor, getLocalStorageValue } from "../layouts"; //Вспомогательные функции

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

//Хук дополнительных данных
const useExtraData = filtersType => {
    //Состояние дополнительных данных
    const [extraData, setExtraData] = useState({
        dataLoaded: false,
        reload: false,
        typeLoaded: "",
        evRoutes: [],
        evPoints: [],
        noteTypes: [],
        docLinks: []
    });

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

    //Считывание учётных документов
    const handleDocLinksLoad = useCallback(
        async (type = filtersType) => {
            //Считываем данные
            const data = await executeStored({
                stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_DOCLINKS_GET",
                args: {
                    SEVNTYPE_CODE: type
                },
                isArray: name => name === "XDOCLINKS",
                respArg: "COUT"
            });
            //Возвращаем учётные документы
            return [...(data?.XDOCLINKS || [])];
        },
        [executeStored, filtersType]
    );

    useEffect(() => {
        //Загрузка дополнительных данных
        const loadExtraData = async () => {
            //Считываем данные
            const data = await executeStored({
                stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_GET_INFO_BY_CODE",
                args: {
                    SEVNTYPE_CODE: filtersType
                },
                isArray: name => ["XEVROUTES", "XEVPOINTS", "XNOTETYPES"].includes(name),
                respArg: "COUT"
            });
            //Форматируем типы примечаний под нужный формат
            let noteTypes = [...(data?.XNOTETYPES || [])].reduce((prev, cur) => [...prev, cur.SNAME], []);
            //Считываем учётные документы
            let docLinks = await handleDocLinksLoad(filtersType);
            //Обновляем дополнительные данные
            setExtraData({
                dataLoaded: true,
                reload: false,
                typeLoaded: filtersType,
                evRoutes: [...(data?.XEVROUTES || [])],
                evPoints: [...(data?.XEVPOINTS || [])],
                noteTypes: [...noteTypes],
                docLinks: [...docLinks]
            });
        };

        //Если указан тип событий и необходимо обновить
        if (extraData.reload && filtersType) {
            //Загружаем дополнительные данные
            if (!extraData.typeLoaded || filtersType !== extraData.typeLoaded) {
                loadExtraData();
            }
        }
    }, [executeStored, extraData.reload, extraData.typeLoaded, filtersType, handleDocLinksLoad]);

    return [extraData, setExtraData, handleDocLinksLoad];
};

//Хук заливок пользовательских настроек
const useColorRules = () => {
    //Собственное состояние
    const [colorRules, setColorRules] = useState({
        loaded: false,
        rules: [],
        selectedColorRule: JSON.parse(getLocalStorageValue("settingsColorRule")) || {}
    });

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

    //При необходимости загрузки заливок
    useEffect(() => {
        //Считывание пользовательских настроек
        let getColorRules = async () => {
            //Считываем данные
            const data = await executeStored({
                stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_DP_RULES_GET",
                isArray: name => name === "XRULES",
                respArg: "COUT"
            });
            //Формируем массив правил заливки пользовательских настроек
            let newColorRules = [...(data.XRULES || [])].reduce(
                (prev, cur) => [
                    ...prev,
                    {
                        id: prev.length,
                        SFIELD: cur.SFIELD,
                        SDP_NAME: cur.SDP_NAME,
                        SCOLOR: cur.SCOLOR,
                        STYPE: cur.STYPE,
                        fromValue: cur.NFROM ?? cur.SFROM ?? cur.DFROM,
                        toValue: cur.NTO ?? cur.STO ?? cur.DTO
                    }
                ],
                []
            );
            //Устанавливаем заливки пользовательских настроек
            setColorRules(pv => ({ ...pv, loaded: true, rules: [...newColorRules] }));
        };

        if (!colorRules.loaded) getColorRules();
    }, [colorRules.loaded, executeStored]);

    //Сохранение при закрытии панели
    useEffect(() => {
        //Обработка события закрытия
        const onBeforeUnload = () => {
            localStorage.setItem("settingsColorRule", JSON.stringify(colorRules.selectedColorRule));
        };
        //Вешаем обработчик события закрытия
        window.addEventListener("beforeunload", onBeforeUnload);
        //Очищаем при размонтировании
        return () => {
            window.removeEventListener("beforeunload", onBeforeUnload);
        };
    }, [colorRules.selectedColorRule]);

    return [colorRules, setColorRules];
};

//Хук статусов событий
const useStatuses = filterType => {
    //Собственное состояние статусов
    const [statuses, setStatuses] = useState([]);

    //Состояние статусов
    const [statusesState, setStatusesState] = useState({
        sorted: false,
        reload: true,
        attr: getLocalStorageValue("statusesSortAttr", "SEVNSTAT_NAME"),
        direction: getLocalStorageValue("statusesSortDirection", "asc")
    });

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

    //При необходимости сортировки статусов
    useEffect(() => {
        //Сортируем статусы
        const sortStatuses = unsortedStatuses => {
            //Инициализируем поле сортировки и порядок сортировки
            const attr = statusesState.attr;
            const direction = statusesState.direction;
            //Сортируем
            let sortedStatuses = unsortedStatuses.sort((a, b) =>
                direction === "asc" ? a[attr].localeCompare(b[attr]) : b[attr].localeCompare(a[attr])
            );
            //Возвращаем
            return sortedStatuses;
        };
        //Загружаем и сортируем статусы
        const loadAndSortStatuses = async filterType => {
            //Инициализируем статусы
            let newStatuses = [];
            //Если требуется перезагрузка
            if (statusesState.reload) {
                const loadedStatuses = await executeStored({
                    stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVNSTATS_LOAD",
                    args: {
                        SCLNEVNTYPES: filterType
                    },
                    isArray: name => name === "XSTATUS",
                    respArg: "COUT"
                });
                //Загружаем статусы и инициализируем цвета
                newStatuses = [...(loadedStatuses?.XSTATUS || [])].reduce(
                    (prev, cur) => [...prev, { ...cur, color: getRandomColor(prev.length + 1) }],
                    []
                );
            } else {
                //Загружаем из состояния
                newStatuses = [...statuses];
            }
            //Сортируем, если требуется
            newStatuses = !statusesState.sorted ? sortStatuses(newStatuses) : newStatuses;
            //Обновляем состояние статусов
            setStatuses([...newStatuses]);
            //Обновляем информацию о состоянии статусов
            setStatusesState(pv => ({ ...pv, sorted: true, reload: false }));
        };
        //При необходимости изменения сортировки
        if (filterType && (statusesState.reload || !statusesState.sorted)) {
            //Считываем старые статусы или загружаем новые
            loadAndSortStatuses(filterType);
        }
    }, [executeStored, filterType, statuses, statusesState.attr, statusesState.direction, statusesState.reload, statusesState.sorted]);

    //Сохранение при закрытии панели
    useEffect(() => {
        //Обработка события закрытия
        const onBeforeUnload = () => {
            localStorage.setItem("statusesSortAttr", statusesState.attr);
            localStorage.setItem("statusesSortDirection", statusesState.direction);
        };
        //Вешаем обработчик события закрытия
        window.addEventListener("beforeunload", onBeforeUnload);
        //Очищаем при размонтировании
        return () => {
            window.removeEventListener("beforeunload", onBeforeUnload);
        };
    }, [statusesState.attr, statusesState.direction]);

    return [statuses, statusesState, setStatuses, setStatusesState];
};

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

export { useExtraData, useColorRules, useStatuses };
