import {
  RecordLeaveInput,
  RecordTimesheetInput,
} from "@/app/api/timesheets/actions";
import { manhourFormatter, shortDateFormatter } from "@/app/utils/formatUtil";
import { Info, KeyboardArrowDown, KeyboardArrowUp } from "@mui/icons-material";
import {
  Box,
  Collapse,
  IconButton,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Tooltip,
  Typography,
} from "@mui/material";
import dayjs from "dayjs";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import {
  DAILY_NORMAL_MAX_HOURS,
  TIMESHEET_DAILY_MAX_HOURS,
} from "@/app/api/timesheets/utils";
import { HolidaysResult } from "@/app/api/holidays";
import { getHolidayForDate } from "@/app/utils/holidayUtils";

interface Props<EntryTableProps = object> {
  days: string[];
  leaveEntries: RecordLeaveInput;
  timesheetEntries: RecordTimesheetInput;
  companyHolidays: HolidaysResult[];
  EntryTableComponent: React.FunctionComponent<
    EntryTableProps & { day: string; isHoliday: boolean }
  >;
  entryTableProps: EntryTableProps;
  isSaturdayWorker: boolean
}

function DateHoursTable<EntryTableProps>({
  days,
  EntryTableComponent,
  entryTableProps,
  leaveEntries,
  timesheetEntries,
  companyHolidays,
  isSaturdayWorker,
}: Props<EntryTableProps>) {
  const { t } = useTranslation("home");
  return (
    <TableContainer sx={{ maxHeight: 400 }}>
      <Table stickyHeader>
        <TableHead>
          <TableRow>
            <TableCell />
            <TableCell>{t("Date")}</TableCell>
            <TableCell>{t("Timesheet Hours")}</TableCell>
            <TableCell>{t("Leave Hours")}</TableCell>
            <TableCell>{t("Daily Total Hours")}</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {days.map((day, index) => {
            return (
              <DayRow
                key={`${day}${index}`}
                day={day}
                companyHolidays={companyHolidays}
                leaveEntries={leaveEntries}
                timesheetEntries={timesheetEntries}
                EntryTableComponent={EntryTableComponent}
                entryTableProps={entryTableProps}
                isSaturdayWorker={isSaturdayWorker}
              />
            );
          })}
        </TableBody>
      </Table>
    </TableContainer>
  );
}

