import { type FC, useEffect, useRef, useState } from 'react';

import { IconExclamationCircle } from '@material-hu/icons/tabler';
import Paper from '@material-hu/mui/Paper';
import Stack from '@material-hu/mui/Stack';

import HuTable from '@material-hu/components/design-system/Table';
import HuTableBody from '@material-hu/components/design-system/Table/components/TableBody';
import HuTableCell from '@material-hu/components/design-system/Table/components/TableCell';
import HuTableContainer from '@material-hu/components/design-system/Table/components/TableContainer';
import HuTableHead from '@material-hu/components/design-system/Table/components/TableHead';
import HuTableRow from '@material-hu/components/design-system/Table/components/TableRow';

import {
  type DaySummary,
  Incidence,
  UserAccountStatus,
  type UserTrackingStatus,
} from 'src/types/timeTracking';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { TIMESHEET_HEADERS } from 'src/utils/timeTracking';

import HuEmptyState from 'src/components/HuEmptyState';

import { usePeriodDetailDrawer } from '../../components/PeriodDetailDrawer/usePeriodDetailDrawer';
import { getIncidenceEntryPairId } from '../utils';

import DayInfoRow from './DayInfoRow';
import TimeSheetTableSkeleton from './TimeSheetTableSkeleton';

type Props = {
  daySummaries: DaySummary[];
  isLoadingSummaries: boolean;
  isLoadingSites: boolean;
  userStatus: UserTrackingStatus;
  userAccountStatus: UserAccountStatus;
  currentDate: string;
  deeplinkDate?: string;
  deeplinkIncidenceType?: Incidence;
};

const TimesheetTable: FC<Props> = props => {
  const {
    daySummaries,
    isLoadingSummaries,
    isLoadingSites,
    userStatus,
    userAccountStatus,
    currentDate,
    deeplinkDate,
    deeplinkIncidenceType,
  } = props;
  const { t } = useLokaliseTranslation('time_tracker');
  const [selectedSummaryIndex, setSelectedSummaryIndex] = useState<number>();
  const lastHandledDeeplinkRef = useRef<string | null>(null);

  const drawerCustomProps = {
    userStatus,
    currentDate,
    loadingSummaries: isLoadingSummaries || isLoadingSites,
    dayInfo:
      selectedSummaryIndex !== undefined
        ? daySummaries?.[selectedSummaryIndex]
        : undefined,
    isDeactivated: userAccountStatus === UserAccountStatus.DEACTIVATED,
  };

  const { showPeriodDetailDrawer, drawer: PeriodDetailDrawer } =
    usePeriodDetailDrawer(drawerCustomProps);

  const handleDaySelection = (summaryIndex: number) => {
    setSelectedSummaryIndex(summaryIndex);
    showPeriodDetailDrawer();
  };

  useEffect(() => {
    if (!deeplinkDate) {
      lastHandledDeeplinkRef.current = null;
      return;
    }
    const deeplinkKey = `${deeplinkDate}|${deeplinkIncidenceType ?? ''}`;
    if (lastHandledDeeplinkRef.current === deeplinkKey) return;
    if (isLoadingSummaries) return;
    const matchingIndex = daySummaries?.findIndex(
      ds => ds.dateString === deeplinkDate,
    );
    if (matchingIndex === undefined || matchingIndex < 0) return;
    document
      .querySelector(`[data-day-summary-date="${deeplinkDate}"]`)
      ?.scrollIntoView({ block: 'center', behavior: 'smooth' });
    const matchingSummary = daySummaries[matchingIndex];
    const accordionId = deeplinkIncidenceType
      ? getIncidenceEntryPairId(
          matchingSummary.timeTrackingEntries,
          deeplinkIncidenceType,
        )
      : null;
    setSelectedSummaryIndex(matchingIndex);
    showPeriodDetailDrawer(accordionId ?? undefined);
    lastHandledDeeplinkRef.current = deeplinkKey;
    // showPeriodDetailDrawer is stable enough for our use case (we only run on
    // highlight changes); including it in deps would force the effect to fire
    // on every render via showPeriodDetailDrawer identity changes.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [deeplinkDate, deeplinkIncidenceType, daySummaries, isLoadingSummaries]);

  if (!isLoadingSummaries && daySummaries?.length === 0) {
    return (
      <HuEmptyState
        titleProps={{
          title: t('NO_TRACKINGS_TITLE'),
          description: t('NO_TRACKINGS_DESCRIPTION'),
          variant: 'M',
        }}
        avatarProps={{
          Icon: IconExclamationCircle,
          color: 'default',
        }}
      />
    );
  }

  return (
    <Stack sx={{ width: '100%' }}>
      {PeriodDetailDrawer}
      <HuTableContainer
        component={Paper}
        sx={{
          border: '1px solid',
          borderColor: ({ palette }) => palette.new.border.neutral.default,
        }}
      >
        <HuTable
          sx={{ width: '100%' }}
          stickyHeader
        >
          <HuTableHead>
            <HuTableRow
              sx={{
                '.MuiTableCell-head': {
                  backgroundColor: ({ palette }) =>
                    palette.new.background.elements.grey,
                  '&:hover': {
                    backgroundColor: ({ palette }) =>
                      palette.new.background.elements.grey,
                  },
                },
              }}
            >
              {TIMESHEET_HEADERS.map(header => (
                <HuTableCell
                  key={header}
                  sx={{ width: header === '' ? 72 : 'unset' }}
                >
                  {t(header)}
                </HuTableCell>
              ))}
            </HuTableRow>
          </HuTableHead>
          <HuTableBody>
            {isLoadingSummaries && <TimeSheetTableSkeleton />}
            {!isLoadingSummaries &&
              daySummaries?.map((ds, index) => (
                <DayInfoRow
                  key={ds.date}
                  isCurrentDate={currentDate === ds.dateString}
                  isFutureDate={ds.dateString > currentDate}
                  data={ds}
                  onDayClick={() => {
                    handleDaySelection(index);
                  }}
                />
              ))}
          </HuTableBody>
        </HuTable>
      </HuTableContainer>
    </Stack>
  );
};

export default TimesheetTable;
