/*
    Парус 8 - Панели мониторинга - ПУП - Выдача сменного задания на участок
    Кастомные хуки
*/

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

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

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

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

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

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

//Хук для основной таблицы
const useCostJobs = () => {
    //Собственное состояние - таблица данных
    const [state, setState] = useState({
        init: false,
        loaded: false,
        jobInfo: {},
        haveNote: false,
        coeff: "1.0"
    });

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

    //При подключении компонента к странице
    useEffect(() => {
        const initJob = async fcJob => {
            const data = await executeStored({
                stored: "PKG_P8PANELS_MECHREC.FCJOBS_MP_INIT",
                args: { NFCJOBS: parseInt(fcJob) },
                respArg: "COUT",
                attributeValueProcessor: (name, val) => (["NHAVE_NOTE"].includes(name) ? val == 1 : val)
            });
            setState(pv => ({
                ...pv,
                init: true,
                jobInfo: data.XFCJOBS ? data.XFCJOBS : {},
                loaded: true
            }));
        };
        if (!state.init) {
            //Считаем параметры, переданные из действия
            const actionPrms = getNavigationSearch();
            //Иницализируем сменное задание
            initJob(actionPrms.NRN);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    return [state, setState];
};

//Хук для таблицы операций
const useCostJobsSpecs = task => {
    //Собственное состояние - таблица данных
    const [costJobsSpecs, setCostJobsSpecs] = useState({
        task: null,
        dataLoaded: false,
        columnsDef: [],
        orders: null,
        rows: [],
        selectedRow: {},
        reload: true,
        pageNumber: 1,
        morePages: true,
        fixedHeader: false,
        fixedColumns: 0
    });

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

    //Выдача задания
    const issueCostJobsSpecs = useCallback(
        async prms => {
            try {
                await executeStored({
                    stored: "PKG_P8PANELS_MECHREC.FCJOBSSP_MP_ISSUE",
                    args: { NFCJOBS: prms.NFCJOBS, NCOEFF: parseFloat(prms.NCOEFF) }
                });
            } catch (e) {
                throw new Error(e.message);
            }
        },
        [executeStored]
    );

    //При необходимости обновить данные таблицы
    useEffect(() => {
        //Если изменилось сменное задание - обновляем состояние
        if (costJobsSpecs.dataLoaded && costJobsSpecs.task !== task) {
            setCostJobsSpecs(pv => ({
                ...pv,
                dataLoaded: false,
                columnsDef: [],
                orders: null,
                rows: [],
                selectedRow: {},
                reload: true,
                pageNumber: 1,
                morePages: true
            }));
        }
        //Если необходимо перезагрузить
        if (costJobsSpecs.reload && task) {
            const loadData = async () => {
                const data = await executeStored({
                    stored: "PKG_P8PANELS_MECHREC.FCJOBSSP_MP_DG_GET",
                    args: {
                        NFCJOBS: task,
                        NPAGE_NUMBER: costJobsSpecs.pageNumber,
                        NPAGE_SIZE: DATA_GRID_PAGE_SIZE,
                        CORDERS: { VALUE: object2Base64XML(costJobsSpecs.orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB },
                        NINCLUDE_DEF: costJobsSpecs.dataLoaded ? 0 : 1
                    },
                    respArg: "COUT",
                    attributeValueProcessor: (name, val) =>
                        name === "NSELECT" ? val === 1 : name === "SWORKERS_LIST" ? (val ? val.split(",").map(Number) : []) : val
                });
                setCostJobsSpecs(pv => ({
                    ...pv,
                    ...data.XDATA_GRID,
                    task: task,
                    columnsDef: data.XDATA_GRID.columnsDef ? [...data.XDATA_GRID.columnsDef] : pv.columnsDef,
                    rows: pv.pageNumber == 1 ? [...(data.XDATA_GRID.rows || [])] : [...pv.rows, ...(data.XDATA_GRID.rows || [])],
                    dataLoaded: true,
                    reload: false,
                    morePages: (data.XDATA_GRID.rows || []).length >= DATA_GRID_PAGE_SIZE
                }));
            };
            loadData();
        }
    }, [
        SERV_DATA_TYPE_CLOB,
        costJobsSpecs.dataLoaded,
        costJobsSpecs.orders,
        costJobsSpecs.pageNumber,
        costJobsSpecs.reload,
        costJobsSpecs.task,
        executeStored,
        task
    ]);

    return [costJobsSpecs, setCostJobsSpecs, issueCostJobsSpecs];
};

//Хук для рабочих
const useCostJobsWorkers = task => {
    //Собственное состояние - таблица данных
    const [costJobsWorkers, setCostJobsWorkers] = useState({
        task: null,
        dataLoaded: false,
        columnsDef: [],
        orders: null,
        rows: [],
        selectedRows: [],
        reload: true,
        pageNumber: 1,
        morePages: true
    });

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

    //Включение рабочего в строку сменного задания
    const includeWorker = useCallback(
        async prms => {
            try {
                await executeStored({
                    stored: "PKG_P8PANELS_MECHREC.FCJOBSSP_MP_INC_PERFORM",
                    args: {
                        NFCJOBSSP: prms.NFCJOBSSP,
                        SPERFORM_LIST: {
                            VALUE: Array.isArray(prms.SELECTED_WORKERS) ? prms.SELECTED_WORKERS.join(";") : prms.SELECTED_WORKERS,
                            SDATA_TYPE: SERV_DATA_TYPE_CLOB
                        },
                        NQUANT_PLAN: prms.NQUANT_PLAN
                    }
                });
            } catch (e) {
                throw new Error(e.message);
            }
        },
        [SERV_DATA_TYPE_CLOB, executeStored]
    );

    //Исключение рабочего из строки сменного задания
    const excludeWorker = useCallback(
        async prms => {
            try {
                await executeStored({
                    stored: "PKG_P8PANELS_MECHREC.FCJOBSSP_MP_EXC_PERFORM",
                    args: { NFCJOBSSP: prms.NFCJOBSSP }
                });
            } catch (e) {
                throw new Error(e.message);
            }
        },
        [executeStored]
    );

    //При необходимости обновить данные таблицы
    useEffect(() => {
        //Если изменилось сменное задание - обновляем состояние
        if (costJobsWorkers.dataLoaded && costJobsWorkers.task !== task) {
            setCostJobsWorkers(pv => ({
                ...pv,
                dataLoaded: false,
                columnsDef: [],
                orders: null,
                rows: [],
                selectedRows: [],
                reload: true,
                pageNumber: 1,
                morePages: true
            }));
        }
        //Если необходимо перезагрузить
        if (costJobsWorkers.reload && task) {
            const loadData = async () => {
                const data = await executeStored({
                    stored: "PKG_P8PANELS_MECHREC.WORKERS_MP_DG_GET",
                    args: {
                        NFCJOBS: task,
                        NPAGE_NUMBER: costJobsWorkers.pageNumber,
                        NPAGE_SIZE: DATA_GRID_PAGE_SIZE,
                        CORDERS: { VALUE: object2Base64XML(costJobsWorkers.orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB },
                        NINCLUDE_DEF: costJobsWorkers.dataLoaded ? 0 : 1
                    },
                    respArg: "COUT",
                    attributeValueProcessor: (name, val) => (["NSELECT"].includes(name) ? val === 1 : val)
                });
                setCostJobsWorkers(pv => ({
                    ...pv,
                    ...data.XDATA_GRID,
                    task: task,
                    columnsDef: data.XDATA_GRID.columnsDef ? [...data.XDATA_GRID.columnsDef] : pv.columnsDef,
                    rows: pv.pageNumber == 1 ? [...(data.XDATA_GRID.rows || [])] : [...pv.rows, ...(data.XDATA_GRID.rows || [])],
                    dataLoaded: true,
                    reload: false,
                    morePages: (data.XDATA_GRID.rows || []).length >= DATA_GRID_PAGE_SIZE
                }));
            };
            loadData();
        }
    }, [
        SERV_DATA_TYPE_CLOB,
        costJobsWorkers.dataLoaded,
        costJobsWorkers.orders,
        costJobsWorkers.pageNumber,
        costJobsWorkers.reload,
        costJobsWorkers.task,
        executeStored,
        task
    ]);

    return [costJobsWorkers, setCostJobsWorkers, includeWorker, excludeWorker];
};

export { useCostJobs, useCostJobsSpecs, useCostJobsWorkers };
