/*
    Парус 8 - Панели мониторинга - ПУП - Работы проектов
    Панель мониторинга: Корневая панель работ проектов
*/
//---------------------
//Подключение библиотек
//---------------------
import React, { useContext, useState, useCallback, useEffect } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import {
    Drawer,
    Fab,
    Box,
    Grid,
    List,
    ListItemButton,
    ListItemText,
    ListItemIcon,
    Icon,
    Typography,
    Divider,
    ListItem,
    Button,
    Dialog,
    DialogContent,
    DialogActions,
    TextField,
    DialogTitle
} from "@mui/material"; //Интерфейсные элементы
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений
import { ApplicationСtx } from "../../context/application"; //Контекст приложения
import { formatDateJSONDateOnly } from "../../core/utils"; //Вспомогательные функции
import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Заголовок страницы
import { APP_STYLES } from "../../../app.styles"; //Типовые стили
import { P8P_GANTT_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
import { P8PGantt } from "../../components/p8p_gantt"; //Диаграмма Ганта
import { formatDateRF } from "../../core/utils"; //Вспомогательные функции
import { BUTTONS } from "../../../app.text"; //Текстовые ресурсы и константы
import { ResMon } from "./res_mon"; //Монитор ресурсов
import { taskAttributeRenderer } from "./layouts"; //Дополнительная разметка и вёрстка клиентских элементов
//---------
//Константы
//---------
//Стили
const STYLES = {
    PROJECTS_LIST_ITEM_NOJOBS: { backgroundColor: "#ff000045" },
    PROJECTS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
    PROJECTS_LIST_ITEM_SECONDARY: { wordWrap: "break-word", fontSize: "0.5rem", textTransform: "uppercase" },
    PROJECTS_LIST_ITEM_SECONDARY_NOJOBS: { color: "red" },
    PROJECTS_LIST_ITEM_SECONDARY_NOEDIT: { color: "gray" },
    PROJECTS_LIST_ITEM_SECONDARY_CHANGED: { color: "green" },
    PROJECTS_BUTTON: { position: "absolute", top: `calc(${APP_BAR_HEIGHT} + 16px)`, left: "16px" },
    PROJECTS_DRAWER: { width: "250px", flexShrink: 0, [`& .MuiDrawer-paper`]: { width: "250px", boxSizing: "border-box", ...APP_STYLES.SCROLL } },
    GANTT_CONTAINER: { height: `calc(100vh - ${APP_BAR_HEIGHT})`, width: "100vw", paddingTop: "24px" },
    GANTT_TITLE: { paddingLeft: "150px", paddingRight: "150px" },
    PERIODS_BUTTON: { position: "absolute", top: `calc(${APP_BAR_HEIGHT} + 16px)`, right: "16px" },
    PERIODS_DRAWER: { width: "1200px", flexShrink: 0, [`& .MuiDrawer-paper`]: { width: "1200px", boxSizing: "border-box", ...APP_STYLES.SCROLL } }
};
//------------------------------------
//Вспомогательные функции и компоненты
//------------------------------------
//Диалог параметров инициализации панели
const InitPrmsDialog = ({ dateBegin, dateFact, onOk, onCancel }) => {
    //Собственное состояние - значения с-по
    const [values, setValues] = useState({ dateBegin: formatDateJSONDateOnly(dateBegin), dateFact: formatDateJSONDateOnly(dateFact) });
    //Отработка воода значения в фильтр
    const handleValueTextFieldChanged = e => setValues(prev => ({ ...prev, [e.target.name]: e.target.value }));
    //Генерация содержимого
    return (
        
    );
};
//Контроль свойств - Диалог параметров инициализации панели
InitPrmsDialog.propTypes = {
    dateBegin: PropTypes.instanceOf(Date).isRequired,
    dateFact: PropTypes.instanceOf(Date).isRequired,
    onOk: PropTypes.func,
    onCancel: PropTypes.func
};
//Область параметров инициализации панели
const InitPrmsArea = ({ dateBegin, dateFact, durationMeasCode, labMeasCode, onClick }) => {
    return (
        
            
                
                            Начало: 
                            {formatDateRF(dateBegin)}
                            
                            Факт на: 
                            {formatDateRF(dateFact)}
                            
                            Длительность: 
                            {durationMeasCode}
                            
                            Трудоёмкость: 
                            {labMeasCode}
                        >
                    }
                />
            
            
                
            
        
);
};
//Контроль свойств - Область параметров инициализации панели
InitPrmsArea.propTypes = {
    dateBegin: PropTypes.instanceOf(Date),
    dateFact: PropTypes.instanceOf(Date),
    durationMeasCode: PropTypes.string,
    labMeasCode: PropTypes.string,
    onClick: PropTypes.func
};
//Область сохранения изменений
const SaveChangesArea = ({ onClick }) => {
    return (
            
                
            
        
);
};
//Контроль свойств - Область сохранения изменений
SaveChangesArea.propTypes = {
    onClick: PropTypes.func
};
//Список проектов
const ProjectsList = ({ projects = [], selectedProject, onClick } = {}) => {
    //Подключение к контексту сообщений
    const { InlineMsgErr } = useContext(MessagingСtx);
    //Генерация содержимого
    return projects.length > 0 ? (
            {projects.map(p => (
                 (onClick ? onClick(p) : null)}
                >
                    
                        
                            {p.NEDITABLE == 1 ? "edit" : "edit_off"}
                        
                    
                    {p.SNAME}}
                        secondary={
                            
                                {p.NJOBS == 1
                                    ? p.NEDITABLE == 1
                                        ? p.NCHANGED == 1
                                            ? "Изменён"
                                            : "Не изменён"
                                        : "Редактирование недоступно"
                                    : "Работы не определены"}
                            
                        }
                    />
                
            ))}
        
) : (
        
    );
};
//Контроль свойств - Список проектов
ProjectsList.propTypes = {
    projects: PropTypes.array,
    selectedProject: PropTypes.number,
    onClick: PropTypes.func
};
//-----------
//Тело модуля
//-----------
//Корневая панель работ проектов
const PrjJobs = () => {
    //Собственное состояние
    let [state, setState] = useState({
        needSave: false,
        showProjectsList: false,
        showPeriodsList: false,
        init: false,
        dateBegin: null,
        dateFact: null,
        durationMeas: null,
        durationMeasCode: null,
        labMeas: null,
        labMeasCode: null,
        resourceStatus: null,
        ident: null,
        projects: [],
        projectsLoaded: false,
        selectedProjectJobsLoaded: false,
        selectedProject: null,
        selectedProjectDocRn: null,
        gantt: {},
        showInitDialog: false
    });
    //Подключение к контексту приложения
    const { pOnlineShowDocument } = useContext(ApplicationСtx);
    //Подключение к контексту сообщений
    const { InlineMsgInfo } = useContext(MessagingСtx);
    //Подключение к контексту взаимодействия с сервером
    const { executeStored } = useContext(BackEndСtx);
    //Загрузка списка проектов
    const loadProjects = useCallback(
        async (force = false) => {
            if (!state.projectsLoaded || force) {
                const data = await executeStored({
                    stored: "PKG_P8PANELS_PROJECTS.JB_PRJCTS_LIST",
                    args: { NIDENT: state.ident },
                    respArg: "COUT",
                    isArray: name => name === "XPROJECTS"
                });
                setState(pv => ({ ...pv, projectsLoaded: true, projects: [...(data?.XPROJECTS || [])] }));
            }
        },
        [executeStored, state.ident, state.projectsLoaded]
    );
    //Загрузка списка работ проекта
    const loadProjectJobs = useCallback(
        async (tasksOnly = false) => {
            const data = await executeStored({
                stored: "PKG_P8PANELS_PROJECTS.JB_JOBS_LIST",
                args: { NIDENT: state.ident, NPRN: state.selectedProject, NINCLUDE_DEF: tasksOnly === false ? 1 : 0 },
                attributeValueProcessor: (name, val) =>
                    name == "numb" ? undefined : ["start", "end"].includes(name) ? formatDateJSONDateOnly(val) : val,
                respArg: "COUT"
            });
            setState(pv => ({
                ...pv,
                selectedProjectJobsLoaded: true,
                gantt: {
                    ...(tasksOnly === true ? { ...pv.gantt, tasks: [...data.XGANTT.tasks] } : data.XGANTT ? { ...data.XGANTT } : {})
                }
            }));
        },
        [executeStored, state.ident, state.selectedProject]
    );
    //Изменение работы в графике
    const modifyJob = useCallback(
        async (job, dateFrom, dateTo) => {
            let data = null;
            try {
                data = await executeStored({
                    stored: "PKG_P8PANELS_PROJECTS.JB_JOBS_MODIFY_PERIOD",
                    args: { NJB_JOBS: job, DDATE_FROM: dateFrom, DDATE_TO: dateTo }
                });
                if (data?.NRESOURCE_STATUS != -1) {
                    setState(pv => ({ ...pv, resourceStatus: data.NRESOURCE_STATUS, needSave: true }));
                    loadProjects(true);
                }
            } finally {
                loadProjectJobs(true);
            }
        },
        [executeStored, loadProjectJobs, loadProjects]
    );
    //Сохранение буфера балансировки в проекты
    const saveProjects = useCallback(async () => {
        const data = await executeStored({
            stored: "PKG_P8PANELS_PROJECTS.JB_SAVE",
            args: { NIDENT: state.ident },
            respArg: "COUT"
        });
        setState(pv => ({ ...pv, needSave: false, projects: [...(data?.XPROJECTS || [])] }));
    }, [executeStored, state.ident]);
    //Инициализация данных балансировки
    const initJobs = useCallback(async () => {
        if (!state.init) {
            const data = await executeStored({
                stored: "PKG_P8PANELS_PROJECTS.JB_INIT",
                args: {
                    DBEGIN: state.dateBegin ? state.dateBegin : null,
                    DFACT: state.dateFact ? state.dateFact : null,
                    NIDENT: state.ident
                }
            });
            setState(pv => ({
                ...pv,
                init: true,
                reInit: false,
                dateBegin: new Date(data.DBEGIN),
                dateFact: new Date(data.DFACT),
                durationMeas: data.NDURATION_MEAS,
                durationMeasCode: data.SDURATION_MEAS,
                labMeas: data.NLAB_MEAS,
                labMeasCode: data.SLAB_MEAS,
                resourceStatus: data.NRESOURCE_STATUS,
                ident: data.NIDENT
            }));
        }
    }, [state.init, state.dateBegin, state.dateFact, state.ident, executeStored]);
    //Грузим список проектов при смене идентификатора процесса
    useEffect(() => {
        if (state.ident) loadProjects();
    }, [state.ident, loadProjects]);
    //При смене выбранного проекта
    useEffect(() => {
        if (state.selectedProject) loadProjectJobs(false);
    }, [state.selectedProject, loadProjectJobs]);
    //При изменении флага инициализации
    useEffect(() => {
        initJobs();
    }, [state.init, initJobs]);
    //Выбор проекта
    const selectPoject = (project, projectDocRn) => {
        setState(pv => ({
            ...pv,
            selectedProject: project,
            selectedProjectDocRn: projectDocRn,
            selectedProjectJobsLoaded: false,
            gantt: {},
            showProjectsList: false
        }));
    };
    //Сброс выбора проекта
    const unselectProject = () =>
        setState(pv => ({
            ...pv,
            selectedProjectJobsLoaded: false,
            selectedProject: null,
            selectedProjectDocRn: null,
            gantt: {},
            showProjectsList: false
        }));
    //Обработка нажатия на элемент в списке проектов
    const handleProjectClick = project => {
        if (state.selectedProject != project.NRN) selectPoject(project.NRN, project.NPROJECT);
        else unselectProject();
    };
    //Отработка нажатия на заголовок плана-графика
    const handleTitleClick = () =>
        state.selectedProjectDocRn ? pOnlineShowDocument({ unitCode: "Projects", document: state.selectedProjectDocRn }) : null;
    //Обработка измненения сроков задачи в диаграмме Гантта
    const handleTaskDatesChange = ({ task, start, end, isMain }) => {
        if (isMain) modifyJob(task.rn, new Date(start), new Date(end));
    };
    //Отработка нажатия на отображения диалога параметров инициализации панели
    const handleShowInitDialogClick = () => setState(pv => ({ ...pv, showInitDialog: true }));
    //Отработка нажатия на "ОК" в диалоге параметров инициализации панели
    const handleOKInitDialogClick = values =>
        setState(pv => ({ ...pv, dateBegin: values.dateBegin, dateFact: values.dateFact, showInitDialog: false, init: false }));
    //Отработка нажатия на "Отмена" в диалоге параметров инициализации панели
    const handleCancelInitDialogClick = () => setState(pv => ({ ...pv, showInitDialog: false }));
    //Обработка нажатия на сохранение данных в проект
    const handleSaveToProjectsClick = () => saveProjects();
    //Обработка нажатия на проект в таблице детализации трудоёмкости по плану-графику монитора ресурсов
    const handlePlanJobsDtlProjectClick = ({ sender }) => {
        setState(pv => ({ ...pv, showPeriodsList: false }));
        if (state.selectedProject != sender.NJB_PRJCTS) selectPoject(sender.NJB_PRJCTS, sender.NPROJECT);
    };
    //Генерация содержимого
    return (
        
            {state.showInitDialog ? (
                
            ) : null}
             setState(pv => ({ ...pv, showProjectsList: !pv.showProjectsList }))}>
                Проекты
                {state.needSave ? (
                    <>
                          
                        save
                    >
                ) : null}
            
             setState(pv => ({ ...pv, showProjectsList: false }))}
                sx={STYLES.PROJECTS_DRAWER}
            >
                {state.projectsLoaded ? (
                    <>
                        
                        
                        {state.needSave ? (
                            <>
                                
                                
                            >
                        ) : null}
                        
                    >
                ) : null}
            
             setState(pv => ({ ...pv, showPeriodsList: !pv.showPeriodsList }))}>
                Ресурсы
                {[0, 1].includes(state.resourceStatus) ? (
                    <>
                          
                        {state.resourceStatus === 0 ? "done" : "error"}
                    >
                ) : null}
            
             setState(pv => ({ ...pv, showPeriodsList: false }))}
                sx={STYLES.PERIODS_DRAWER}
            >
                {state.ident ?  : null}
            
            {state.init == true ? (
                
                    
                        {state.selectedProjectJobsLoaded ? (
                            
                        ) : !state.selectedProject ? (
                            
                                
                            
                        ) : null}
                    
                
            ) : null}
        
    );
};
//----------------
//Интерфейс модуля
//----------------
export { PrjJobs };