import { TimeEntry, RecordTimesheetInput } from "@/app/api/timesheets/actions";
import { manhourFormatter, shortDateFormatter } from "@/app/utils/formatUtil";
import { Add, Edit } from "@mui/icons-material";
import {
  Box,
  Button,
  Card,
  CardContent,
  IconButton,
  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 { AssignedProject, ProjectWithTasks } from "@/app/api/projects";
import TimesheetEditModal, {
  Props as TimesheetEditModalProps,
} from "./TimesheetEditModal";
import TimeEntryCard from "./TimeEntryCard";

interface Props {
  date: string;
  allProjects: ProjectWithTasks[];
  assignedProjects: AssignedProject[];
}

const MobileTimesheetEntry: React.FC<Props> = ({
  date,
  allProjects,
  assignedProjects,
}) => {
  const {
    t,
    i18n: { language },
  } = useTranslation("home");

  const projectMap = useMemo(() => {
    return allProjects.reduce<{
      [id: ProjectWithTasks["id"]]: ProjectWithTasks;
    }>((acc, project) => {
      return { ...acc, [project.id]: project };
    }, {});
  }, [allProjects]);

  const dayJsObj = dayjs(date);
  const { watch, setValue } = useFormContext<RecordTimesheetInput>();
  const currentEntries = watch(date);

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

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

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

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

  return (
    <>
      <Typography
        paddingInline={2}
        variant="overline"
        color={dayJsObj.day() === 0 ? "error.main" : undefined}
      >
        {shortDateFormatter(language).format(dayJsObj.toDate())}
      </Typography>
      <Box
        paddingInline={2}
        flex={1}
        display="flex"
        flexDirection="column"
        gap={2}
        overflow="scroll"
      >
        {currentEntries.length ? (
          currentEntries.map((entry, index) => {
            const project = entry.projectId
              ? projectMap[entry.projectId]
              : undefined;

            const task = project?.tasks.find((t) => t.id === entry.taskId);

            return (
              <TimeEntryCard
                key={`${entry.id}-${index}`}
                project={project}
                task={task}
                entry={entry}
                onEdit={openEditModal(entry)}
              />
            );
          })
        ) : (
          <Typography variant="body2" display="block">
            {t("Add some time entries!")}
          </Typography>
        )}
        <Box>
          <Button startIcon={<Add />} onClick={openEditModal()}>
            {t("Record leave")}
          </Button>
        </Box>
        <TimesheetEditModal
          allProjects={allProjects}
          assignedProjects={assignedProjects}
          open={editModalOpen}
          onClose={closeEditModal}
          onSave={onSaveEntry}
          {...editModalProps}
        />
      </Box>
    </>
  );
};

export default MobileTimesheetEntry;
