import { FC, forwardRef, useState } from 'react';
import { useInfiniteQuery } from 'react-query';

import { useDebounce } from '@material-hu/hooks/useDebounce';
import { IconInfoCircle, IconZoomExclamation } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuAvatar from '@material-hu/components/design-system/Avatar';
import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuChips from '@material-hu/components/design-system/Chip';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';
import HuSkeleton from '@material-hu/components/design-system/Skeleton';
import HuTable from '@material-hu/components/design-system/Table';
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 HuTooltip from '@material-hu/components/design-system/Tooltip';

import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import { AudienceTypes, LiveStreamInsights } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getNextCursor } from 'src/utils/pagination';
import { getInitials } from 'src/utils/userUtils';

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

import { formatDurationLivestream, formatStartTimetLivestream } from './utils';

type Header = {
  id: string;
  text: string;
  tooltip?: string;
};

type AudienceTableProps = {
  insights: LiveStreamInsights;
  currentLocale: Locale;
};

const AudienceTable = forwardRef<HTMLDivElement, AudienceTableProps>(
  function AudienceTable({ insights, currentLocale }, ref) {
    const { instance } = useAuth();
    const { t } = useLokaliseTranslation('livestream');
    const [audienceType, setAudienceType] = useState<AudienceTypes>(
      AudienceTypes.USERS,
    );
    const [query, setQuery] = useState('');

    const debouncedQuery = useDebounce(query);

    const showGeneralError = useGeneralError();

    const handleChangeQuery = (value: string) => {
      setQuery(value);
    };

    const headers: Header[] = [
      { id: 'name', text: t('general:name') },
      { id: 'employeeInternalId', text: t('EMPLOYEE_INTERNAL_ID') },
      ...(audienceType === AudienceTypes.VIEWS
        ? [
            {
              id: 'viewTime',
              text: t('VIEW_TIME'),
              tooltip: t('VIEW_TIME_TOOLTIP'),
            },
            { id: 'joinedAt', text: t('JOINED_AT') },
            { id: 'leftAt', text: t('LEFT_AT') },
          ]
        : []),
    ];

    const { data, ...listWrapperProps } = useInfiniteQuery(
      insights.viewerReports.keys(audienceType, debouncedQuery),
      ({ pageParam = '' }) => {
        return insights.viewerReports.service({
          q: debouncedQuery,
          limit: 10,
          cursor: pageParam,
          audienceType,
        });
      },
      {
        getNextPageParam: getNextCursor,
        onError: err => showGeneralError(err, t('ERROR_LOADING_VIEWERS')),
      },
    );

    const viewers = data ? data?.pages.flatMap(page => page.data.items) : [];

    return (
      <Stack ref={ref}>
        <HuCardContainer
          sx={{ p: 1 }}
          fullWidth
        >
          <Stack
            sx={{
              mb: 3,
            }}
          >
            <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}>
              <Typography
                variant="globalS"
                fontWeight="fontWeightSemiBold"
              >
                {t('AUDIENCE_TABLE_TITLE')}
              </Typography>
            </Stack>
            <Typography variant="globalXS">
              {t('AUDIENCE_TABLE_DESCRIPTION')}
            </Typography>
          </Stack>
          <HuSearch
            value={query}
            onChange={handleChangeQuery}
            placeholder={t('AUDIENCE_TABLE_SEARCH_PLACEHOLDER')}
            sx={{ mb: 2 }}
          />
          <Stack
            sx={{
              mb: 2,
              flexDirection: 'row',
              gap: 1,
            }}
          >
            {Object.values(AudienceTypes).map(type => (
              <HuChips
                key={type}
                label={t(type)}
                isSelected={type === audienceType}
                onClick={() => setAudienceType(type)}
              />
            ))}
          </Stack>
          <HuTableContainer sx={{ mb: 1, maxHeight: '490px' }}>
            <HuTable>
              <HuTableHead>
                <HuTableRow headerRow>
                  {headers.map(item => (
                    <HuTableCell
                      headerCell
                      key={item.id}
                    >
                      <Stack
                        sx={{
                          flexDirection: 'row',
                          alignItems: 'center',
                          gap: 0.5,
                        }}
                      >
                        {item.text}
                        {item.tooltip && (
                          <HuTooltip description={item.tooltip}>
                            <IconInfoCircle size={16} />
                          </HuTooltip>
                        )}
                      </Stack>
                    </HuTableCell>
                  ))}
                </HuTableRow>
              </HuTableHead>
              <InfiniteTable
                {...listWrapperProps}
                isEmpty={listWrapperProps.isSuccess && !viewers.length}
                renderEmptyState={<EmptyState />}
                totalColumns={headers.length}
              >
                {viewers.map(viewer => (
                  <HuTableRow key={viewer.id}>
                    <HuTableCell sx={{ maxWidth: '240px', minWidth: 0 }}>
                      <Stack
                        sx={{
                          display: 'flex',
                          flexDirection: 'row',
                          alignItems: 'center',
                          gap: 1,
                          minWidth: 0,
                          overflow: 'hidden',
                        }}
                      >
                        <HuAvatar
                          src={viewer.profilePictureUrl ?? ''}
                          alt={viewer.fullName}
                          text={getInitials(viewer.fullName)}
                          size="small"
                        />
                        <Stack sx={{ minWidth: 0, overflow: 'hidden' }}>
                          <EllipsisTooltip title={viewer.fullName}>
                            <Typography
                              variant="globalS"
                              noWrap
                              sx={{ display: 'block' }}
                            >
                              {viewer.fullName}
                            </Typography>
                          </EllipsisTooltip>
                          <Typography
                            variant="globalXS"
                            noWrap
                            color={theme =>
                              theme.palette.new.text.neutral.lighter
                            }
                          >
                            {viewer.role}
                          </Typography>
                        </Stack>
                      </Stack>
                    </HuTableCell>
                    <HuTableCell sx={{ maxWidth: '160px', minWidth: 0 }}>
                      <EllipsisTooltip title={viewer.employeeInternalId ?? ''}>
                        <Typography
                          noWrap
                          sx={{ display: 'block' }}
                        >
                          {viewer.employeeInternalId}
                        </Typography>
                      </EllipsisTooltip>
                    </HuTableCell>
                    {audienceType === AudienceTypes.VIEWS && (
                      <>
                        <HuTableCell>
                          {formatDurationLivestream(
                            0,
                            viewer.viewingTimeSeconds,
                            currentLocale,
                          )}
                        </HuTableCell>
                        <HuTableCell>
                          {formatStartTimetLivestream(
                            viewer.joinedAt,
                            instance?.timezone,
                          )}
                        </HuTableCell>
                        <HuTableCell>
                          {formatStartTimetLivestream(
                            viewer.leftAt,
                            instance?.timezone,
                          )}
                        </HuTableCell>
                      </>
                    )}
                  </HuTableRow>
                ))}
                {listWrapperProps.isLoading && (
                  <TableSkeleton columns={headers.length + 1} />
                )}
              </InfiniteTable>
            </HuTable>
          </HuTableContainer>
        </HuCardContainer>
      </Stack>
    );
  },
);

