import { LeaveType } from "@/app/api/timesheets";
import { LeaveEntry, RecordLeaveInput } from "@/app/api/timesheets/actions";
import { shortDateFormatter } from "@/app/utils/formatUtil";
import { Add } from "@mui/icons-material";
import { Box, Button, Typography } from "@mui/material";
import dayjs from "dayjs";
import React, { useCallback, useMemo, useState } from "react";
import { useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import LeaveEditModal, { Props as LeaveEditModalProps } from "./LeaveEditModal";
import LeaveEntryCard from "./LeaveEntryCard";
import { HolidaysResult } from "@/app/api/holidays";
import { getHolidayForDate } from "@/app/utils/holidayUtils";

interface Props {
  date: string;
  leaveTypes: LeaveType[];
  companyHolidays: HolidaysResult[];
}

const MobileLeaveEntry: React.FC<Props> = ({
  date,
  leaveTypes,
  companyHolidays,
}) => {
  const {
    t,
    i18n: { language },
  } = useTranslation("home");
  const dayJsObj = dayjs(date);
  const holiday = getHolidayForDate(date, companyHolidays);
  const isHoliday = holiday || dayJsObj.day() === 0 || dayJsObj.day() === 6;

  const leaveTypeMap = useMemo<{ [id: LeaveType["id"]]: LeaveType }>(() => {
    return leaveTypes.reduce(
      (acc, leaveType) => ({ ...acc, [leaveType.id]: leaveType }),
      {},
    );
  }, [leaveTypes]);

  const { watch, setValue, clearErrors } = useFormContext<RecordLeaveInput>();
  const currentEntries = watch(date);

  // Edit modal
  const [editModalProps, setEditModalProps] = useState<
    Partial<LeaveEditModalProps>
  >({});
  const [editModalOpen, setEditModalOpen] = useState(false);

  const openEditModal = useCallback(
    (defaultValues?: LeaveEntry) => () => {
      setEditModalProps({
        defaultValues: defaultValues ? { ...defaultValues } : undefined,
        onDelete: defaultValues
          ? async () => {
              setValue(
                date,
                currentEntries.filter((entry) => entry.id !== defaultValues.id),
              );
              clearErrors(date);
              setEditModalOpen(false);
            }
          : undefined,
      });
      setEditModalOpen(true);
    },
    [clearErrors, currentEntries, date, setValue],
  );

  const closeEditModal = useCallback(() => {
    setEditModalOpen(false);
  }, []);

  const onSaveEntry = useCallback(
    async (entry: LeaveEntry) => {
      const existingEntry = currentEntries.find((e) => e.id === entry.id);
      if (existingEntry) {
        setValue(
          date,
          currentEntries.map((e) => ({
            ...(e.id === existingEntry.id ? entry : e),
          })),
        );
        clearErrors(date);
      } else {
        setValue(date, [...currentEntries, entry]);
      }
      setEditModalOpen(false);
    },
    [clearErrors, currentEntries, date, setValue],
  );

  return (
    <>
      <Typography
        paddingInline={2}
        variant="overline"
        color={isHoliday ? "error.main" : undefined}
      >
        {shortDateFormatter(language).format(dayJsObj.toDate())}
        {holiday && (
          <Typography
            marginInlineStart={1}
            variant="caption"
          >{`(${holiday.title})`}</Typography>
        )}
      </Typography>
      <Box
        paddingInline={2}
        flex={1}
        display="flex"
        flexDirection="column"
        gap={2}
        overflow="scroll"
      >
        {currentEntries.length ? (
          currentEntries.map((entry, index) => {
            return (
              <LeaveEntryCard
                key={`${entry.id}-${index}`}
                entry={entry}
                onEdit={openEditModal(entry)}
                leaveTypeMap={leaveTypeMap}
              />
            );
          })
        ) : (
          <Typography variant="body2" display="block">
            {t("Add some leave entries!")}
          </Typography>
        )}
        <Box>
          <Button startIcon={<Add />} onClick={openEditModal()}>
            {t("Record leave")}
          </Button>
        </Box>
        <LeaveEditModal
          leaveTypes={leaveTypes}
          open={editModalOpen}
          onClose={closeEditModal}
          onSave={onSaveEntry}
          isHoliday={Boolean(isHoliday)}
          {...editModalProps}
        />
      </Box>
    </>
  );
};

export default MobileLeaveEntry;
