import { LeaveType } from "@/app/api/timesheets";
import { LeaveEntry } from "@/app/api/timesheets/actions";
import { LEAVE_DAILY_MAX_HOURS } from "@/app/api/timesheets/utils";
import { roundToNearestQuarter } from "@/app/utils/manhourUtils";
import { Check, Delete } from "@mui/icons-material";
import {
  Box,
  Button,
  FormControl,
  InputLabel,
  MenuItem,
  Modal,
  ModalProps,
  Paper,
  Select,
  SxProps,
  TextField,
} from "@mui/material";
import React, { useCallback, useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";

export interface Props extends Omit<ModalProps, "children"> {
  onSave: (leaveEntry: LeaveEntry) => void;
  onDelete?: () => void;
  leaveTypes: LeaveType[];
  defaultValues?: Partial<LeaveEntry>;
}

const modalSx: SxProps = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: "90%",
  maxHeight: "90%",
  padding: 3,
  display: "flex",
  flexDirection: "column",
  gap: 2,
};
const LeaveEditModal: React.FC<Props> = ({
  onSave,
  onDelete,
  open,
  onClose,
  leaveTypes,
  defaultValues,
}) => {
  const { t } = useTranslation("home");
  const { register, control, reset, getValues, trigger, formState } =
    useForm<LeaveEntry>({
      defaultValues: {
        leaveTypeId: leaveTypes[0].id,
      },
    });

  useEffect(() => {
    reset(defaultValues ?? { leaveTypeId: leaveTypes[0].id, id: Date.now() });
  }, [defaultValues, leaveTypes, reset]);

  const saveHandler = useCallback(async () => {
    const valid = await trigger();
    if (valid) {
      onSave(getValues());
      reset({ id: Date.now() });
    }
  }, [getValues, onSave, reset, trigger]);

  const closeHandler = useCallback<NonNullable<ModalProps["onClose"]>>(
    (...args) => {
      onClose?.(...args);
      reset({ id: Date.now() });
    },
    [onClose, reset],
  );

  return (
    <Modal open={open} onClose={closeHandler}>
      <Paper sx={modalSx}>
        <FormControl fullWidth>
          <InputLabel>{t("Leave Type")}</InputLabel>
          <Controller
            defaultValue={leaveTypes[0].id}
            control={control}
            name="leaveTypeId"
            render={({ field }) => (
              <Select label={t("Leave Type")} {...field}>
                {leaveTypes.map((type, index) => (
                  <MenuItem key={`${type.id}-${index}`} value={type.id}>
                    {type.name}
                  </MenuItem>
                ))}
              </Select>
            )}
          />
        </FormControl>
        <TextField
          type="number"
          label={t("Hours")}
          fullWidth
          {...register("inputHours", {
            setValueAs: (value) => roundToNearestQuarter(parseFloat(value)),
            validate: (value) =>
              (0 < value && value <= LEAVE_DAILY_MAX_HOURS) ||
              t(
                "Input hours should be between 0 and {{LEAVE_DAILY_MAX_HOURS}}",
                { LEAVE_DAILY_MAX_HOURS },
              ),
          })}
          error={Boolean(formState.errors.inputHours)}
          helperText={formState.errors.inputHours?.message}
        />
        <TextField
          label={t("Remark")}
          fullWidth
          multiline
          rows={2}
          {...register("remark")}
        />
        <Box display="flex" justifyContent="flex-end" gap={1}>
          {onDelete && (
            <Button
              variant="outlined"
              startIcon={<Delete />}
              color="error"
              onClick={onDelete}
            >
              {t("Delete")}
            </Button>
          )}
          <Button
            variant="contained"
            startIcon={<Check />}
            onClick={saveHandler}
          >
            {t("Save")}
          </Button>
        </Box>
      </Paper>
    </Modal>
  );
};

export default LeaveEditModal;
