"use client";
import Grid from "@mui/material/Grid";
import Paper from "@mui/material/Paper";
import { useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import PageTitle from "../PageTitle/PageTitle";
import { Suspense } from "react";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import Link from "next/link";
import {
  Box, Card, Typography,
} from "@mui/material";
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 AddPhotoAlternateOutlinedIcon from "@mui/icons-material/AddPhotoAlternateOutlined";
import ImageNotSupportedOutlinedIcon from "@mui/icons-material/ImageNotSupportedOutlined";
import React from "react";
import {
  GridRowsProp,
  GridRowModesModel,
  GridRowModes,
  DataGrid,
  GridColDef,
  GridActionsCellItem,
  GridEventListener,
  GridRowId,
  GridRowModel,
  GridRowEditStopReasons,
  GridEditInputCell,
  GridTreeNodeWithRender,
  GridRenderCellParams,
} from "@mui/x-data-grid";
import dayjs from "dayjs";
import { Props } from "react-intl/src/components/relative";
import palette from "@/theme/devias-material-kit/palette";
import { ProjectCombo } from "@/app/api/claims";
import { ClaimDetailTable, ClaimInputFormByStaff } from "@/app/api/claims/actions";
import { useFieldArray, useFormContext } from "react-hook-form";
import { GridRenderEditCellParams } from "@mui/x-data-grid";
import { convertDateToString, moneyFormatter } from "@/app/utils/formatUtil";

interface BottomBarProps {
  getCostTotal: () => number;
  setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void;
  setRowModesModel: (
    newModel: (oldModel: GridRowModesModel) => GridRowModesModel,
  ) => void;
}

interface EditFooterProps {
  setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void;
  setRowModesModel: (
    newModel: (oldModel: GridRowModesModel) => GridRowModesModel,
  ) => void;
}

const BottomBar = (props: BottomBarProps) => {
  const { t } = useTranslation("claim")
  const { setRows, setRowModesModel, getCostTotal } = props;
  // const getCostTotal = props.getCostTotal;
  const [newId, setNewId] = useState(-1);

  const handleAddClick = () => {
    const id = newId;
    setNewId(newId - 1);
    setRows((oldRows) => [
      ...oldRows,
      { id, invoiceDate: new Date(), project: null, description: null, amount: null, newSupportingDocument: null, supportingDocumentName: null, isNew: true },
    ]);
    setRowModesModel((oldModel) => ({
      ...oldModel,
      [id]: { mode: GridRowModes.Edit, fieldToFocus: "projectCode" },
    }));
  };

  const TotalCell = ({ value }: Props) => {
    const [invalid, setInvalid] = useState(false);

    useEffect(() => {
      const newInvalid = (value ?? 0) < 0;
      setInvalid(newInvalid);
    }, [value]);

    return (
      <Box flex={1} style={{ color: invalid ? "red" : "black" }}>
        $ {value}
      </Box>
    );
  };

  return (
    <div>
      <div style={{ display: "flex", justifyContent: "flex", width: "100%" }}>
        <Box flex={1.5} textAlign={"right"} marginRight="4rem">
          <b>{t("Total")}:</b>
        </Box>
        <TotalCell value={getCostTotal()} />
      </div>
      <Button
        variant="outlined"
        color="primary"
        startIcon={<AddIcon />}
        onClick={handleAddClick}
        sx={{ margin: "20px" }}
      >
        {t("Add Record")}
      </Button>
    </div>
  );
};

const EditFooter = (props: EditFooterProps) => {
  return (
    <div style={{ display: "flex", justifyContent: "flex", width: "100%" }}>
      <Box flex={1}>
        <b>Total: </b>
      </Box>
      <Box flex={2}>test</Box>
    </div>
  );
};

interface ClaimFormInputGridProps {
  // onClose?: () => void;
  projectCombo: ProjectCombo[]
}

const initialRows: GridRowsProp = [
  {
    id: 1,
    invoiceDate: new Date(),
    description: "Taxi to client office",
    amount: 169.5,
    supportingDocumentName: "taxi_receipt.jpg",
  },
  {
    id: 2,
    invoiceDate: dayjs().add(-14, "days").toDate(),
    description: "MTR fee to Kowloon Bay Office",
    amount: 15.5,
    supportingDocumentName: "octopus_invoice.jpg",
  },
  {
    id: 3,
    invoiceDate: dayjs().add(-44, "days").toDate(),
    description: "Starbucks",
    amount: 504,
  },
];

const ClaimFormInputGrid: React.FC<ClaimFormInputGridProps> = ({
  // onClose,
  projectCombo,
}) => {
  const { t } = useTranslation()
  const { control, setValue, getValues, formState: { errors }, clearErrors, setError } = useFormContext<ClaimInputFormByStaff>();
  const { fields } = useFieldArray({
    control,
    name: "addClaimDetails"
  })

  const [rows, setRows] = useState<GridRowsProp>([]);
  const [rowModesModel, setRowModesModel] = React.useState<GridRowModesModel>(
    {},
  );

  // Row function
  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 } });
  };

  const handleDeleteClick = (id: GridRowId) => () => {
    setRows(rows.filter((row) => row.id !== 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 = React.useCallback((newRow: GridRowModel) => {
    const updatedRow = { ...newRow };
    const updatedRows = rows.map((row) => (row.id === newRow.id ? { ...updatedRow, supportingDocumentName: row.supportingDocumentName } : row))
    setRows(updatedRows);
    setValue("addClaimDetails", updatedRows as ClaimDetailTable[])
    return updatedRows.find((row) => row.id === newRow.id) as GridRowModel;
  }, [rows, rowModesModel, t]);

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

  // File Upload function
  const fileInputRef: React.RefObject<Record<string, HTMLInputElement | null>> = React.useRef({})

  const setFileInputRefs = (ele: HTMLInputElement | null, key: string) => {
    if (fileInputRef.current !== null) {
      fileInputRef.current[key] = ele
    }
  }

  useEffect(() => {

  }, [])
  const handleFileSelect = (key: string) => {
    if (fileInputRef !== null && fileInputRef.current !== null && fileInputRef.current[key] !== null) {
      fileInputRef.current[key]?.click()
    }
  }

  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>, params: GridRenderEditCellParams<any, any, any, GridTreeNodeWithRender>) => {

    const file = event.target.files?.[0] ?? null

    if (file !== null) {
      console.log(file)
      console.log(typeof file)
      const updatedRows = rows.map((row) => (row.id === params.row.id ? { ...row, supportingDocumentName: file.name, newSupportingDocument: file } : row))
      setRows(updatedRows);
      setValue("addClaimDetails", updatedRows as ClaimDetailTable[])
      // const url = URL.createObjectURL(new Blob([file]));
      // const link = document.createElement("a");
      // link.href = url;
      // link.setAttribute("download", file.name);
      // link.click();
    }
  }

  const handleFileDelete = (id: number) => {
    const updatedRows = rows.map((row) => (row.id === id ? { ...row, supportingDocumentName: null, newSupportingDocument: null } : row))
    setRows(updatedRows);
    setValue("addClaimDetails", updatedRows as ClaimDetailTable[])
  }

  const handleLinkClick = (params: GridRenderEditCellParams<any, any, any, GridTreeNodeWithRender>) => {

    const url = URL.createObjectURL(new Blob([params.row.newSupportingDocument]));
    const link = document.createElement("a");
    link.href = url;
    link.setAttribute("download", params.row.supportingDocumentName);
    link.click();

    // console.log(params)
    // console.log(rows)
  }

  // columns
  const getCostTotal = () => {
    let sum = 0;
    rows.forEach((row) => {
      sum += row["amount"] ?? 0;
    });
    return sum;
  };

  const commonGridColConfig: any = {
    type: "number",
    // sortable: false,
    //width: 100,
    flex: 1,
    align: "left",
    headerAlign: "left",
    // headerClassName: 'header',
    editable: true,
    renderEditCell: (value: any) => (
      <GridEditInputCell
        {...value}
        inputProps={{
          max: 24,
          min: 0,
          step: 0.25,
        }}
      />
    ),
  };

  const columns: GridColDef[] = React.useMemo(() => [
    {
      field: "actions",
      type: "actions",
      headerName: t("Actions"),
      width: 100,
      cellClassName: "actions",
      getActions: ({ id }) => {
        const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;

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

        return [
          <GridActionsCellItem
            key={`actions-${id}-edit`}
            icon={<EditIcon />}
            title="Edit"
            label="Edit"
            className="textPrimary"
            onClick={handleEditClick(id)}
            color="inherit"
          />,
          <GridActionsCellItem
            key={`actions-${id}-delete`}
            title="Delete"
            label="Delete"
            icon={<DeleteIcon />}
            onClick={handleDeleteClick(id)}
            sx={{ color: "red" }}
          />,
        ];
      },
    },
    {
      field: "invoiceDate",
      headerName: t("Invoice Date"),
      // width: 220,
      flex: 1,
      editable: true,
      type: "date",
      renderCell: (params: GridRenderCellParams<any, Date>) => {
        return convertDateToString(params.value!!)
      },
    },
    {
      field: "project",
      headerName: t("Project"),
      // width: 220,
      flex: 1,
      editable: true,
      type: "singleSelect",
      getOptionLabel: (value: ProjectCombo) => {
        return !value?.code || value?.code.length === 0 ? `${value?.name}` : `${value?.code} - ${value?.name}`;
      },
      getOptionValue: (value: ProjectCombo) => value.id,
      valueOptions: () => {
        const options = projectCombo ?? []

        if (options.length === 0) {
          options.push({ id: -1, code: "", name: "No Projects" })
        }

        return options as ProjectCombo[];
      },
      valueGetter: (params) => {
        return params.value ?? projectCombo[0] ?? { id: -1, code: "", name: "No Projects" } as ProjectCombo
      },
    },
    {
      field: "description",
      headerName: t("Description"),
      // width: 220,
      flex: 2,
      editable: true,
      type: "string",
    },
    {
      field: "amount",
      headerName: t("Amount"),
      editable: true,
      type: "number",
      align: "right",
      valueFormatter: (params) => {
        return moneyFormatter.format(params.value ?? 0);
      },
    },
    {
      field: "supportingDocumentName",
      headerName: t("Supporting Document"),
      // type: "string",
      editable: true,
      flex: 2,
      renderCell: (params) => {
        return params.value ? (
          <span>
            <Link onClick={() => handleLinkClick(params)} href="#">{params.value}</Link>
            {/* <a href="" target="_blank" rel="noopener noreferrer">
              {params.value}
            </a> */}
          </span>
        ) : (
          <span style={{ color: palette.text.disabled }}>No Documents</span>
        );
      },
      renderEditCell: (params) => {
        // const currentRow = rows.find(row => row.id === params.row.id);
        return params.formattedValue ? (
          <span>
            <Link onClick={() => handleLinkClick(params)} href="#">{params.formattedValue}</Link>
            {/* <a href="" target="_blank" rel="noopener noreferrer">
              {params.formattedValue}
            </a> */}
            <Button
              title="Remove Document"
              onClick={() => handleFileDelete(params.row.id)}
            >
              <ImageNotSupportedOutlinedIcon
                sx={{ fontSize: "25px", color: "red" }}
              />
            </Button>
          </span>
        ) : (
          <div>
            <input
              type="file"
              ref={ele => setFileInputRefs(ele, params.row.id)}
              accept="image/jpg, image/jpeg, image/png, .doc, .docx, .pdf"
              style={{ display: 'none' }}
              onChange={(event) => handleFileChange(event, params)}
            />
            <Button title="Add Document" onClick={() => handleFileSelect(params.row.id)}>
              <AddPhotoAlternateOutlinedIcon
                sx={{ fontSize: "25px", color: "green" }}
              />
            </Button>
          </div>
        );
      },
    },
  ], [rows, rowModesModel, t],);

  // check error
  useEffect(() => {
    if (getValues("addClaimDetails") === undefined || getValues("addClaimDetails") === null) {
      return;
    }

    if (getValues("addClaimDetails").length === 0) {
      clearErrors("addClaimDetails")
    } else {

      console.log(rows)
      if (rows.filter(row => String(row.description).trim().length === 0 || String(row.amount).trim().length === 0 || row.project === null || row.project === undefined || ((row.oldSupportingDocument === null || row.oldSupportingDocument === undefined) && (row.newSupportingDocument === null || row.newSupportingDocument === undefined))).length > 0) {
        setError("addClaimDetails", { message: "Claim details include empty fields", type: "required" })
      } else {
        let haveError = false

        if (rows.filter(row => row.invoiceDate.getTime() > new Date().getTime()).length > 0) {
          haveError = true
          setError("addClaimDetails", { message: "Claim details include invalid invoice date", type: "invalid_date" })
        }

        if (rows.filter(row => row.project === null || row.project === undefined).length > 0) {
          haveError = true
          setError("addClaimDetails", { message: "Claim details include empty project", type: "invalid_project" })
        }

        if (rows.filter(row => row.amount <= 0).length > 0) {
          haveError = true
          setError("addClaimDetails", { message: "Claim details include invalid amount", type: "invalid_amount" })
        }

        if (!haveError) {
          clearErrors("addClaimDetails")
        }
      }
    }
  }, [rows, rowModesModel])

  // check editing
  useEffect(() => {
    const filteredByKey = Object.fromEntries(
      Object.entries(rowModesModel).filter(([key, value]) => rowModesModel[key].mode === 'edit'))

    if (Object.keys(filteredByKey).length > 0) {
      setValue("isGridEditing", true)
    } else {
      setValue("isGridEditing", false)
    }
  }, [rowModesModel])

  return (
    <Box
      sx={{
        // marginBottom: '-5px',
        display: "flex",
        "flex-direction": "column",
        // 'justify-content': 'flex-end',
        height: "100%", //'25rem',
        width: "100%",
        "& .actions": {
          color: "text.secondary",
        },
        "& .header": {
          backgroundColor: "#F8F9FA",
          // border: 1,
          // 'border-width': '1px',
          // 'border-color': 'grey',
        },
        "& .textPrimary": {
          color: "text.primary",
        },
      }}
    >
      {Boolean(errors.addClaimDetails?.type === "required") && <Typography sx={(theme) => ({ color: theme.palette.error.main, ml: 3, mt: 1 })} variant="overline" display='inline-block' noWrap>
        {t("Please ensure at least one row is created, and all the fields are inputted and saved")}
      </Typography>}
      {Boolean(errors.addClaimDetails?.type === "invalid_date") && <Typography sx={(theme) => ({ color: theme.palette.error.main, ml: 3, mt: 1 })} variant="overline" display='inline-block' noWrap>
        {t("Please ensure the date are correct")}
      </Typography>}
      {Boolean(errors.addClaimDetails?.type === "invalid_project") && <Typography sx={(theme) => ({ color: theme.palette.error.main, ml: 3, mt: 1 })} variant="overline" display='inline-block' noWrap>
        {t("Please ensure the projects are selected")}
      </Typography>}
      {Boolean(errors.addClaimDetails?.type === "invalid_amount") && <Typography sx={(theme) => ({ color: theme.palette.error.main, ml: 3, mt: 1 })} variant="overline" display='inline-block' noWrap>
        {t("Please ensure the amount are correct")}
      </Typography>}
      <div style={{ height: 400, width: "100%" }}>
        <DataGrid
          sx={{ flex: 1 }}
          rows={rows}
          columns={columns}
          editMode="row"
          rowModesModel={rowModesModel}
          onRowModesModelChange={handleRowModesModelChange}
          onRowEditStop={handleRowEditStop}
          processRowUpdate={processRowUpdate}
          disableRowSelectionOnClick={true}
          disableColumnMenu={true}
          // hideFooterPagination={true}
          slots={
            {
              // footer: EditFooter,
            }
          }
          slotProps={
            {
              // footer: { setDay, setRows, setRowModesModel },
            }
          }
          initialState={{
            pagination: { paginationModel: { pageSize: 5 } },
          }}
        />
      </div>
      <BottomBar
        getCostTotal={getCostTotal}
        setRows={setRows}
        setRowModesModel={setRowModesModel}
      // sx={{flex:2}}
      />
    </Box>
  );
};

export default ClaimFormInputGrid;