const EmptyState: FC = () => {
  const { t } = useLokaliseTranslation('livestream');
  return (
    <Stack
      sx={{
        alignItems: 'center',
        gap: theme => theme.spacing(2),
        flex: 1,
        justifyContent: 'center',
        py: 5.75,
      }}
    >
      <HuAvatar
        size="large"
        Icon={IconZoomExclamation}
        color="primary"
      />
      <Stack sx={{ textAlign: 'center' }}>
        <Typography
          variant="globalM"
          fontWeight="fontWeightSemiBold"
        >
          {t('general:no_results_found.title')}
        </Typography>
        <Typography variant="globalXS">
          {t('NO_RESULTS_DESCRIPTION')}
        </Typography>
      </Stack>
    </Stack>
  );
};

const TableSkeleton = ({ columns }: { columns: number }) => {
  return (
    <>
      {Array.from({ length: 6 }).map((_, index) => (
        <HuTableRow key={index}>
          {Array.from({ length: columns - 1 }).map((__, cellIndex) => (
            <HuTableCell key={cellIndex}>
              <HuSkeleton
                isLoading
                width={100}
                height={35}
                variant="rounded"
              />
            </HuTableCell>
          ))}
        </HuTableRow>
      ))}
    </>
  );
};

export default AudienceTable;
