/*
    Парус 8 - Панели мониторинга - ПУП - Производственный план цеха
    Панель мониторинга: Корневая панель производственного плана цеха
*/

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

import React, { useContext, useState } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Drawer, Fab, Box, List, ListItemButton, ListItemText, Typography, TextField, Link, Grid } from "@mui/material"; //Интерфейсные элементы
import { APP_STYLES } from "../../../app.styles"; //Типовые стили
import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Заголовок страницы
import { useDeptCostProdPlans, useFilteredPlans, useDeptCostProdPlanInfo } from "./hooks"; //Вспомогательные хуки
import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
import { MessagingCtx } from "../../context/messaging"; //Контекст сообщений
import { IncomFromDepsDataGridDialog } from "./incomefromdeps"; //Диалог сдачи продукции
import { CostRouteListsDataGridDialog } from "./fcroutlst"; //Диалог маршрутных листов

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

//Высота заголовка
const TITLE_HEIGHT = "35px";

//Верхний отступ заголовка
const TITLE_PADDING_TOP = "10px";

//Нижний отступ заголовка
const TITLE_PADDING_BOTTOM = "20px";

//Стили
const STYLES = {
    PLANS_FILTER: { paddingTop: "20px", display: "flex", flexDirection: "column", alignItems: "center", gap: "5px" },
    PLANS_FILTER_ITEM: { margin: "0px 10px", width: "93%" },
    PLANS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
    PLANS_BUTTON: { position: "absolute" },
    PLANS_DRAWER: {
        width: "350px",
        display: "inline-block",
        flexShrink: 0,
        [`& .MuiDrawer-paper`]: { width: "350px", display: "inline-block", boxSizing: "border-box", ...APP_STYLES.SCROLL }
    },
    CONTAINER: { textAlign: "center" },
    TITLE: { height: TITLE_HEIGHT, overflow: "hidden", paddingTop: TITLE_PADDING_TOP, paddingBottom: TITLE_PADDING_BOTTOM, display: "inline-table" },
    DATA_GRID_CONTAINER: {
        height: `calc(100vh - ${APP_BAR_HEIGHT} - ${TITLE_HEIGHT} - ${TITLE_PADDING_TOP} - ${TITLE_PADDING_BOTTOM} - 29px)`,
        width: "98vw",
        ...APP_STYLES.SCROLL
    },
    DATA_GRID_GROUP_CELL: { padding: "2px" },
    DATA_GRID_CELL: { padding: "8px", maxWidth: "300px", textOverflow: "ellipsis", overflow: "hidden", whiteSpace: "pre" },
    DATA_GRID_CELL_STATUS: (currentStyle, row) => ({ backgroundColor: getRowBackgroudColor(row), ...currentStyle }),
    DATA_GRID_CELL_PLAN_FACT: currentStyle => ({ ...currentStyle, backgroundColor: "lightgrey" }),
    DATA_GRID_CELL_MATRES_CODE: (currentStyle, row) => ({ backgroundColor: getRowBackgroudColor(row), ...currentStyle }),
    PLAN_FACT_VALUE: { textAlign: "center", display: "flex", justifyContent: "center" },
    PLAN_FACT_DELIMITER: { padding: "0px 5px" },
    FACT_VALUE: { color: "blue" }
};

//Имена полей компонента
const SFIELD_MONTH = "month";

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

//Считывание текущего года и месяца в формате "YYYY-MM"
const getCurrentYearMonth = () => {
    return `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}`;
};

//Генерация представления ячейки заголовка группы
export const groupCellRender = ({ group }) => ({
    cellStyle: STYLES.DATA_GRID_GROUP_CELL,
    data: group.caption
});

//Вычисление цвета заливки для строки
const getRowBackgroudColor = row => {
    //Факт === План
    if (row["NMAIN_QUANT"] === row["NREL_FACT"]) return "lightgreen";
    //План <= (Факт + Запущено)
    if (row["NMAIN_QUANT"] <= row["NREL_FACT"] + row["NFCROUTLST_QUANT"]) return "lightblue";
    //Сумма "Количество план" = 0 или < "План"
    if (row["NSUM_PLAN"] === 0 || (row["NSUM_PLAN"] !== 0 && row["NSUM_PLAN"] < row["NMAIN_QUANT"])) {
        //"Факт" >= "План"
        if (row["NREL_FACT"] >= row["NMAIN_QUANT"]) return "#F0E68C";
    } else {
        //Сумма "Количество факт" >= сумма "Количество план"
        if (row["NSUM_FACT"] >= row["NSUM_PLAN"]) return "#F0E68C";
    }
    return "lightcoral";
};