function DayRow<EntryTableProps>({
  day,
  leaveEntries,
  timesheetEntries,
  entryTableProps,
  EntryTableComponent,
  companyHolidays,
  isSaturdayWorker,
}: {
  day: string;
  companyHolidays: HolidaysResult[];
  leaveEntries: RecordLeaveInput;
  timesheetEntries: RecordTimesheetInput;
  EntryTableComponent: React.FunctionComponent<
    EntryTableProps & { day: string; isHoliday: boolean }
  >;
  entryTableProps: EntryTableProps;
  isSaturdayWorker: boolean
}) {
  const {
    t,
    i18n: { language },
  } = useTranslation("home");
  const dayJsObj = dayjs(day);

  const [open, setOpen] = useState(false);
  const holiday = getHolidayForDate(day, companyHolidays);
  const isWeekend = !isSaturdayWorker ? dayJsObj.day() === 0 || dayJsObj.day() === 6 : dayJsObj.day() === 0;
  const isHoliday = holiday || isWeekend;

  const leaves = leaveEntries[day];
  const leaveHours =
    leaves?.reduce((acc, entry) => acc + entry.inputHours, 0) || 0;

  const timesheet = timesheetEntries[day];
  const timesheetNormalHours =
    timesheet?.reduce((acc, entry) => acc + (entry.inputHours || 0), 0) || 0;
  const timesheetOtHours =
    timesheet?.reduce((acc, entry) => acc + (entry.otHours || 0), 0) || 0;
  const timesheetHours = timesheetNormalHours + timesheetOtHours;

  const dailyTotal = leaveHours + timesheetHours;

  const normalHoursExceeded =
    timesheetNormalHours + leaveHours > DAILY_NORMAL_MAX_HOURS;
  const dailyTotalExceeded = dailyTotal > TIMESHEET_DAILY_MAX_HOURS;

  return (
    <>
      <TableRow>
        <TableCell align="center" width={70}>
          <IconButton
            disableRipple
            aria-label="expand row"
            size="small"
            onClick={() => setOpen(!open)}
          >
            {open ? <KeyboardArrowUp /> : <KeyboardArrowDown />}
          </IconButton>
        </TableCell>
        <TableCell sx={{ color: isHoliday ? "error.main" : undefined }}>
          {shortDateFormatter(language).format(dayJsObj.toDate())}
          {holiday && (
            <Typography
              display="block"
              variant="caption"
            >{`(${holiday.title})`}</Typography>
          )}
        </TableCell>
        {/* Timesheet */}
        <TableCell
          sx={{
            color: normalHoursExceeded ? "error.main" : undefined,
          }}
        >
          <Box display="flex" gap={1} alignItems="center">
            {manhourFormatter.format(timesheetHours)}
            {normalHoursExceeded && (
              <Tooltip
                title={t(
                  "The daily normal hours (timesheet hours + leave hours) cannot be more than {{DAILY_NORMAL_MAX_HOURS}} (timesheet hours: {{timesheetNormalHours}}, leave hours: {{leaveHours}}). Please use other hours for exceeding hours or decrease the leave hours.",
                  {
                    timesheetNormalHours,
                    leaveHours,
                    DAILY_NORMAL_MAX_HOURS,
                  },
                )}
              >
                <Info fontSize="small" />
              </Tooltip>
            )}
          </Box>
        </TableCell>
        {/* Leave total */}
        <TableCell
          sx={{
            color: normalHoursExceeded ? "error.main" : undefined,
          }}
        >
          <Box display="flex" gap={1} alignItems="center">
            {manhourFormatter.format(leaveHours)}
            {normalHoursExceeded && (
              <Tooltip
                title={t(
                  "The daily normal hours (timesheet hours + leave hours) cannot be more than {{DAILY_NORMAL_MAX_HOURS}} (timesheet hours: {{timesheetNormalHours}}, leave hours: {{leaveHours}}). Please use other hours for exceeding hours or decrease the leave hours.",
                  {
                    timesheetNormalHours,
                    leaveHours,
                    DAILY_NORMAL_MAX_HOURS,
                  },
                )}
              >
                <Info fontSize="small" />
              </Tooltip>
            )}
          </Box>
        </TableCell>
        {/* Daily total */}
        <TableCell
          sx={{
            color: dailyTotalExceeded ? "error.main" : undefined,
          }}
        >
          <Box display="flex" gap={1} alignItems="center">
            {manhourFormatter.format(dailyTotal)}
            {dailyTotalExceeded && (
              <Tooltip
                title={t(
                  "The daily total hours cannot be more than {{TIMESHEET_DAILY_MAX_HOURS}}",
                  {
                    TIMESHEET_DAILY_MAX_HOURS,
                  },
                )}
              >
                <Info fontSize="small" />
              </Tooltip>
            )}
          </Box>
        </TableCell>
      </TableRow>
      <TableRow>
        <TableCell
          sx={{
            p: 0,
            border: "none",
            outline: open ? "1px solid" : undefined,
            outlineColor: "primary.main",
          }}
          colSpan={5}
        >
          <Collapse in={open} timeout="auto" unmountOnExit>
            <Box>
              {
                <EntryTableComponent
                  day={day}
                  isHoliday={Boolean(isHoliday)}
                  {...entryTableProps}
                />
              }
            </Box>
          </Collapse>
        </TableCell>
      </TableRow>
    </>
  );
}

export default DateHoursTable;
