import { Fragment, useState } from 'react';
import { useQuery } from 'react-query';

import { isNil } from 'lodash-es';
import Divider from '@material-hu/mui/Divider';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import Pagination from '@material-hu/components/design-system/Inputs/Pagination';
import Spinner from '@material-hu/components/design-system/ProgressIndicators/Spinner';

import { goalsKeys } from 'src/pages/dashboard/goals/queries';
import RichText from 'src/pages/dashboard/performance/components/RichText';
import { formatDateFromISO } from 'src/utils/date';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getFullName } from 'src/utils/userUtils';

import { getGoalHistory } from '../../services';
import { type GoalHistory, GoalProgressChange } from '../../types';
import {
  GOAL_HISTORY_DEFAULT_LIMIT,
  GOAL_HISTORY_LIMIT_OPTIONS,
  GOAL_HISTORY_ORDER,
  GOAL_HISTORY_ORDER_BY,
} from '../constants';

export type ProgressHistoryTableProps = {
  goalId: number;
};

const ProgressHistoryTable = ({ goalId }: ProgressHistoryTableProps) => {
  const { t } = useLokaliseTranslation('goals');
  const theme = useTheme();

  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(GOAL_HISTORY_DEFAULT_LIMIT);

  const pagination = {
    page: page - 1,
    limit,
    order: GOAL_HISTORY_ORDER,
    orderBy: GOAL_HISTORY_ORDER_BY,
  };

  const { data, isLoading } = useQuery(
    goalsKeys.history(goalId, pagination),
    () => getGoalHistory(goalId, pagination),
    {
      select: r => r.data,
    },
  );

  const goals: GoalHistory[] = data?.items || [];
  const totalCount = data?.count ?? 0;
  const totalPages = Math.ceil(totalCount / limit);

  const getValueChange = (type: GoalProgressChange, value: number) => {
    if (type === GoalProgressChange.DELTA_VALUE && value >= 0)
      return `+${value}`;
    if (type === GoalProgressChange.DELTA_VALUE && value < 0)
      return `-${value}`;
    if (type === GoalProgressChange.TOTAL_VALUE)
      return t('detail.total_value', { value });
  };

  const handleChangePage = (newPage: number) => {
    setPage(newPage);
  };

  const handleChangeLimit = (newLimit: number) => {
    setLimit(newLimit);
    setPage(1);
  };

  return (
    <Stack sx={{ gap: 3, width: '100%' }}>
      <Typography sx={{ fontSize: '16px', fontWeight: 600 }}>
        {t('detail.history')}
      </Typography>
      <Stack
        sx={{
          border: `1px solid ${theme.palette.new.border.neutral.default}`,
          borderRadius: '16px',
          backgroundColor: theme.palette.new.background.layout.tertiary,
          p: 3,
          gap: 0,
        }}
      >
        {isLoading && (
          <Stack
            sx={{ py: 4, alignItems: 'center' }}
            data-testid="goal-history-loading"
          >
            <Spinner />
          </Stack>
        )}
        {!isLoading &&
          !!goals.length &&
          goals.map((goal: GoalHistory, index: number) => (
            <Fragment key={goal.id}>
              <Stack
                sx={{
                  flexDirection: 'row',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                  gap: 2,
                  py: 1,
                }}
              >
                <Stack sx={{ flex: 1, minWidth: 0, gap: 0.5 }}>
                  <Typography
                    sx={{
                      fontSize: '14px',
                      fontWeight: 600,
                      color: theme.palette.new.text.neutral.default,
                    }}
                  >
                    {getFullName(goal.user)}
                  </Typography>
                  <Typography
                    sx={{
                      fontSize: '12px',
                      fontWeight: 400,
                      color: theme.palette.new.text.neutral.lighter,
                    }}
                  >
                    {formatDateFromISO(goal.createdAt)}
                  </Typography>
                  {!!goal.description?.trim() && (
                    <RichText
                      text={goal.description}
                      decodeEntities
                      sx={{
                        mb: 0,
                        mt: 0.5,
                        fontSize: '14px',
                        wordBreak: 'break-word',
                        whiteSpace: 'normal',
                        color: theme.palette.new.text.neutral.lighter,
                        '& p': { whiteSpace: 'normal' },
                      }}
                    />
                  )}
                </Stack>
                {!isNil(goal.value) && !isNil(goal.type) && (
                  <Stack
                    sx={{ alignItems: 'flex-end', flexShrink: 0, gap: 0.25 }}
                  >
                    <Typography
                      sx={{
                        fontSize: '12px',
                        fontWeight: 400,
                        color: theme.palette.new.text.neutral.lighter,
                      }}
                    >
                      {t('detail.advances_label')}
                    </Typography>
                    <Typography
                      sx={{
                        fontSize: '14px',
                        fontWeight: 600,
                        color: theme.palette.new.text.feedback.success,
                      }}
                    >
                      {getValueChange(goal.type, goal.value)}
                    </Typography>
                  </Stack>
                )}
              </Stack>
              {index < goals.length - 1 && <Divider flexItem />}
            </Fragment>
          ))}
        {!isLoading && !goals.length && (
          <Stack
            sx={{
              width: '100%',
              justifyContent: 'center',
              alignItems: 'center',
              textAlign: 'center',
              py: 6,
            }}
          >
            <Typography sx={{ fontSize: '16px', fontWeight: 500 }}>
              {t('detail.empty_history')}
            </Typography>
          </Stack>
        )}
        {totalCount > limit && (
          <Pagination
            page={page}
            totalPages={totalPages}
            limit={limit}
            limitOptions={[...GOAL_HISTORY_LIMIT_OPTIONS]}
            onChangePage={handleChangePage}
            onChangeLimit={handleChangeLimit}
            type="changer"
            sx={{ border: 'none', mt: 3 }}
          />
        )}
      </Stack>
    </Stack>
  );
};

export default ProgressHistoryTable;