//Генерация заливки строки исходя от значений
const dataCellRender = ({ row, columnDef, onProdOrderClick, onMatresCodeClick }) => {
    //Описываем общие свойства
    let cellProps = { title: row[columnDef.name] };
    //Описываем общий стиль
    let cellStyle = STYLES.DATA_GRID_CELL;
    //Для колонки "Статус"
    if (columnDef.name === "SSTATUS") return { cellProps, cellStyle: STYLES.DATA_GRID_CELL_STATUS(cellStyle, row), data: row[columnDef] };
    //Для колонки даты
    if (columnDef.name.indexOf("PLAN_FACT") >= 0) {
        //Получаем текущий день
        let curDay = new Date().getDate().toString().padStart(2, "0");
        //Формируем regex для проверки
        let regex = new RegExp(`N_${curDay}.*`, "g");
        //Если это значение текущего дня
        if (columnDef.name.match(regex)) cellStyle = STYLES.DATA_GRID_CELL_PLAN_FACT(cellStyle);
        //Если в колонке есть значение
        if (row[columnDef.name]) {
            //Разбиваем его на план/факт
            let values = row[columnDef.name].split("/");
            //Разбиваем значения на блоки
            return {
                cellProps,
                cellStyle,
                data: (
                    <Box sx={STYLES.PLAN_FACT_VALUE}>
                        <Box>{values[0]}</Box>
                        <Box sx={STYLES.PLAN_FACT_DELIMITER}>/</Box>
                        <Box sx={STYLES.FACT_VALUE}>{values[1]}</Box>
                    </Box>
                )
            };
        } else return { cellProps, cellStyle, data: row[columnDef] };
    }
    //Для колонки "Заказ"
    if (columnDef.name === "SPROD_ORDER") {
        return {
            cellProps,
            cellStyle,
            data: (
                <Link component="button" variant="body2" align="left" underline="hover" onClick={() => onProdOrderClick(row["NRN"])}>
                    {row[columnDef.name]}
                </Link>
            )
        };
    }
    //Для колонки "Обозначение"
    if (columnDef.name === "SMATRES_CODE")
        return {
            cellProps,
            cellStyle: STYLES.DATA_GRID_CELL_MATRES_CODE(cellStyle, row),
            data: (
                <Link component="button" variant="body2" align="left" underline="hover" onClick={() => onMatresCodeClick(row["NRN"])}>
                    {row[columnDef.name]}
                </Link>
            )
        };
    //Для всех остальных
    return { cellProps, cellStyle, data: row[columnDef] };
};

//Список каталогов планов
const PlanList = ({ plans = [], selectedPlan, filter, onFilterChange, onClick } = {}) => {
    //При изменении фильтра
    const handleFilterChange = e => {
        onFilterChange && onFilterChange(e);
    };

    //Генерация содержимого
    return (
        <div>
            <Box sx={STYLES.PLANS_FILTER}>
                <TextField
                    sx={STYLES.PLANS_FILTER_ITEM}
                    name={SFIELD_MONTH}
                    label="Месяц"
                    type="month"
                    value={filter.month}
                    InputLabelProps={{ shrink: true }}
                    variant="standard"
                    fullWidth
                    onChange={handleFilterChange}
                    required={true}
                ></TextField>
                <TextField
                    sx={STYLES.PLANS_FILTER_ITEM}
                    name="planName"
                    label="План"
                    value={filter.planName}
                    variant="standard"
                    fullWidth
                    onChange={handleFilterChange}
                ></TextField>
            </Box>
            <List>
                {plans.map(p => (
                    <ListItemButton key={p.NRN} selected={p.NRN === selectedPlan.NRN} onClick={() => (onClick ? onClick(p) : null)}>
                        <ListItemText primary={<Typography sx={STYLES.PLANS_LIST_ITEM_PRIMARY}>{p.SDOC_INFO}</Typography>} />
                    </ListItemButton>
                ))}
            </List>
        </div>
    );
};

//Контроль свойств - Список каталогов планов
PlanList.propTypes = {
    plans: PropTypes.array,
    selectedPlan: PropTypes.object,
    onClick: PropTypes.func,
    filter: PropTypes.object,
    onFilterChange: PropTypes.func
};

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

