/*
    Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта
    Компонент панели: Разделы настройки
*/

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

import React, { useState, useEffect, useContext, useCallback } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Box, Tabs, IconButton, Icon, Stack, Button } from "@mui/material"; //Интерфейсные компоненты
import { tabsClasses } from "@mui/material/Tabs"; //Классы закладок
import { ApplicationCtx } from "../../../context/application"; //Контекст взаимодействия с приложением
import { BackEndCtx } from "../../../context/backend"; //Контекст взаимодействия с сервером
import { MessagingCtx } from "../../../context/messaging"; //Контекст сообщений
import { useConfSections } from "../hooks"; //Кастомные хуки
import { ActionMessage } from "./action_message"; //Сообщение с действиями
import { SectionTab } from "./section_tab"; //Закладка раздела
import { DialogSectionIU } from "./dialog_section_iu"; //Диалог добавления/исправления раздела

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

//Стили
const STYLES = {
    CONTAINER: { borderBottom: 1, borderColor: "divider", width: "100%", height: "100%" },
    TABS_SECTIONS: { width: "100%", [`& .${tabsClasses.scrollButtons}`]: { "&.Mui-disabled": { opacity: 0.3 } } }
};

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

//Поиск активного раздела после удаления текущего
const getNextSectionAfterDelete = (sections, deletedSection) => {
    //Находим индекс удаляемого раздела
    const delInd = sections.findIndex(s => s.NRN === deletedSection);
    //Возвращаем рег. номер либо предыдущего раздела, либо следующего, либо ничего
    return delInd === -1 ? null : sections[delInd - 1]?.NRN || sections[delInd + 1]?.NRN || null;
};

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

//Разделы настройки
const Sections = ({ conf, onSectionChange, onSectionCountChange }) => {
    //Текущий раздел настройки
    const [section, setSection] = useState(-1);

    //Редактируемый раздел настройки
    const [modSection, setModSection] = useState(null);

    //Список разделов и просто описание настройки
    const [confDesc, sections, refreshSections, sectionsLoading, sectionsInit] = useConfSections(conf);

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

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

    //Подключение к контексту сообщений
    const { showMsgWarn } = useContext(MessagingCtx);

    //Выбор раздела
    const selectSection = useCallback(
        section => {
            if (onSectionChange) onSectionChange(section);
            setSection(section);
        },
        [onSectionChange]
    );

    //Добавление раздела
    const insertSection = async ({ conf, code, name }) => {
        const data = await executeStored({
            stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_INSERT",
            args: { NPRN: conf, SCODE: code, SNAME: name },
            loader: false
        });
        selectSection(data.NRN);
        refreshSections();
    };

    //Исправление раздела
    const updateSection = async ({ rn, code, name }) => {
        await executeStored({
            stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_UPDATE",
            args: { NRN: rn, SCODE: code, SNAME: name },
            loader: false
        });
        refreshSections();
    };

    //Удаление раздела
    const deleteSection = async section => {
        await executeStored({
            stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_DELETE",
            args: { NRN: section },
            loader: false
        });
        selectSection(getNextSectionAfterDelete(sections, section));
        refreshSections();
    };

    //При измении закладки текущего раздела
    const handleSectionTabChange = (event, section) => selectSection(section);

    //При добавлении раздела настройки
    const handleSectionAdd = () => setModSection(true);

    //При редактировании раздела настройки
    const handleSectionEdit = section => setModSection(sections.find(s => s.NRN === section) || null);

    //При удалении раздела настройки
    const handleSectionDelete = section => showMsgWarn("Удалить раздел?", () => deleteSection(section));

    //При закрытии диалога добавления/исправления по "ОК"
    const handleIUDialogOk = async values => {
        if (modSection === true) await insertSection({ conf, ...values });
        else await updateSection({ rn: modSection.NRN, ...values });
        setModSection(null);
    };

    //При закрытии диалога добавления/исправления по "Отмена"
    const handleIUDialogCancel = () => setModSection(null);

    //При изменении состава разделов
    useEffect(() => {
        //Если ещё не инициализировали выбранный раздел и есть чем
        if (section === -1 && sections.length > 0) selectSection(sections[0].NRN);
    }, [section, sections, selectSection]);

    //При изменении количества разделов
    useEffect(() => {
        onSectionCountChange && onSectionCountChange(sections.length);
    }, [sections.length, onSectionCountChange]);

    //При изменении описания раздела
    useEffect(() => {
        if (confDesc?.SNAME) setAppBarTitle(confDesc.SNAME);
    }, [confDesc, setAppBarTitle]);

    //Вычисление подсвеченной закладки раздела
    const hlSection = sections.find(s => s.NRN === section)?.NRN || false;

    //Формирование представления
    return (
        <Stack direction={"row"} sx={STYLES.CONTAINER}>
            {modSection && (
                <DialogSectionIU
                    code={modSection?.SCODE}
                    name={modSection?.SNAME}
                    insert={modSection === true}
                    onOk={handleIUDialogOk}
                    onCancel={handleIUDialogCancel}
                />
            )}
            {sections.length > 0 ? (
                <>
                    <Box display={"flex"} justifyContent={"center"} alignItems={"center"} sx={STYLES.PANELS_MAIN_COLOR} title={"Добавить раздел"}>
                        <IconButton onClick={handleSectionAdd}>
                            <Icon>add</Icon>
                        </IconButton>
                    </Box>
                    <Tabs value={hlSection} onChange={handleSectionTabChange} variant={"scrollable"} scrollButtons sx={STYLES.TABS_SECTIONS}>
                        {sections.map((s, i) => (
                            <SectionTab
                                key={i}
                                value={s.NRN}
                                section={section}
                                sectionDesc={s}
                                onSectionEdit={handleSectionEdit}
                                onSectionDelete={handleSectionDelete}
                            />
                        ))}
                    </Tabs>
                </>
            ) : (
                sectionsInit &&
                !sectionsLoading && (
                    <ActionMessage icon={"info"} title={"В настройке нет разделов"} desc={"Добавьте первый..."}>
                        <Button startIcon={<Icon>add</Icon>} onClick={handleSectionAdd}>
                            Раздел
                        </Button>
                    </ActionMessage>
                )
            )}
        </Stack>
    );
};

//Контроль свойств - Разделы настройки
Sections.propTypes = {
    conf: PropTypes.number,
    onSectionChange: PropTypes.func,
    onSectionCountChange: PropTypes.func
};

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

export { Sections };
