import { useReducer } from 'react';
import { useInfiniteQuery } from 'react-query';
import { Link } from 'react-router-dom';

import { times } from 'lodash-es';
import { useDebounce } from '@material-hu/hooks/useDebounce';
import Stack from '@material-hu/mui/Stack';

import PxTableRowSkeleton from '@material-hu/components/composed-components/peopleExperience/TableRowSkeleton';
import Button from '@material-hu/components/design-system/Buttons/Button';
import HuChips from '@material-hu/components/design-system/Chip';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';
import HuPills from '@material-hu/components/design-system/Pills';
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 HuTableLoader from '@material-hu/components/design-system/Table/components/TableLoader';
import HuTableRow from '@material-hu/components/design-system/Table/components/TableRow';
import HuTitle from '@material-hu/components/design-system/Title';

import { useAuth } from 'src/contexts/JWTContext';
import useFormatDate from 'src/hooks/useFormatDate';
import { getSurveys } from '../../services';
import {
  CollaboratorSurveyStatus,
  type CollaboratorSurveysReqParams,
} from '../../types';
import { type LokaliseTFunction, useLokaliseTranslation } from 'src/utils/i18n';

import EmptyState from '../../components/EmptyState';
import { pxKeys } from '../../queries';
import { pxRoutes } from '../../routes';

const COLUMNS_LENGTH = 4;

const getFilterChipLabel = ({
  t,
  status,
}: {
  t: LokaliseTFunction;
  status: CollaboratorSurveyStatus | null;
}) => {
  switch (status) {
    case CollaboratorSurveyStatus.FINISHED:
      return t('survey.finished_other');
    case CollaboratorSurveyStatus.IN_PROGRESS:
      return t('in_progress');
    case CollaboratorSurveyStatus.PENDING:
      return t('pending_other');
    case CollaboratorSurveyStatus.UNCOMPLETED:
      return t('survey_status_uncompleted');
    default:
      return t('survey.all');
  }
};

const getStatusPillLabel = ({
  t,
  status,
}: {
  t: LokaliseTFunction;
  status: CollaboratorSurveyStatus;
}) => {
  switch (status) {
    case CollaboratorSurveyStatus.FINISHED:
      return t('survey.finished_one');
    case CollaboratorSurveyStatus.IN_PROGRESS:
      return t('in_progress');
    case CollaboratorSurveyStatus.PENDING:
      return t('pending_one');
    case CollaboratorSurveyStatus.UNCOMPLETED:
      return t('survey_status_uncompleted');
  }
};

const reducer = (
  currentState: CollaboratorSurveysReqParams,
  payload: Partial<CollaboratorSurveysReqParams>,
) => Object.assign({}, currentState, payload);

const initialFilters: CollaboratorSurveysReqParams = {
  q: '',
  status: undefined,
};

const STATUSES_PILL_TYPE: Record<
  CollaboratorSurveyStatus,
  React.ComponentProps<typeof HuPills>['type']
> = {
  [CollaboratorSurveyStatus.PENDING]: 'success',
  [CollaboratorSurveyStatus.IN_PROGRESS]: 'neutral',
  [CollaboratorSurveyStatus.FINISHED]: 'highlight',
  [CollaboratorSurveyStatus.UNCOMPLETED]: 'disabled',
};

type SurveysListProps = {
  onScrollToTop?: () => void;
};

