import { Box, Button, Modal, ModalProps, Paper, SxProps, Tooltip, Typography } from "@mui/material"
import StyledDataGrid from "../StyledDataGrid"
import { useTranslation } from "react-i18next";
import { useFormContext } from "react-hook-form";
import { useCallback, useEffect, useMemo, useState } from "react";
import { GridRenderEditCellParams, FooterPropsOverrides, GridActionsCellItem, GridCellParams, GridEventListener, GridRowEditStopReasons, GridRowId, GridRowIdGetter, GridRowModel, GridRowModes, GridRowModesModel, GridToolbarContainer, useGridApiRef, GridEditDateCell, GridEditSingleSelectCell } from "@mui/x-data-grid";
import AddIcon from '@mui/icons-material/Add';
import SaveIcon from '@mui/icons-material/Save';
import DeleteIcon from '@mui/icons-material/Delete';
import CancelIcon from '@mui/icons-material/Cancel';
import EditIcon from '@mui/icons-material/Edit'; 
import waitForCondition from "../utils/waitFor";
import { gradeHistory } from "@/app/api/staff/actions";
import { Add } from "@mui/icons-material";
import { comboItem } from "../CreateStaff/CreateStaff";
import { StaffEntryError, validateRowAndRowBefore } from "./validateDates";
import { ProcessRowUpdateError } from "./TeamHistoryModal";

interface Props {
  open: boolean;
  onClose: () => void;
  combos: comboItem;
    // columns: any[]
}

const modalSx: SxProps = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: "90%",
  maxWidth: "auto",
  maxHeight: "auto",
  padding: 3,
  display: "flex",
  flexDirection: "column",
  gap: 2,
};

