import { type FC, Fragment, useMemo, useState } from 'react';

import {
  IconChevronRight,
  IconMapPinExclamation,
} from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import TableCell from '@material-hu/mui/TableCell';
import TableRow from '@material-hu/mui/TableRow';
import Typography from '@material-hu/mui/Typography';

import HuAvatar from '@material-hu/components/design-system/Avatar';
import HuTooltip from '@material-hu/components/design-system/Tooltip';

import { useAuth } from 'src/contexts/JWTContext';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { type DaySummary, Incidence } from 'src/types/timeTracking';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  daySummaryWithAutoClosedEntry,
  displayHoursAndMinutes,
  formatCompleteDecimalHours,
  parseDateToDisplay,
  parseDayScheduleStatus,
} from 'src/utils/timeTracking';

import DayOffPopover from '../../components/DayOffPopover';
import HuIncidenceTag from '../../components/Incidences/IncidenceTag';
import ProgressBar from '../../components/ProgressBar';
import ScheduledHoursPopover from '../../components/ScheduledHoursPopover';
import {
  NON_TAG_INCIDENCES,
  svgColorCorrection,
  TOOLTIP_DELAY,
} from '../../constants';
import ProgrammedHours from '../../PeriodCollaborators/components/RegistersTable/components/ProgrammedHours';

type Props = {
  data: DaySummary;
  isCurrentDate: boolean;
  isFutureDate: boolean;
  onDayClick: () => void;
};

