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 { Add } from "@mui/icons-material";
import { positionHistory } from "@/app/api/staff/actions";
import { comboItem } from "../CreateStaff/CreateStaff";
import { StaffEntryError, validateRowAndRowBefore } from "./validateDates";
import { ProcessRowUpdateError } from "./TeamHistoryModal";
import { createSearchParamsBailoutProxy } from "next/dist/client/components/searchparams-bailout-proxy";

interface Props {
  open: boolean;
  onClose: () => void;
  combos: comboItem;
}

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 PositionModalRow = Partial<
positionHistory & {
  _isNew: boolean
  _error: StaffEntryError;
}>

const thisField = "positionHistory"
const PositionHistoryModal: 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: PositionModalRow[] = getValues(thisField)
      return list && list.length > 0 ? list : []
    });
    const [_delRows, setDelRows] = useState<number[]>([]);
    const getRowId = useCallback<GridRowIdGetter<PositionModalRow>>(
      (row) => row.id!!,
      [],
    );

    const handleSave = useCallback(
      (id: GridRowId) => () => {
        setRowModesModel((prevRowModesModel) => ({
          ...prevRowModesModel,
          [id]: { mode: GridRowModes.View }
        }));
      },
      [setRowModesModel]
    );

    const onCancel = useCallback(() => {
      console.log(originalRows)
      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 onProcessRowUpdateError = useCallback(
      (updateError: ProcessRowUpdateError<PositionModalRow>) => {
        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],
    );  
      // handle row update here
      const processRowUpdate = useCallback((
        newRow: GridRowModel<PositionModalRow>, 
        originalRow: GridRowModel<PositionModalRow>
      ) => {
        const rowIndex = _rows.findIndex((row: PositionModalRow) => row.id === newRow.id);
        const prevRow: PositionModalRow | 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 addRow = useCallback(() => {
        const newEntry = { id: Date.now(), _isNew: true } satisfies PositionModalRow;
        setRows((prev) => [...prev, newEntry])
        setRowModesModel((model) => ({
          ...model,
          [getRowId(newEntry)]: {
            mode: GridRowModes.Edit,
            fieldToFocus: "position",
          }
        }))
      }, [getRowId]);

      const handleCancel = useCallback(
        (id: GridRowId) => () => {
          setRowModesModel((model) => ({
            ...model,
            [id]: { mode: GridRowModes.View, ignoreModifications: true }
          }));
          const editedRow = _rows.find((row) => getRowId(row) === id);
          console.log(editedRow)
          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])
        },
        [setRows, setDelRows]
      );
    
      useEffect(()=> {
        console.log(_rows)
        setValue(thisField, _rows)
        setValue('delPositionHistory', _delRows)
    }, [_rows, _delRows])

    const columns = useMemo(
      () => [
        {
        field: 'position',
        headerName: 'position',
        flex: 1,
        editable: true,
        type: 'singleSelect',
        valueOptions: combos.position.map(item => item.label),
        renderEditCell(params: GridRenderEditCellParams<PositionModalRow>) {
          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<PositionModalRow>) {
          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])

      const footer = (
        <Box display="flex" gap={2} alignItems="center">
          <Button
            disableRipple
            variant="outlined"
            startIcon={<Add />}
            onClick={addRow}
            size="small"
          >
            {t("Add Record")}
          </Button>
        </Box>
        )

    return (
      <Modal open={open} onClose={handleClose}>
            <Paper sx={{ ...modalSx }}>
                <Typography variant="h6" component="h2">
                {t('PositionHistoryModal')}
                </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<PositionModalRow>) => {
                          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 PositionHistoryModal