import { ReactNode, useEffect } from 'react';
import { useInView } from 'react-intersection-observer';

import ChevronRight from '@material-hu/icons/material/ChevronRight';
import InfoOutlined from '@material-hu/icons/material/InfoOutlined';
import * as colors from '@material-hu/mui/colors';
import Paper from '@material-hu/mui/Paper';
import Skeleton from '@material-hu/mui/Skeleton';
import Table from '@material-hu/mui/Table';
import TableBody from '@material-hu/mui/TableBody';
import TableCell, { TableCellProps } from '@material-hu/mui/TableCell';
import TableContainer from '@material-hu/mui/TableContainer';
import TableHead from '@material-hu/mui/TableHead';
import TableRow, { TableRowProps } from '@material-hu/mui/TableRow';
import Tooltip from '@material-hu/mui/Tooltip';
import Typography from '@material-hu/mui/Typography';

import { FavBaseStatsResponse } from '../types';
import { LokaliseTFunction, useLokaliseTranslation } from 'src/utils/i18n';

import { formatValue } from '../utils';

import EmptyState from './EmptyState';

type SkeletonRowProps = {
  rowRef: TableRowProps['ref'];
};

const SkeletonRow = ({ rowRef }: SkeletonRowProps) => (
  <TableRow ref={rowRef}>
    <TableCell>
      <Skeleton
        variant="text"
        width="50%"
      />
      <Skeleton
        variant="text"
        width="80%"
      />
    </TableCell>
    <TableCell>
      <Skeleton
        variant="text"
        width="100%"
      />
    </TableCell>
    <TableCell>
      <Skeleton
        variant="text"
        width="50%"
        sx={{ m: '0 auto' }}
      />
    </TableCell>
  </TableRow>
);

type EmptyStateRowProps = {
  slotProps?: Partial<{ cell: TableCellProps }>;
};

const EmptyStateRow = ({ slotProps }: EmptyStateRowProps) => {
  const { t } = useLokaliseTranslation('people_experience');
  return (
    <TableRow>
      <TableCell colSpan={slotProps?.cell?.colSpan}>
        <EmptyState
          title={t('NOT_ENOUGH_DATA_TITLE')}
          description={t('NOT_ENOUGH_DATA_DESCRIPTION')}
        />
      </TableCell>
    </TableRow>
  );
};

const renderScoreColumn = <TRow extends FavBaseStatsResponse>({
  row,
  t,
}: {
  row: TRow;
  t: LokaliseTFunction;
}) => {
  if (!row.passedThreshold) {
    return (
      <Typography
        variant="body2"
        sx={{ letterSpacing: 2 }}
      >
        --
      </Typography>
    );
  }

  if (row.score) {
    return <Typography variant="body2">{formatValue(row.score)}</Typography>;
  }

  return (
    <Tooltip
      PopperProps={{ sx: { maxWidth: 180 } }}
      title={t('WARNING_LIKERT_EXCLUSIVE') as string}
    >
      <InfoOutlined
        fontSize="small"
        sx={theme => ({ color: theme.palette.new.icon.neutral.lighter })}
      />
    </Tooltip>
  );
};

type FavBaseTableListProps<TData> = {
  isPreviousData: boolean;
  isLoading: boolean;
  data: TData[];
  renderDescriptionColumn: (row: TData) => JSX.Element;
  renderDistributionColumn: (row: TData) => JSX.Element;
  descriptionColumnTitle?: ReactNode;
  slotProps?: Partial<{
    dataRow: (row: TData) => TableRowProps;
    distributionColumn: (row: TData) => TableCellProps;
  }>;
  hasNextPage?: boolean;
  onLoadMore?: () => void;
};

const FavBaseTableList = <TData extends FavBaseStatsResponse>({
  isPreviousData,
  isLoading,
  data,
  renderDescriptionColumn,
  renderDistributionColumn,
  slotProps,
  descriptionColumnTitle,
  hasNextPage,
  onLoadMore,
}: FavBaseTableListProps<TData>) => {
  const { t } = useLokaliseTranslation('people_experience');
  const hasData = !!data?.length;

  const { ref, inView } = useInView({
    threshold: 0.5,
  });

  useEffect(() => {
    if (inView) {
      onLoadMore?.();
    }
  }, [inView, onLoadMore]);

  return (
    <TableContainer
      component={Paper}
      elevation={2}
    >
      <Table sx={{ tableLayout: 'fixed', opacity: isPreviousData ? 0.5 : 1 }}>
        <TableHead>
          <TableRow>
            <TableCell sx={{ width: '45%' }}>
              {descriptionColumnTitle}
            </TableCell>
            <TableCell align="center">{t('DISTRIBUTION')}</TableCell>
            <TableCell
              sx={{ width: '15%' }}
              align="center"
            >
              {t('SCORE')}
            </TableCell>

            <TableCell sx={{ width: 64 }}></TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {isLoading && <SkeletonRow rowRef={ref} />}
          {hasData &&
            !isLoading &&
            data.map(row => {
              const rowExtraProps = slotProps?.dataRow?.(row);

              return (
                <TableRow
                  key={row.id}
                  tabIndex={0}
                  role="button"
                  {...rowExtraProps}
                  sx={{
                    cursor: 'pointer',
                    '&:hover': {
                      bgcolor: theme =>
                        theme.palette.new.action.background.neutral.hover,
                    },
                    transition: 'background-color 250ms',
                    ...rowExtraProps?.sx,
                  }}
                >
                  <TableCell sx={{ width: '45%' }}>
                    {renderDescriptionColumn(row)}
                  </TableCell>
                  <TableCell
                    align="center"
                    {...slotProps?.distributionColumn?.(row)}
                  >
                    {renderDistributionColumn(row)}
                  </TableCell>
                  <TableCell align="center">
                    {renderScoreColumn({ row, t })}
                  </TableCell>
                  <TableCell align="right">
                    <ChevronRight
                      sx={theme => ({
                        color: theme.palette.new.icon.neutral.lighter,
                      })}
                    />
                  </TableCell>
                </TableRow>
              );
            })}
          {!hasData && !isLoading && (
            <EmptyStateRow slotProps={{ cell: { colSpan: 4 } }} />
          )}
          {hasNextPage && <SkeletonRow rowRef={ref} />}
        </TableBody>
      </Table>
    </TableContainer>
  );
};

export default FavBaseTableList;