const DayInfoRow: FC<Props> = props => {
  const { data, isCurrentDate, isFutureDate, onDayClick } = props;
  const [popoverAnchor, setPopoverAnchor] = useState<HTMLElement | null>(null);
  const { t } = useLokaliseTranslation('time_tracker');
  const { user } = useAuth();
  const HuGoThemeProvider = useHuGoTheme();

  const { date, dayOfWeek } = parseDateToDisplay(
    `${data.dateString}T00:00:00.000`,
    user!,
  );

  const hourBalance = formatCompleteDecimalHours(
    data.workedHours - data.estimatedHours,
    true,
  );

  const handlePopoverOpen = (event: React.MouseEvent<HTMLElement>) => {
    event.stopPropagation();
    setPopoverAnchor(event.currentTarget);
  };

  // For now we will only show the incidences defined on the Incidence enum
  const visibleIncidences = Array.from(
    new Set(
      data.incidences.filter(
        i =>
          Object.keys(Incidence).includes(i) && !NON_TAG_INCIDENCES.includes(i),
      ),
    ),
  );

  const IncidenceTags = useMemo(
    () =>
      visibleIncidences.map(incidence => (
        <Fragment key={incidence}>
          {incidence === Incidence.LOCATION_INCIDENCE ? (
            <HuTooltip
              title={t('LOCATION_INCIDENCE_TOOLTIP')}
              description={t('CHECK_LOCATION')}
              direction="top"
              delay={TOOLTIP_DELAY}
            >
              <span>
                <HuAvatar
                  size="small"
                  Icon={IconMapPinExclamation}
                  color="warning"
                />
              </span>
            </HuTooltip>
          ) : (
            <HuIncidenceTag
              type={incidence}
              count={hourBalance}
              aria-haspopup="true"
              hideCount={
                incidence === Incidence.ABSENT || incidence === Incidence.LATE
              }
              pillProps={{
                id: incidence,
                hasIcon: false,
                label: t(incidence),
              }}
              pillVariant="default"
              daySummary={data}
              visibleIncidences={visibleIncidences}
              withPopover
            />
          )}
        </Fragment>
      )),
    [visibleIncidences, t, data, hourBalance],
  );

  const { holiday, isScheduledDayOff } = parseDayScheduleStatus({
    holidays: data.holidays,
    isWorkday: data.isWorkday,
    scheduleSource: data.scheduleSource,
    timeOffRequests: data.timeOffRequests,
  });

  return (
    <HuGoThemeProvider>
      <TableRow
        // Used as the scroll target for deeplink navigation from TimesheetTable.
        data-day-summary-date={data.dateString}
        sx={{
          backgroundColor: isCurrentDate
            ? ({ palette }) => palette.new.background.layout.brand
            : undefined,
        }}
      >
        <TableCell
          align="left"
          width={160}
        >
          <Stack
            sx={{
              alignItems: 'baseline',
              flex: 1,
              flexDirection: 'row',
              gap: 1,
            }}
          >
            <Stack
              sx={{
                width: '100%',
                '.MuiTypography-root': {
                  textTransform: 'capitalize',
                },
              }}
            >
              <Typography
                variant="globalS"
                sx={{
                  color: ({ palette }) =>
                    isFutureDate
                      ? palette.new.text.neutral.lighter
                      : palette.new.text.neutral.default,
                }}
              >
                {date}
              </Typography>
              <Typography
                variant="globalXS"
                sx={{
                  color: ({ palette }) => palette.new.text.neutral.lighter,
                }}
              >
                {dayOfWeek}
              </Typography>
            </Stack>
          </Stack>
        </TableCell>
        <TableCell
          align="left"
          width={250}
        >
          <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 0.5 }}>
            <ProgrammedHours
              scheduledHours={data.scheduledHours}
              holiday={holiday}
              isScheduledDayOff={isScheduledDayOff}
              onOpenDayOffPopover={handlePopoverOpen}
              onOpenSchedulePopover={handlePopoverOpen}
              isWorkday={data.isWorkday}
              dailyView
            />
          </Stack>
        </TableCell>
        <TableCell
          align="left"
          width={250}
        >
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              gap: 0.5,
              '& > :first-of-type': {
                flex: 1,
              },
            }}
          >
            <ProgressBar
              worked={data.workedHours}
              estimated={data.estimatedHours}
              extra={data.extraHours}
              autoClosed={daySummaryWithAutoClosedEntry(data)}
              isDayOffOrHoliday={isScheduledDayOff || Boolean(holiday?.name)}
              showTooltip
            />
            <Typography
              variant="globalXS"
              sx={{
                color: ({ palette }) => palette.new.text.neutral.lighter,
              }}
            >
              {displayHoursAndMinutes(data.workedHours, false, true)}
            </Typography>
          </Stack>
        </TableCell>
        <TableCell align="left">
          <Stack
            sx={{
              alignItems: 'center',
              flexDirection: 'row',
              gap: 2,
            }}
          >
            {IncidenceTags}
          </Stack>
        </TableCell>
        <TableCell align="left">
          {!isFutureDate && (
            <IconButton
              onClick={onDayClick}
              size="small"
              aria-haspopup="true"
              aria-label={t('see_trackings')}
              sx={{ ...svgColorCorrection('neutralText') }}
            >
              <IconChevronRight size={16} />
            </IconButton>
          )}
        </TableCell>
      </TableRow>
      <DayOffPopover
        dayOffEvent={data.timeOffRequests[0] || data.holidays[0]}
        isOpen={popoverAnchor?.id === 'dayoff'}
        anchor={popoverAnchor}
        closePopover={() => {
          setPopoverAnchor(null);
        }}
      />
      <ScheduledHoursPopover
        type="schedules"
        isOpen={popoverAnchor?.id === 'schedule'}
        anchor={popoverAnchor}
        closePopover={() => {
          setPopoverAnchor(null);
        }}
        workSchedule={{
          name: data.workScheduleName || t('assigned_schedule'),
          description:
            data.workScheduleDescription || t('assigned_schedule_hint'),
          slots:
            data.timeSlots?.map(ts => `${ts.startTime} - ${ts.endTime}`) || [],
          totalHours: data.estimatedHours,
        }}
      />
    </HuGoThemeProvider>
  );
};

export default DayInfoRow;
