import { useEffect, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { useQuery } from 'react-query';
import { useNavigate, useNavigationType } from 'react-router-dom';

import { lastDayOfMonth } from 'date-fns';
import { useDrawerV2 } from '@material-hu/hooks/useDrawerV2';
import { IconDownload, IconInfoCircle } from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Paper from '@material-hu/mui/Paper';
import Stack from '@material-hu/mui/Stack';
import Skeleton from '@material-hu/components/design-system/Skeleton';
import Typography from '@material-hu/mui/Typography';

import HuDatePeriodSelector from '@material-hu/components/composed-components/DatePeriodSelector';
import { Periods } from '@material-hu/components/composed-components/DatePeriodSelector/types';
import { recognizePeriod } from '@material-hu/components/composed-components/DatePeriodSelector/utils';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';
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 HuTableRow from '@material-hu/components/design-system/Table/components/TableRow';

import { logEvent } from 'src/config/amplitude';
import { useAuth } from 'src/contexts/JWTContext';
import { useGetDaySummaries } from 'src/hooks/queryHooks/timeTracking';
import { useDebounce } from 'src/hooks/useDebounce';
import useGeneralError from 'src/hooks/useGeneralError';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import useReportFilters from 'src/hooks/useReportFilters';
import { feedKeys } from 'src/pages/dashboard/feed/queries';
import { profileRoutes } from 'src/pages/dashboard/profile/routes';
import { getSegmentationGroups } from 'src/services/segmentations';
import { getRegions, getUsers } from 'src/services/timeTracking';
import { EventName } from 'src/types/amplitude';
import { type Segmentation } from 'src/types/segmentation';
import {
  type ReportFilterFields,
  type SegmentationGroup,
} from 'src/types/timeTracking';
import { formatUTCLocalDate } from 'src/utils/date';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  formatCommonReportParams,
  getTodayInTimezone,
} from 'src/utils/timeTracking';

import HuEmptyState from 'src/components/HuEmptyState';
import InfiniteTable from 'src/components/InfiniteTable';

import { parseGroup } from '../../../../components/dashboard/filterDrawer/utils';
import getIncidencesDrawerContent from '../components/Incidences/IncidencesDrawer';
import { useTimeTrackingCollaboratorsActions } from '../contexts/CollaboratorContext';
import { timeTrackingKeys } from '../queries';
import { timeTrackingRoutes } from '../routes';

import RegistersTable from './components/RegistersTable';
import PeriodHeaders from './components/RegistersTable/components/PeriodHeaders';
import { getHeaders } from './components/RegistersTable/constants';
import ReportDownload from './components/ReportDownload';

