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

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

import React, { useState, useContext } from "react"; //Классы React
import { Box, Grid } from "@mui/material"; //Интерфейсные компоненты MUI
import { ApplicationCtx } from "../../context/application"; //Контекст взаимодействия с приложением
import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Компоненты рабочего стола
import { P8PEditorToolBar } from "../../components/editors/p8p_editor_toolbar"; //Панель инструментов редактора
import { QueryDiagram } from "./components/query_diagram/query_diagram"; //Диаграмма запроса
import { Inspector } from "./components/inspector/inspector"; //Инспектор свойств
import { QueriesManager } from "./components/queries_manager/queries_manager"; //Менеджер запросов
import { useQuery } from "./hooks"; //Хуки для работы с метаданными запроса на сервере
import { useQueryRelations } from "./components/inspector_query_rls/hooks"; //Хуки для работы со связями запроса на сервере
import { useQueryEntities } from "./components/inspector_query_ents/hooks"; //Хуки для работы с сущностями запроса на сервере

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

//Заголовок панели по умолчанию
const APP_BAR_TITLE_DEFAULT = "Редактор запросов";

//Стили
const STYLES = {
    CONTAINER: { display: "flex" },
    GRID_CONTAINER: { height: `calc(100vh - ${APP_BAR_HEIGHT})` },
    GRID_ITEM_INSPECTOR: { backgroundColor: "#e9ecef" }
};

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

//Корневой компонент редактора запросов
const QueryEditor = () => {
    //Текущий запрос
    const [query, setQuery] = useState(null);

    //Текущая сущность
    const [entity, setEntity] = useState(null);

    //Текущая связь
    const [relation, setRelation] = useState(null);

    //Отображения менеджера запросов
    const [openQueriesManager, setOpenQueriesManager] = useState(true);

    //Получение метаданных с описанием запроса
    const [queryDiagram, queryOption, querySQL, doRefresh] = useQuery(query);

    //Работа с сущностями на сервере
    const { removeEnt, setEntPosition } = useQueryEntities(query);

    //Работа со связями на сервере
    const { addRl, removeRl } = useQueryRelations(query);

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

    //Выбор сущности
    const selectEntity = ent => {
        setRelation(null);
        const queryEnt = queryDiagram.entities.find(e => e.id === ent);
        if (queryEnt) setEntity({ ...queryEnt });
    };

    //Выбор связи
    const selectRelation = rl => {
        setEntity(null);
        const queryRl = queryDiagram.relations.find(r => r.id === rl);
        if (queryRl) setRelation({ ...queryRl });
    };

    //Сброс выбора связи и сущности
    const cleanupEnRlSelection = () => {
        setRelation(null);
        setEntity(null);
    };

    //Обработка изменения положения сущности на диаграмме
    const handleEntityPositionChange = (ent, position) => setEntPosition(ent, position.x, position.y);

    //Обработка удаления сущности из запроса
    const handleEntityRemove = async ent => {
        await removeEnt(ent);
        if (entity && entity?.id === ent) cleanupEnRlSelection();
        doRefresh();
    };

    //Обработка выделения сущности
    const handleEntityClick = ent => selectEntity(ent);

    //Обработка выделения тарибута сущности
    const handleEntityAttrClick = ent => selectEntity(ent);

    //Обработка выделения связи
    const handleRelationClick = rl => selectRelation(rl);

    //Обработка добавления отношения cущностей
    const handleRelationAdd = async (source, target) => {
        cleanupEnRlSelection();
        await addRl(source, target);
        doRefresh();
    };

    //Обработка удаления отношения cущностей
    const handleRelationRemove = async rl => {
        await removeRl(rl);
        if (relation && relation?.id === rl) cleanupEnRlSelection();
        doRefresh();
    };

    //При нажатии на панели (пустом месте) диаграммы запроса
    const handlePaneClick = () => cleanupEnRlSelection();

    //Открытие менеджера запросов
    const handleOpenQueriesManager = () => setOpenQueriesManager(true);

    //Закрытие менеджера запросов
    const handleCancelQueriesManager = () => setOpenQueriesManager(false);

    //Закрытие запроса
    const handleQueryClose = () => {
        setAppBarTitle(APP_BAR_TITLE_DEFAULT);
        cleanupEnRlSelection();
        setQuery(null);
    };

    //При выборе запроса
    const handleQuerySelect = ({ rn, name }) => {
        setAppBarTitle(`Запрос [${name}]`);
        setQuery(rn);
        setOpenQueriesManager(false);
        cleanupEnRlSelection();
    };

    //При изменении свойств запроса
    const handleQueryOptionsChanged = () => {
        cleanupEnRlSelection();
        doRefresh();
    };

    //Панель инструмментов
    const toolBar = (
        <P8PEditorToolBar
            items={[
                { icon: "file_open", title: "Менеджер запросов", onClick: handleOpenQueriesManager },
                { icon: "close", title: "Закрыть запрос", onClick: handleQueryClose, disabled: !query }
            ]}
        />
    );

    //Генерация содержимого
    return (
        <Box sx={STYLES.CONTAINER}>
            {openQueriesManager && <QueriesManager current={query} onQuerySelect={handleQuerySelect} onCancel={handleCancelQueriesManager} />}
            <Grid container sx={STYLES.GRID_CONTAINER} columns={25}>
                <Grid item xs={20}>
                    {queryDiagram && (
                        <QueryDiagram
                            nodes={queryDiagram?.nodes}
                            edges={queryDiagram?.edges}
                            onEntityClick={handleEntityClick}
                            onEntityAttrClick={handleEntityAttrClick}
                            onEntityPositionChange={handleEntityPositionChange}
                            onEntityRemove={handleEntityRemove}
                            onRelactionClick={handleRelationClick}
                            onRelationAdd={handleRelationAdd}
                            onRelationRemove={handleRelationRemove}
                            onPaneClick={handlePaneClick}
                        />
                    )}
                </Grid>
                <Grid item xs={5} sx={STYLES.GRID_ITEM_INSPECTOR}>
                    {toolBar}
                    {query && (
                        <Inspector
                            {...queryOption}
                            {...querySQL}
                            query={query}
                            entity={entity}
                            relation={relation}
                            entities={queryDiagram?.entities}
                            onOptionsChanged={handleQueryOptionsChanged}
                        />
                    )}
                </Grid>
            </Grid>
        </Box>
    );
};

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

export { QueryEditor };
