"use client";
import {
  FooterPropsOverrides,
  GridActionsCellItem,
  GridCellParams,
  GridRowId,
  GridRowIdGetter,
  GridRowModel,
  GridRowModes,
  GridRowModesModel,
  GridToolbarContainer,
  useGridApiRef,
} from "@mui/x-data-grid";
import {
  Dispatch,
  MutableRefObject,
  SetStateAction,
  useCallback,
  useEffect,
  useMemo,
  useState,
} from "react";
import StyledDataGrid from "../StyledDataGrid";
import { GridColDef } from "@mui/x-data-grid";
import { Box, Button, Grid, Icon, Typography } from "@mui/material";
import { useTranslation } from "react-i18next";
import { Add } from "@mui/icons-material";
import SaveIcon from "@mui/icons-material/Save";
import DeleteIcon from "@mui/icons-material/Delete";
import CancelIcon from "@mui/icons-material/Cancel";
import FactCheckIcon from "@mui/icons-material/FactCheck";
import ShoppingCartIcon from "@mui/icons-material/ShoppingCart";
// import PoQcModal from "./PoQcModal";
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
import { useSearchParams } from "next/navigation";
import { decimalFormatter } from "@/app/utils/formatUtil";
import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
import HighlightOffIcon from "@mui/icons-material/HighlightOff";
import {
  DetailedProdScheduleLineBomMaterialResult,
  RoughProdScheduleLineBomMaterialResult,
  ScheduleType,
} from "@/app/api/scheduling";

interface ResultWithId {
  id: number;
}

interface Props {
  bomMaterial: RoughProdScheduleLineBomMaterialResult[] | DetailedProdScheduleLineBomMaterialResult[];
  type: ScheduleType;
}

export type BomMaterialEntryError = {
  [field in keyof any]?: string;
};

export type BomMaterialRow = Partial<
  any & {
    isActive: boolean | undefined;
    _isNew: boolean;
    _error: BomMaterialEntryError;
  } & ResultWithId
>;

class ProcessRowUpdateError extends Error {
  public readonly row: BomMaterialRow;
  public readonly errors: BomMaterialEntryError | undefined;
  constructor(
    row: BomMaterialRow,
    message?: string,
    errors?: BomMaterialEntryError,
  ) {
    super(message);
    this.row = row;
    this.errors = errors;

    Object.setPrototypeOf(this, ProcessRowUpdateError.prototype);
  }
}

function BomMaterialTable({ bomMaterial }: Props) {
  const { t } = useTranslation("schedule");
  const apiRef = useGridApiRef();
  const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
  const getRowId = useCallback<GridRowIdGetter<BomMaterialRow>>(
    (row) => row.id as number,
    [],
  );
  const [entries, setEntries] = useState<BomMaterialRow[]>(bomMaterial || []);

  const columns = useMemo<GridColDef[]>(
    () => [
      {
        field: "code",
        headerName: t("Code"),
        flex: 1,
      },
      {
        field: "name",
        headerName: t("Name"),
        flex: 1,
      },
      {
        field: "type",
        headerName: t("type"),
        flex: 1,
        renderCell: (row) => {
          return t(row.value);
        },
      },
      {
        field: "availableQty",
        headerName: t("Available Qty"),
        flex: 1,
        type: "number",
        // editable: true,
        align: "right",
        headerAlign: "right",
        renderCell: (row) => {
          return decimalFormatter.format(row.value);
        },
        // replace with tooltip + content
      },
      {
        field: "demandQty",
        headerName: t("Demand Qty"),
        flex: 1,
        // editable: true,
        align: "right",
        headerAlign: "right",
        renderCell: (row) => {
          return decimalFormatter.format(row.value);
        },
      },
      {
        field: "uomName",
        headerName: t("UoM"),
        flex: 1,
        align: "left",
        headerAlign: "left",
        renderCell: (row) => {
          return row.value;
        },
      },
      {
        field: "status",
        headerName: t("status"),
        flex: 0.7,
        // editable: true,
        align: "center",
        headerAlign: "center",
        renderCell: (params) => {
          return params.row.availableQty - params.row.demandQty >= 0 ? (
            <CheckCircleOutlineIcon color="success" fontSize="small" />
          ) : (
            <HighlightOffIcon color="error" fontSize="small" />
          );
        },
      },
    ],
    [],
  );
  const validation = useCallback(
    (
      newRow: GridRowModel<BomMaterialRow>,
    ): BomMaterialEntryError | undefined => {
      const error: BomMaterialEntryError = {};
      console.log(newRow);
      return Object.keys(error).length > 0 ? error : undefined;
    },
    [],
  );
  const processRowUpdate = useCallback(
    (
      newRow: GridRowModel<BomMaterialRow>,
      originalRow: GridRowModel<BomMaterialRow>,
    ) => {
      const errors = validation(newRow); // change to validation
      if (errors) {
        throw new ProcessRowUpdateError(
          originalRow,
          "validation error",
          errors,
        );
      }
      const { _isNew, _error, ...updatedRow } = newRow;
      const rowToSave = {
        ...updatedRow,
      } satisfies BomMaterialRow;
      const newEntries = entries.map((e) =>
        getRowId(e) === getRowId(originalRow) ? rowToSave : e,
      );
      setEntries(newEntries);
      //update remaining qty
      const total = newEntries.reduce(
        (acc, curr) => acc + (curr.acceptedQty || 0),
        0,
      );
      return rowToSave;
    },
    [getRowId, entries],
  );

  const onProcessRowUpdateError = useCallback(
    (updateError: ProcessRowUpdateError) => {
      const errors = updateError.errors;
      const oldRow = updateError.row;

      apiRef.current.updateRows([{ ...oldRow, _error: errors }]);
    },
    [apiRef],
  );

  return (
    <>
      <StyledDataGrid
        getRowId={getRowId}
        apiRef={apiRef}
        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
        // editMode="row"
        rows={entries}
        rowModesModel={rowModesModel}
        onRowModesModelChange={setRowModesModel}
        processRowUpdate={processRowUpdate}
        onProcessRowUpdateError={onProcessRowUpdateError}
        columns={columns}
        getCellClassName={(params: GridCellParams<BomMaterialRow>) => {
          let classname = "";
          if (params.row._error) {
            classname = "hasError";
          }
          return classname;
        }}
        // slots={{
        //   footer: FooterToolbar,
        //   noRowsOverlay: NoRowsOverlay,
        // }}
        // slotProps={{
        //   footer: { child: footer },
        // }}
      />
    </>
  );
}
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>
  );
};

const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => {
  return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>;
};
export default BomMaterialTable;
