import {
  type FetchNextPageOptions,
  type InfiniteQueryObserverResult,
} from 'react-query';
import { useNavigate } from 'react-router-dom';

import { type AxiosResponse } from 'axios';
import { type HuTableSortingHeaderProps } from '@material-hu/hooks/TableSorting/useHuServerTableSorting';

import Table from '@material-hu/components/design-system/Table';
import TableBody from '@material-hu/components/design-system/Table/components/TableBody';
import TableCell from '@material-hu/components/design-system/Table/components/TableCell';
import TableContainer from '@material-hu/components/design-system/Table/components/TableContainer';
import TableHead from '@material-hu/components/design-system/Table/components/TableHead';
import TableLoader from '@material-hu/components/design-system/Table/components/TableLoader';
import TableRow from '@material-hu/components/design-system/Table/components/TableRow';
import Title from '@material-hu/components/design-system/Title';

import useFormatDate from 'src/hooks/useFormatDate';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { TableError } from '../../components/TableError';
import { TableNoInternetConnection } from '../../components/TableNoInternetConnection';
import { TableSkeleton } from '../../components/TableSkeleton';
import { JOB_OFFERS_ORDER_BY_FIELDS } from '../../constants';
import { recruitingRoutes } from '../../routes';
import {
  type JobOffer,
  JobOfferStatus,
  type PaginatedResponse,
} from '../../types';
import { StatusPill } from '../StatusPill';

import { JobsTableEmptyState } from './JobsTableEmptyState';
import { getJobSubtitle } from './utils';

type JobsTableProps = {
  jobs: JobOffer[];
  totalCount: number;
  isLoading: boolean;
  isFetchingNextPage: boolean;
  hasNextPage: boolean;
  fetchNextPage: (
    options?: FetchNextPageOptions,
  ) => Promise<
    InfiniteQueryObserverResult<
      AxiosResponse<PaginatedResponse<JobOffer>, unknown>,
      unknown
    >
  >;
  onScrollToTop: () => void;
  noInternetConnection: boolean;
  errorCount: number;
  refetch: () => void;
  HuTableSortingHeader: React.ComponentType<HuTableSortingHeaderProps>;
  hasSearch?: boolean;
  hasFilters?: boolean;
};

export const JobsTable = ({
  jobs,
  totalCount,
  isLoading,
  isFetchingNextPage,
  fetchNextPage,
  onScrollToTop,
  noInternetConnection,
  errorCount,
  refetch,
  HuTableSortingHeader,
  hasSearch = false,
  hasFilters = false,
}: JobsTableProps) => {
  const { formatDate } = useFormatDate();
  const { t } = useLokaliseTranslation(['ats', 'material_hu_only']);
  const navigate = useNavigate();
  const onRowClick = (job: JobOffer) => {
    navigate(recruitingRoutes.jobOffer(Number(job.id || 0)));
  };

  if (noInternetConnection) {
    return <TableNoInternetConnection onRetry={refetch} />;
  }

  if (jobs.length === 0 && !isLoading && !errorCount) {
    return (
      <JobsTableEmptyState
        hasSearch={hasSearch}
        hasFilters={hasFilters}
      />
    );
  }

  if (errorCount > 0) {
    return (
      <TableError
        errorCount={errorCount}
        onRetry={refetch}
      />
    );
  }

  return (
    <>
      <TableContainer>
        <Table>
          <TableHead>
            <TableRow
              headerRow
              sx={{
                height: 74,
              }}
            >
              <HuTableSortingHeader id={JOB_OFFERS_ORDER_BY_FIELDS.name}>
                {t('job_offers.list.columns.name')}
              </HuTableSortingHeader>
              <TableCell headerCell>
                {t('job_offers.list.columns.department')}
              </TableCell>
              <TableCell headerCell>
                {t('job_offers.list.columns.status')}
              </TableCell>
              <HuTableSortingHeader
                id={JOB_OFFERS_ORDER_BY_FIELDS.applicationsCount}
              >
                {t('job_offers.list.columns.applicants')}
              </HuTableSortingHeader>
              <HuTableSortingHeader id={JOB_OFFERS_ORDER_BY_FIELDS.createdAt}>
                {t('job_offers.list.columns.created_at')}
              </HuTableSortingHeader>
            </TableRow>
          </TableHead>
          <TableBody>
            {isLoading && (
              <TableSkeleton
                rows={5}
                cols={5}
              />
            )}
            {!isLoading &&
              jobs.map(job => (
                <TableRow
                  key={job.id}
                  onClick={() => onRowClick(job)}
                  sx={{ cursor: 'pointer', height: 74 }}
                >
                  <TableCell
                    sx={{
                      minWidth: 280,
                    }}
                  >
                    <Title
                      title={job.name}
                      withEllipsis
                      overflow="tooltip"
                      fontWeight="fontWeightRegular"
                      variant="S"
                      description={getJobSubtitle(job)}
                    />
                  </TableCell>
                  <TableCell
                    sx={{
                      minWidth: 224,
                    }}
                  >
                    <Title
                      title={job.department || '-'}
                      withEllipsis
                      overflow="tooltip"
                      fontWeight="fontWeightRegular"
                      variant="S"
                    />
                  </TableCell>
                  <TableCell>
                    <StatusPill
                      status={
                        job.isPublished && job.status === JobOfferStatus.OPEN
                          ? JobOfferStatus.PUBLISHED
                          : job.status || JobOfferStatus.DRAFT
                      }
                    />
                  </TableCell>
                  <TableCell>
                    <Title
                      title={job.applicationsCount || 0}
                      fontWeight="fontWeightRegular"
                      variant="S"
                    />
                  </TableCell>
                  <TableCell
                    sx={{
                      minWidth: 224,
                    }}
                  >
                    <Title
                      title={
                        job.createdAt
                          ? formatDate(job.createdAt, 'dd/MM/yyyy')
                          : '-'
                      }
                      fontWeight="fontWeightRegular"
                      variant="S"
                    />
                  </TableCell>
                </TableRow>
              ))}
            {isFetchingNextPage && (
              <TableSkeleton
                rows={3}
                cols={5}
              />
            )}
          </TableBody>
        </Table>
      </TableContainer>
      {!isLoading && (
        <TableLoader
          loadedCount={jobs.length}
          totalCount={totalCount}
          onLoadMore={fetchNextPage}
          onScrollToTop={onScrollToTop}
          slotProps={{
            button: {
              disabled: isFetchingNextPage,
            },
          }}
        />
      )}
    </>
  );
};