export type GradeModalRow = Partial<
gradeHistory & {
  _isNew: boolean
  _error: StaffEntryError;
}>
const thisField = "gradeHistory"
const GradeHistoryModal: React.FC<Props> = ({ open, onClose, combos }) => {
    const {
      t,
      // i18n: { language },
    } = useTranslation();
    const { setValue, getValues } = useFormContext();
    const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
    const apiRef = useGridApiRef()
    const originalRows = getValues(thisField)
    const [_rows, setRows] = useState(() => {
      const list: GradeModalRow[] = getValues(thisField)
      return list && list.length > 0 ? list : []
    });
    const [_delRows, setDelRows] = useState<number[]>([]);
    const getRowId = useCallback<GridRowIdGetter<GradeModalRow>>(
      (row) => row.id!!,
      [],
    );
    const handleSave = useCallback(
      (id: GridRowId) => () => {
        setRowModesModel((prevRowModesModel) => ({
          ...prevRowModesModel,
          [id]: { mode: GridRowModes.View }
        }));
      },
      [setRowModesModel]
    );

    const onCancel = useCallback(() => {
      setRows(originalRows)
      onClose();
    }, [onClose, originalRows]);
  
    const handleClose = useCallback<NonNullable<ModalProps["onClose"]>>(
      (_, reason) => {
        if (reason !== "backdropClick") {
          onClose();
        }
    }, [onClose]);

    const isSaved = useCallback(() => {
      const saved = Object.keys(rowModesModel).every(key => {
        rowModesModel[key].mode === GridRowModes.Edit
      })
      return saved
    }, [rowModesModel])

    const doSave = useCallback(async () => {
      try {
        if (isSaved()) {
          setValue(thisField, _rows)
          onClose()
        }
      } catch (error) {
        console.error(error);
      }
    }, [isSaved, onClose, _rows])

    const addRow = useCallback(() => {
      const id = Date.now()
      const newEntry = { id, _isNew: true } satisfies GradeModalRow;
      setRows((prev) => [...prev, newEntry])
      setRowModesModel((model) => ({
        ...model,
        [getRowId(newEntry)]: {
          mode: GridRowModes.Edit,
          fieldToFocus: "grade",
        }
      }))
    }, []);
    const onProcessRowUpdateError = useCallback(
      (updateError: ProcessRowUpdateError<GradeModalRow>) => {
        const errors = updateError.errors;
        // const prevRow = updateError.prevRow;
        const currRow = updateError.currRow;
        // if (updateError.prevRow) {
        //   apiRef.current.updateRows([{ ...prevRow, _error: errors }]);
        // }
        apiRef.current.updateRows([{ ...currRow, _error: errors }]);
      },
      [apiRef, rowModesModel],
    );  

    const processRowUpdate = useCallback((
      newRow: GridRowModel<GradeModalRow>, 
      originalRow: GridRowModel<GradeModalRow>
    ) => {
      const rowIndex = _rows.findIndex((row: GradeModalRow) => row.id === newRow.id);
      const prevRow: GradeModalRow | null = rowIndex > 0 ? _rows[rowIndex - 1] : null;
      const errors = validateRowAndRowBefore(prevRow, newRow)
      console.log(errors)
      if (errors) {
        throw new ProcessRowUpdateError(
          prevRow,
          newRow,
          "validation error",
          errors
        )
      }
      const { _isNew, _error, ...updatedRow } = newRow;

      const rowToSave = {
        ...updatedRow,
      }
      console.log(_rows)
      if (_rows.length != 0) {
        setRows((prev: any[]) => prev?.map((row: any) => (row.id === newRow.id ? rowToSave : row)).sort((a, b) => {
          if (!a.from || !b.from) return 0;
          return new Date(a.from).getTime() - new Date(b.from).getTime();
        }));
      }
      return rowToSave;
    }
    , [_rows, validateRowAndRowBefore])

    const handleCancel = useCallback(
        (id: any) => () => {
          setRowModesModel((prevRowModesModel) => ({
            ...prevRowModesModel,
            [id]: { mode: GridRowModes.View, ignoreModifications: true }
          }));
          const editedRow = _rows.find((r) => getRowId(r) === id)
          if (editedRow?._isNew) {
            setRows((rw) => rw.filter((r) => r.id !== id))
          } else {
            setRows((rw) =>
              rw.map((r) =>
                getRowId(r) === id
                  ? { ...r, _error: undefined }
                  : r,
              ),
            );
          }
        },
        [setRowModesModel, _rows]
      );

    const handleDelete = useCallback(
        (id: GridRowId) => () => {
          setRows((prevRows) => prevRows.filter((row) => row.id !== id));
          setDelRows((prevRowsId: number[]) => [...prevRowsId, id as number])
        },
        []
      );
    
      useEffect(()=> {
        console.log(_rows)
        // setValue(thisField, _rows)
        setValue('delGradeHistory', _delRows)
    }, [_rows, _delRows])

    const footer = (
      <Box display="flex" gap={2} alignItems="center">
        <Button
          disableRipple
          variant="outlined"
          startIcon={<Add />}
          onClick={addRow}
          size="small"
        >
          {t("Add Record")}
        </Button>
      </Box>
      )
      const columns = useMemo(
        () => [
          {
          field: 'grade',
          headerName: 'grade',
          flex: 1,
          editable: true,
          type: 'singleSelect',
          valueOptions: combos.grade.map(item => item.label),
          renderEditCell(params: GridRenderEditCellParams<GradeModalRow>) {
            const errorMessage = params.row._error?.[params.field as keyof StaffEntryError]
            const content = (
              <GridEditSingleSelectCell variant="outlined" {...params} />
            );
            return errorMessage ? (
              <Tooltip title={errorMessage}>
                <Box width="100%">{content}</Box>
              </Tooltip>
            ) : (
              content
            );
          }
          },
          {
          field: 'from',
          headerName: 'from',
          flex: 1,
          editable: true,
          type: 'date',
          renderEditCell(params: GridRenderEditCellParams<GradeModalRow>) {
            const errorMessage = params.row._error?.[params.field as keyof StaffEntryError]
            const content = <GridEditDateCell {...params} />;
            return errorMessage ? (
              <Tooltip title={errorMessage}>
                <Box width="100%">{content}</Box>
              </Tooltip>
            ) : (
              content
            );
          }
          },
          {
            field: 'actions',
            type: 'actions',
            headerName: 'edit',
            width: 100,
            cellClassName: 'actions',
            getActions: ({ id }: { id: number }) => {
              const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
              if (isInEditMode) {
                return [
                  <GridActionsCellItem
                    icon={<SaveIcon />}
                    label="Save"
                    key="edit"
                    sx={{
                      color: 'primary.main'
                    }}
                    onClick={handleSave(id)}
                  />,
                  <GridActionsCellItem
                    icon={<CancelIcon />}
                    label="Cancel"
                    key="edit"
                    onClick={handleCancel(id)}
                  />
                ];
              }
              return [
                <GridActionsCellItem 
                  icon={<DeleteIcon />} 
                  label="Delete" 
                  sx={{
                    color: 'error.main'
                  }}
                  onClick={handleDelete(id)} color="inherit" key="edit" />
              ];
            }
          }
      ], [combos, rowModesModel, handleSave, handleCancel, handleDelete])      

    return (
      <Modal open={open} onClose={handleClose}>
            <Paper sx={{ ...modalSx }}>
                <Typography variant="h6" component="h2">
                {t('GradeHistoryModal')}
                </Typography>
                <StyledDataGrid
                        getRowId={getRowId}
                        apiRef={apiRef}
                        rows={_rows}
                        columns={columns}
                        editMode="row"
                        autoHeight
                        sx={{
                          "--DataGrid-overlayHeight": "100px",
                          ".MuiDataGrid-row .MuiDataGrid-cell.hasError": {
                            border: "1px solid",
                            borderColor: "error.main",
                          },
                          ".MuiDataGrid-row .MuiDataGrid-cell.hasWarning": {
                            border: "1px solid",
                            borderColor: "warning.main",
                          },
                        }}
                        disableColumnMenu
                        rowModesModel={rowModesModel}
                        onRowModesModelChange={setRowModesModel}
                        processRowUpdate={processRowUpdate}
                        onProcessRowUpdateError={onProcessRowUpdateError}
                        getCellClassName={(params: GridCellParams<GradeModalRow>) => {
                          let classname = "";
                          if (params.row._error) {
                            classname = "hasError"
                          }
                          return classname;
                        }}
                        slots={{
                          footer: FooterToolbar,
                          noRowsOverlay: NoRowsOverlay,
                        }}
                        slotProps={{
                          footer: { child: footer },
                        }}
                    /> 
                <Box display="flex" justifyContent="flex-end" gap={2}>
                <Button variant="text" onClick={onCancel}>
                  {t('Close')}
                </Button>
                <Button variant="contained" onClick={doSave}>
                    {t("Save")}
                </Button>
                </Box>
                {/* </FormControl> */}
            </Paper>
        </Modal>
    )
}
const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => {
  return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>;
};
const NoRowsOverlay: React.FC = () => {
  const { t } = useTranslation("home");
  return (
    <Box
      display="flex"
      justifyContent="center"
      alignItems="center"
      height="100%"
    >
      <Typography variant="caption">{t("Add some entries!")}</Typography>
    </Box>
  );
};
export default GradeHistoryModal