//Корневая панель производственного плана цеха
const MechRecDeptCostProdPlans = () => {
    //Состояние для фильтра каталогов
    const [filter, setFilter] = useState({ planName: "", month: getCurrentYearMonth() });

    //Собственное состояние - таблица планов
    const [plans, setPlans] = useDeptCostProdPlans(filter.month);

    //Собственное состояние - таблица информации
    const [planInfo, setPlanInfo, onPlanInfoClear, onPlanInfoOrderChanged, onPlanInfoPagesCountChanged] = useDeptCostProdPlanInfo(plans.selected);

    //Массив отфильтрованных каталогов
    const filteredPlanCtgls = useFilteredPlans(plans.rows, filter);

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

    //Выбор плана
    const selectPlan = plan => {
        setPlans(pv => ({
            ...pv,
            selected: plan,
            showPlanList: false
        }));
        onPlanInfoClear();
    };

    //Сброс выбора плана
    const unselectPlan = () => {
        setPlans(pv => ({
            ...pv,
            selected: {},
            showPlanList: false
        }));
        onPlanInfoClear();
    };

    //Обработка нажатия на элемент в списке планов
    const handlePlanClick = plan => {
        if (plans.selected.NRN != plan.NRN) selectPlan(plan);
        else unselectPlan();
    };

    //При изменении состояния сортировки информации плана
    const handlePlanInfoOrderChanged = ({ orders }) => onPlanInfoOrderChanged({ orders });

    //При изменении количества отображаемых страниц информации плана
    const handlePlanInfoPagesCountChanged = () => onPlanInfoPagesCountChanged();

    //При нажатии на "Заказ"
    const handleProdOrderClick = planSp => {
        setPlanInfo(pv => ({ ...pv, showIncomeFromDeps: planSp }));
    };

    //При нажатии на "Обозначение"
    const handleMatresCodeClick = planSp => {
        setPlanInfo(pv => ({ ...pv, showFcroutelst: planSp }));
    };

    //При изменении фильтров
    const handleFilterChange = e =>
        setFilter(pv => ({ ...pv, [e.target.name]: e.target.name === SFIELD_MONTH && !e.target.value ? getCurrentYearMonth() : e.target.value }));

    //Генерация содержимого
    return (
        <Box p={2}>
            <Fab variant="extended" sx={STYLES.PLANS_BUTTON} onClick={() => setPlans(pv => ({ ...pv, showPlanList: !pv.showPlanList }))}>
                Планы
            </Fab>
            <Drawer
                anchor={"left"}
                open={plans.showPlanList}
                onClose={() => setPlans(pv => ({ ...pv, showPlanList: false }))}
                sx={STYLES.PLANS_DRAWER}
            >
                <PlanList
                    plans={filteredPlanCtgls}
                    selectedPlan={plans.selected}
                    filter={filter}
                    onFilterChange={handleFilterChange}
                    onClick={handlePlanClick}
                />
            </Drawer>
            <Grid container>
                <Grid item xs={12}>
                    <Box display="flex" justifyContent="center" alignItems="center">
                        {planInfo.dataLoaded ? (
                            planInfo.rows.length === 0 ? (
                                <InlineMsgInfo okBtn={false} text={"В плане отсутствуют записи спецификации"} />
                            ) : (
                                <Box sx={STYLES.CONTAINER}>
                                    <Typography sx={STYLES.TITLE} variant={"h6"}>
                                        {`Производственный план цеха №${plans.selected.SSUBDIV} на ${plans.selected.SPERIOD}`}
                                    </Typography>
                                    <Box>
                                        <P8PDataGrid
                                            {...P8P_DATA_GRID_CONFIG_PROPS}
                                            containerComponentProps={{ elevation: 6, sx: STYLES.DATA_GRID_CONTAINER }}
                                            fixedHeader={planInfo.fixedHeader}
                                            fixedColumns={planInfo.fixedColumns}
                                            columnsDef={planInfo.columnsDef}
                                            rows={planInfo.rows}
                                            size={P8P_DATA_GRID_SIZE.MEDIUM}
                                            morePages={planInfo.morePages}
                                            reloading={planInfo.reload}
                                            onOrderChanged={handlePlanInfoOrderChanged}
                                            onPagesCountChanged={handlePlanInfoPagesCountChanged}
                                            dataCellRender={prms =>
                                                dataCellRender({
                                                    ...prms,
                                                    onProdOrderClick: handleProdOrderClick,
                                                    onMatresCodeClick: handleMatresCodeClick
                                                })
                                            }
                                            groupCellRender={groupCellRender}
                                        />
                                    </Box>
                                </Box>
                            )
                        ) : !plans.selected.NRN ? (
                            <InlineMsgInfo okBtn={false} text={"Укажите план для отображения спецификаций"} />
                        ) : null}
                    </Box>
                </Grid>
            </Grid>
            {planInfo.showIncomeFromDeps ? (
                <IncomFromDepsDataGridDialog task={planInfo.showIncomeFromDeps} onClose={() => handleProdOrderClick(null)} />
            ) : null}
            {planInfo.showFcroutelst ? (
                <CostRouteListsDataGridDialog task={planInfo.showFcroutelst} onClose={() => handleMatresCodeClick(null)} />
            ) : null}
        </Box>
    );
};

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

export { MechRecDeptCostProdPlans };