const SurveysList = ({ onScrollToTop = () => {} }: SurveysListProps) => {
  const { t } = useLokaliseTranslation(['people_experience', 'general']);
  const { instance } = useAuth();
  const [filters, setFilters] = useReducer(reducer, initialFilters);
  const { q, status } = filters;
  const debouncedSearch = useDebounce(q);
  const { formatDate } = useFormatDate();

  const hasFiltersApplied = !!(q || status);

  const reqParams: CollaboratorSurveysReqParams = {
    status,
    q: q ? debouncedSearch : q,
  };

  const { data, isLoading, fetchNextPage, isFetchingNextPage } =
    useInfiniteQuery({
      queryKey: pxKeys.collaboratorSurveysList(reqParams),
      queryFn: ({ pageParam = 1 }) =>
        getSurveys({ ...reqParams, page: pageParam }),
      getNextPageParam: lastPage =>
        lastPage.data.page < lastPage.data.totalPages
          ? lastPage.data.page + 1
          : null,
    });

  const surveys = data?.pages.flatMap(page => page.data.items) || [];

  const handleChangeSearch = (nextValue: CollaboratorSurveysReqParams['q']) => {
    setFilters({ q: nextValue });
  };

  const handleChangeStatus = (
    nextValue: CollaboratorSurveysReqParams['status'],
  ) => {
    setFilters({ status: nextValue });
  };

  return (
    <>
      <Stack
        sx={{
          flexDirection: 'row',
          alignItems: 'center',
          gap: 2,
        }}
      >
        <HuSearch
          variant="classic"
          value={q ?? ''}
          onChange={handleChangeSearch}
        />
        <Stack sx={{ flexDirection: 'row', gap: 0.5 }}>
          {[
            null,
            CollaboratorSurveyStatus.PENDING,
            CollaboratorSurveyStatus.IN_PROGRESS,
            CollaboratorSurveyStatus.FINISHED,
          ].map(filter => (
            <HuChips
              key={filter}
              label={getFilterChipLabel({ t, status: filter ?? null })}
              onClick={() => handleChangeStatus(filter ?? undefined)}
              isSelected={filter === status}
            />
          ))}
        </Stack>
      </Stack>
      <Stack sx={{ gap: 1 }}>
        <HuTableContainer>
          <HuTable
            sx={{
              minWidth: 650,
              tableLayout: 'fixed',
            }}
          >
            <colgroup>
              <col style={{ width: '300px' }} />
              <col />
              <col />
              <col style={{ width: '150px' }} />
              <col />
              <col style={{ width: '150px' }} />
              <col />
              <col style={{ width: '150px' }} />
              <col />
            </colgroup>
            <HuTableHead>
              <HuTableRow headerRow>
                <HuTableCell
                  colSpan={3}
                  headerCell
                >
                  {t('general:name')}
                </HuTableCell>
                <HuTableCell
                  colSpan={2}
                  headerCell
                >
                  {t('LAUNCH')}
                </HuTableCell>
                <HuTableCell
                  colSpan={2}
                  headerCell
                >
                  {t('status')}
                </HuTableCell>
                <HuTableCell
                  colSpan={2}
                  headerCell
                ></HuTableCell>
              </HuTableRow>
            </HuTableHead>
            <HuTableBody>
              {isLoading &&
                times(8, row => (
                  <PxTableRowSkeleton
                    key={row}
                    columnsLength={COLUMNS_LENGTH}
                    getTableCellProps={column => ({
                      colSpan: column === 0 ? 3 : 2,
                    })}
                  />
                ))}
              {!isLoading && surveys?.length === 0 && (
                <HuTableRow>
                  <HuTableCell colSpan={9}>
                    <EmptyState
                      title={t(
                        hasFiltersApplied
                          ? 'EMPTY_FILTERED_SURVEYS_TITLE'
                          : 'EMPTY_SURVEYS_TITLE',
                      )}
                      description={t(
                        hasFiltersApplied
                          ? 'EMPTY_FILTERED_SURVEYS_DESCRIPTION'
                          : 'EMPTY_SURVEYS_DESCRIPTION',
                        { communityName: instance?.name ?? '' },
                      )}
                    />
                  </HuTableCell>
                </HuTableRow>
              )}
              {surveys?.map(item => (
                <HuTableRow
                  key={item.id}
                  hover
                >
                  <HuTableCell colSpan={3}>
                    <HuTitle
                      variant="S"
                      title={item.survey.name}
                      description={item.survey.description}
                      fontWeight="fontWeightRegular"
                      withEllipsis
                    />
                  </HuTableCell>
                  <HuTableCell colSpan={2}>
                    {item.survey.launchDate
                      ? formatDate(item.survey.launchDate)
                      : '--'}
                  </HuTableCell>
                  <HuTableCell colSpan={2}>
                    <HuPills
                      label={getStatusPillLabel({
                        t,
                        status: item.status,
                      })}
                      size="small"
                      type={STATUSES_PILL_TYPE[item.status]}
                      hasIcon={false}
                    />
                  </HuTableCell>
                  <HuTableCell colSpan={2}>
                    {[
                      CollaboratorSurveyStatus.PENDING,
                      CollaboratorSurveyStatus.IN_PROGRESS,
                    ].includes(item.status) && (
                      <Button
                        component={Link}
                        to={pxRoutes.collaboratorSurvey(item.survey.id)}
                        size="small"
                      >
                        {t(
                          item.status === CollaboratorSurveyStatus.IN_PROGRESS
                            ? 'CONTINUE'
                            : 'RESPOND',
                        )}
                      </Button>
                    )}
                  </HuTableCell>
                </HuTableRow>
              ))}
              {isFetchingNextPage &&
                times(4, row => (
                  <PxTableRowSkeleton
                    key={row}
                    columnsLength={COLUMNS_LENGTH}
                    getTableCellProps={column => ({
                      colSpan: column === 0 ? 3 : 2,
                    })}
                  />
                ))}
            </HuTableBody>
          </HuTable>
        </HuTableContainer>
        {surveys?.length > 0 && (
          <HuTableLoader
            loadedCount={surveys.length}
            totalCount={data?.pages[0].data.count ?? 0}
            onLoadMore={fetchNextPage}
            onScrollToTop={onScrollToTop}
          />
        )}
      </Stack>
    </>
  );
};

export default SurveysList;
