import { useEffect, useState } from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import AddIcon from '@mui/icons-material/Add';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/DeleteOutlined';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Close';
import {
    GridRowsProp,
    GridRowModesModel,
    GridRowModes,
    DataGrid,
    GridColDef,
    GridToolbarContainer,
    GridActionsCellItem,
    GridEventListener,
    GridRowId,
    GridRowModel,
    GridRowEditStopReasons,
    GridSlots,
} from '@mui/x-data-grid';

interface EditToolbarProps {
    setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void;
    setRowModesModel: (
        newModel: (oldModel: GridRowModesModel) => GridRowModesModel,
    ) => void;
    columns: GridColDef[];
    autoComplete?: React.ReactElement | null;
}

function EditToolbar(props: EditToolbarProps) {
    const { setRows, setRowModesModel, columns, autoComplete } = props;

    const handleClick = () => {
        const id = Date.now().toString(36)
        const newValues: any = {};

        columns.forEach(column => {
            if (column.type === 'number') {
                newValues[column.field] = 0
            } else if (column.type === 'string') {
                newValues[column.field] = ''
            } else if (column.type === 'boolean') {
                newValues[column.field] = false
            } else {
                newValues[column.field] = undefined
            }

            if (column.field === 'region_id') {
                // column.valueGetter = (value: any) => {
                //     console.log(value)
                // }
            }
        })

        setRows((oldRows) => [...oldRows, { id, ...newValues, isNew: true }]);
        setRowModesModel((oldModel) => ({
            ...oldModel,
            [id]: { mode: GridRowModes.Edit, fieldToFocus: columns[0].field },
        }));
    };

    return (
        <GridToolbarContainer sx={{ px: '16px', py: '16px' }}>
            {autoComplete &&
                <Box sx={{ flexGrow: '1' }}>
                    {autoComplete}
                </Box>
            }

            <Button color="primary" startIcon={<AddIcon />} onClick={handleClick}>
                Добавить
            </Button>
        </GridToolbarContainer>
    );
}

interface DataGridProps {
    initialRows: GridRowsProp;
    columns: GridColDef[];
    actions: boolean;
    onRowClick: GridEventListener<"rowClick">;
    onSave: any;
    onDelete: any;
    autoComplete?: React.ReactElement | null;
    loading: boolean;
}

export default function FullFeaturedCrudGrid({
    initialRows,
    columns,
    actions = false,
    onRowClick,
    onSave,
    onDelete,
    autoComplete,
    loading
}: DataGridProps) {
    const [rows, setRows] = useState(initialRows);
    const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});

    const handleRowEditStop: GridEventListener<'rowEditStop'> = (params, event) => {
        if (params.reason === GridRowEditStopReasons.rowFocusOut) {
            event.defaultMuiPrevented = true;
        }
    };

    const handleEditClick = (id: GridRowId) => () => {
        setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } });
    };

    const handleSaveClick = (id: GridRowId) => () => {
        setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } });
        onSave?.(id)
    };

    const handleDeleteClick = (id: GridRowId) => () => {
        setRows(rows.filter((row) => row.id !== id));
        onDelete?.(id)
    };

    const handleCancelClick = (id: GridRowId) => () => {
        setRowModesModel({
            ...rowModesModel,
            [id]: { mode: GridRowModes.View, ignoreModifications: true },
        });

        const editedRow = rows.find((row) => row.id === id);
        if (editedRow!.isNew) {
            setRows(rows.filter((row) => row.id !== id));
        }
    };

    const processRowUpdate = (newRow: GridRowModel) => {
        const updatedRow = { ...newRow, isNew: false };
        setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row)));
        return updatedRow;
    };

    const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => {
        setRowModesModel(newRowModesModel);
    };

    useEffect(() => {
        if (initialRows) {
            setRows(initialRows)
        }
    }, [initialRows])

    const actionColumns: GridColDef[] = [
        {
            field: 'actions',
            type: 'actions',
            headerName: 'Действия',
            width: 100,
            cellClassName: 'actions',
            getActions: ({ id }) => {
                const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;

                if (isInEditMode) {
                    return [
                        <GridActionsCellItem
                            icon={<SaveIcon />}
                            label="Save"
                            sx={{
                                color: 'primary.main',
                            }}
                            onClick={handleSaveClick(id)}
                        />,
                        <GridActionsCellItem
                            icon={<CancelIcon />}
                            label="Cancel"
                            className="textPrimary"
                            onClick={handleCancelClick(id)}
                            color="inherit"
                        />,
                    ];
                }

                return [
                    <GridActionsCellItem
                        icon={<EditIcon />}
                        label="Edit"
                        className="textPrimary"
                        onClick={handleEditClick(id)}
                        color="inherit"
                    />,
                    <GridActionsCellItem
                        icon={<DeleteIcon />}
                        label="Delete"
                        onClick={handleDeleteClick(id)}
                        color="inherit"
                    />,
                ];
            },
        }
    ]

    return (
        <Box
            sx={{
                height: 500,
                width: '100%',
                '& .actions': {
                    color: 'text.secondary',
                },
                '& .textPrimary': {
                    color: 'text.primary',
                },
            }}
        >
            <DataGrid
                loading={loading}
                rows={rows || []}
                columns={actions ? [...columns, ...actionColumns] : columns}
                editMode="row"
                rowModesModel={rowModesModel}
                onRowClick={onRowClick}
                onRowModesModelChange={handleRowModesModelChange}
                onRowEditStop={handleRowEditStop}
                processRowUpdate={processRowUpdate}
                slots={{
                    toolbar: EditToolbar as GridSlots['toolbar'],
                }}
                slotProps={{
                    toolbar: { setRows, setRowModesModel, columns, autoComplete },
                }}
            />
        </Box>
    );
}