import React, { useCallback, useMemo } from "react";
import {
  Box,
  Button,
  Card,
  CardActions,
  CardContent,
  Modal,
  ModalProps,
  SxProps,
  Typography,
} from "@mui/material";
import TimesheetTable from "../TimesheetTable";
import { useTranslation } from "react-i18next";
import { Check, Close } from "@mui/icons-material";
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import {
  RecordTimesheetInput,
  saveTimesheet,
} from "@/app/api/timesheets/actions";
import dayjs from "dayjs";
import { INPUT_DATE_FORMAT } from "@/app/utils/formatUtil";
import { AssignedProject, ProjectWithTasks } from "@/app/api/projects";

interface Props {
  isOpen: boolean;
  onClose: () => void;
  allProjects: ProjectWithTasks[];
  assignedProjects: AssignedProject[];
  username: string;
  defaultTimesheets?: RecordTimesheetInput;
}

const modalSx: SxProps = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: { xs: "calc(100% - 2rem)", sm: "90%" },
  maxHeight: "90%",
  maxWidth: 1200,
};

const TimesheetModal: React.FC<Props> = ({
  isOpen,
  onClose,
  allProjects,
  assignedProjects,
  username,
  defaultTimesheets,
}) => {
  const { t } = useTranslation("home");

  const defaultValues = useMemo(() => {
    const today = dayjs();
    return Array(7)
      .fill(undefined)
      .reduce<RecordTimesheetInput>((acc, _, index) => {
        const date = today.subtract(index, "day").format(INPUT_DATE_FORMAT);
        return {
          ...acc,
          [date]: defaultTimesheets?.[date] ?? [],
        };
      }, {});
  }, [defaultTimesheets]);

  const formProps = useForm<RecordTimesheetInput>({ defaultValues });

  const onSubmit = useCallback<SubmitHandler<RecordTimesheetInput>>(
    async (data) => {
      const savedRecords = await saveTimesheet(data, username);

      const today = dayjs();
      const newFormValues = Array(7)
        .fill(undefined)
        .reduce<RecordTimesheetInput>((acc, _, index) => {
          const date = today.subtract(index, "day").format(INPUT_DATE_FORMAT);
          return {
            ...acc,
            [date]: savedRecords[date] ?? [],
          };
        }, {});

      formProps.reset(newFormValues);
      onClose();
    },
    [formProps, onClose, username],
  );

  const onCancel = useCallback(() => {
    formProps.reset(defaultValues);
    onClose();
  }, [defaultValues, formProps, onClose]);

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

  return (
    <Modal open={isOpen} onClose={onModalClose}>
      <Card sx={modalSx}>
        <FormProvider {...formProps}>
          <CardContent
            component="form"
            onSubmit={formProps.handleSubmit(onSubmit)}
          >
            <Typography variant="overline" display="block" marginBlockEnd={1}>
              {t("Timesheet Input")}
            </Typography>
            <Box
              sx={{
                marginInline: -3,
                marginBlock: 4,
              }}
            >
              <TimesheetTable
                assignedProjects={assignedProjects}
                allProjects={allProjects}
              />
            </Box>
            <CardActions sx={{ justifyContent: "flex-end" }}>
              <Button
                variant="outlined"
                startIcon={<Close />}
                onClick={onCancel}
              >
                {t("Cancel")}
              </Button>
              <Button variant="contained" startIcon={<Check />} type="submit">
                {t("Save")}
              </Button>
            </CardActions>
          </CardContent>
        </FormProvider>
      </Card>
    </Modal>
  );
};

export default TimesheetModal;