const PeriodCollaborators = () => {
  const { user, instance } = useAuth();
  const [isDownloadOpen, setIsDownloadOpen] = useState(false);
  const {
    fromDate,
    toDate,
    setFromDate: handleFromDateChange,
    setToDate: handleToDateChange,
    search,
    setSearch,
    reportFilters: liftedFilters,
    setReportFilters: setLiftedFilters,
    setTotalRecords,
    totalRecords,
  } = useTimeTrackingCollaboratorsActions();
  const navigationType = useNavigationType();
  const { t } = useLokaliseTranslation([
    'time_tracker',
    'time_tracking_common',
    'approval_requests',
  ]);
  const navigate = useNavigate();
  const HugoThemeProvider = useHuGoTheme();
  const showGeneralError = useGeneralError();

  const { data: segmentationGroups = [], isLoading: isLoadingSegmentations } =
    useQuery(feedKeys.segmentate.groups(), () => getSegmentationGroups(), {
      select: response => {
        const parseItems = (segmentation: Segmentation) =>
          segmentation.items.map(i => ({
            label: i.name,
            value: i.id,
            checked: false,
          }));
        return response.data.reduce<SegmentationGroup[]>((acc, cur) => {
          // We will only use segmentations which have defined items
          if (cur.items.length) {
            acc.push({
              name: cur.name,
              value: cur.id,
              items: parseItems(cur),
            });
          }
          return acc;
        }, []);
      },
      onError: error => {
        showGeneralError(error, t('ERROR_LOADING_SEGMENTATION_GROUPS'));
      },
    });

  const { data: regionsData, isLoading: isLoadingRegions } = useQuery(
    timeTrackingKeys.regions(),
    () => getRegions({ page: 1, limit: 300 }),
    {
      select: response =>
        parseGroup(
          response.data.items.map(r => ({
            id: r.id,
            name: r.title,
            items: r.sites || [],
          })),
        ),
      onError: err => {
        showGeneralError(err, t('REGIONS_ERROR'));
      },
    },
  );

  const usersWithPoliciesQuery = (searchQuery: string) =>
    useQuery(
      timeTrackingKeys.getUsers(searchQuery),
      () => getUsers({ page: 1, limit: 30, search: searchQuery }),
      {
        select: data => data.data.items,
      },
    );

  const reportFilters = useReportFilters({
    segmentationGroups,
    isLoadingSegmentations,
    regions: regionsData!,
    isLoadingRegions,
    showIncludeDeactivated: true,
    usersQuery: usersWithPoliciesQuery,
    initialValues: liftedFilters ?? undefined,
    onValuesChange: (v: ReportFilterFields) => {
      setLiftedFilters(v);
    },
  });

  const { debouncedValue: debouncedValues, isDebouncing } = useDebounce({
    ...formatCommonReportParams({
      fromDate,
      toDate,
      reportFilters: reportFilters.values,
    }),
    search,
  });

  const {
    registers,
    currentUserCount,
    totalRegisters,
    isLoading: isLoadingCollaborators,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useGetDaySummaries(debouncedValues);

  const { showDrawer: showIncidencesDrawer, drawer: IncidencesDrawer } =
    useDrawerV2(drawerProps =>
      getIncidencesDrawerContent({ ...drawerProps, t }),
    );

  const isLoading = isLoadingCollaborators || isDebouncing;
  const isDailyView = recognizePeriod(fromDate, toDate) === Periods.DAILY;
  const showEmptyState = !isLoading && totalRegisters === 0;
  const hasFiltersApplied =
    reportFilters.appliedFilters || (search?.trim() ?? '') !== '';

  const handleUserNavigation = (userId: number) => {
    navigate(timeTrackingRoutes.employeeTimesheet(userId), {
      // If daily view, navigate to the timesheet using a monthly period
      state: {
        fromDate: isDailyView
          ? new Date(fromDate.getFullYear(), fromDate.getMonth(), 1)
          : fromDate,
        toDate: isDailyView ? lastDayOfMonth(toDate) : toDate,
        initialFromDate: fromDate,
        initialToDate: toDate,
      },
    });
  };

  const handleNavigateToProfile = (userId: number) => {
    navigate(profileRoutes.profile(userId));
  };

  useEffect(() => {
    if (navigationType === 'PUSH') {
      logEvent(EventName.TIME_TRACKING_CONTROL_MODULE_OPENED, {});
    }
  }, []);

  useEffect(() => {
    if (currentUserCount > totalRecords) {
      setTotalRecords(currentUserCount);
    }
  }, [currentUserCount]);

  return (
    <HugoThemeProvider>
      {IncidencesDrawer}
      <Stack
        sx={{
          alignItems: 'center',
          minHeight: '100%',
        }}
      >
        <Helmet>
          <title>{formatTitle(t('TIME_TRACKING'))}</title>
        </Helmet>
        <Stack
          sx={{
            flex: 1,
            mb: 6,
            width: '100%',
          }}
        >
          <Stack
            sx={{
              flexDirection: 'row',
              justifyContent: 'space-between',
            }}
          >
            {reportFilters.component}
            <Stack
              sx={{
                alignItems: 'center',
                flexDirection: 'row',
                gap: 1,
              }}
            >
              <HuDatePeriodSelector
                fromDate={fromDate}
                handleFromChange={handleFromDateChange}
                toDate={toDate}
                handleToChange={handleToDateChange}
                initialPeriod={recognizePeriod(fromDate, toDate)}
                currentDate={getTodayInTimezone(instance?.timezone!)}
                dateFormatter={(date, format) =>
                  formatUTCLocalDate(date, user!, format)
                }
                sx={{
                  alignSelf: 'center',
                  gap: 1,
                  maxWidth: '720px',
                  pl: 1,
                  width: '100%',
                }}
                showDateReference
              />
              <IconButton
                aria-label={t('DOWNLOAD_REPORT')}
                variant="secondary"
                onClick={() => {
                  setIsDownloadOpen(true);
                }}
              >
                <IconDownload />
              </IconButton>
            </Stack>
          </Stack>
          <Stack
            sx={{
              alignItems: 'center',
              flexDirection: 'row',
              gap: 2,
              mt: 2,
            }}
          >
            <HuSearch
              value={search}
              onChange={setSearch}
              placeholder={t('SEARCH_COLLABORATOR')}
              aria-label={t('SEARCH_COLLABORATOR')}
            />
          </Stack>
          <Typography
            variant="globalXS"
            sx={{
              color: ({ palette }) => palette.new.text.neutral.lighter,
              mt: 2,
              mb: 1,
            }}
          >
            {isLoading && (
              <Skeleton
                variant="text"
                width={'20%'}
                height={18}
              />
            )}
            {!isLoading &&
              totalRegisters > 0 &&
              t('VISIBLE_COLLABORATORS', {
                current: currentUserCount,
                total: totalRecords,
              })}
          </Typography>
          {showEmptyState && !hasFiltersApplied && (
            <HuEmptyState
              titleProps={{
                title: t('no_collaborators_title'),
                description: t('no_collaborators_description'),
                variant: 'M',
              }}
              avatarProps={{
                Icon: IconInfoCircle,
                color: 'primary',
              }}
              sx={{
                bgcolor: ({ palette }) =>
                  palette.new.background.layout.tertiary,
                borderRadius: 2,
                border: '1px solid',
                borderColor: ({ palette }) =>
                  palette.new.border.neutral.divider,
                my: 3,
                minHeight: 200,
              }}
            />
          )}

          {(!showEmptyState || hasFiltersApplied) && (
            <Stack>
              <HuTableContainer
                component={Paper}
                sx={{
                  border: '1px solid',
                  borderColor: ({ palette }) =>
                    palette.new.border.neutral.default,
                }}
              >
                <HuTable sx={{ width: '100%', tableLayout: 'fixed' }}>
                  <PeriodHeaders
                    isDailyView={isDailyView}
                    onOpenIncidencesDrawer={showIncidencesDrawer}
                  />
                  {!showEmptyState && (
                    <InfiniteTable
                      fetchNextPage={fetchNextPage}
                      hasNextPage={hasNextPage}
                      isFetchingNextPage={isFetchingNextPage}
                      isEmpty={!totalRegisters}
                      isLoading={isLoading}
                      totalColumns={getHeaders(isDailyView).length}
                    >
                      <RegistersTable
                        registers={registers}
                        onNavigateToUser={handleUserNavigation}
                        onNavigateToProfile={handleNavigateToProfile}
                        isLoadingSummaries={isLoading}
                        isDailyView={isDailyView}
                      />
                    </InfiniteTable>
                  )}
                  {showEmptyState && hasFiltersApplied && (
                    <HuTableBody>
                      <HuTableRow>
                        <HuTableCell
                          colSpan={getHeaders(isDailyView).length}
                          sx={{
                            border: 'none',
                            verticalAlign: 'middle',
                            my: 3,
                            px: 3,
                          }}
                        >
                          <HuEmptyState
                            titleProps={{
                              title: t('no_collaborators_title'),
                              description: t(
                                'no_collaborators_description_filtered',
                              ),
                              variant: 'M',
                            }}
                            avatarProps={{
                              Icon: IconInfoCircle,
                              color: 'primary',
                            }}
                            sx={{
                              bgcolor: ({ palette }) =>
                                palette.new.background.layout.tertiary,
                              borderRadius: 2,
                              border: '1px solid',
                              borderColor: ({ palette }) =>
                                palette.new.border.neutral.divider,
                              my: 3,
                              minHeight: 200,
                            }}
                          />
                        </HuTableCell>
                      </HuTableRow>
                    </HuTableBody>
                  )}
                </HuTable>
              </HuTableContainer>
            </Stack>
          )}
          <ReportDownload
            open={isDownloadOpen}
            onClose={() => {
              setIsDownloadOpen(false);
            }}
            segmentationGroups={segmentationGroups.map(group => ({
              label: group.name,
              value: group.value,
            }))}
            isLoadingSegmentations={isLoadingSegmentations}
            appliedFilters={reportFilters.values}
            reportUsersCount={currentUserCount}
            fromDate={fromDate}
            toDate={toDate}
            search={search}
          />
        </Stack>
      </Stack>
    </HugoThemeProvider>
  );
};

export default PeriodCollaborators;
