import { Helmet } from 'react-helmet-async';
import { useQuery } from 'react-query';
import { useLocation, useNavigate, useParams } from 'react-router-dom';

import { isNil } from 'lodash-es';
import CloseIcon from '@material-hu/icons/material/Close';
import { IconArrowLeft } from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import HuAlert from '@material-hu/components/design-system/Alert';
import Spinner from '@material-hu/components/design-system/ProgressIndicators/Spinner';

import { useAuth } from 'src/contexts/JWTContext';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import RichText from 'src/pages/dashboard/performance/components/RichText';
import { performanceRoutes } from 'src/pages/dashboard/performance/routes';
import { profileKeys } from 'src/pages/dashboard/profile/queries';
import { getUserBosses } from 'src/services/users';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { goalsKeys } from '../queries';
import { goalsRoutes } from '../routes';
import { getGoal, getGoalCycle } from '../services';
import { type GoalTeamUser } from '../types';
import {
  canLogProgressByConfig,
  isGoalCycleFinishedStatus,
  isGoalFinishedStatus,
} from '../utils';

import AddProgress from './components/AddProgress';
import ProgressBar from './components/ProgressBar';
import ProgressHistoryTable from './components/ProgressHistoryTable';
import Responsible from './components/Responsible';

type LocationState = {
  cycleId: number;
  selectedReview: number;
  backLink: string;
  goalUser: GoalTeamUser;
  goalCycleId: number;
};

const GoalDetail = () => {
  const { id } = useParams();
  const { t } = useLokaliseTranslation('goals');
  const theme = useTheme();
  const HuGoThemeProvider = useHuGoTheme();
  const navigate = useNavigate();
  const { user } = useAuth();
  const goalId = id ? parseInt(id) : undefined;
  const { state } = useLocation();
  const { selectedReview, cycleId, backLink, goalUser, goalCycleId } =
    (state as LocationState) || {};

  const handleClose = () => {
    if (backLink) {
      navigate(backLink, {
        state: {
          goalUser: goalUser,
          goalCycleId: goalCycleId,
        },
      });
    } else {
      if (cycleId) {
        navigate(performanceRoutes.review.detail(cycleId), {
          state: { selectedReview: selectedReview },
        });
      } else {
        navigate(goalsRoutes.goals());
      }
    }
  };

  const { data: goal, isLoading: goalLoading } = useQuery(
    goalsKeys.detail(goalId ?? 0),
    () => getGoal(goalId as number),
    {
      select: r => r.data,
      enabled: !isNil(goalId),
    },
  );

  const goalCycleIdFromGoal = goal?.goalCycleId;
  const { data: goalCycle, isLoading: goalCycleLoading } = useQuery(
    goalsKeys.cycle(goalCycleIdFromGoal ?? 0),
    () => getGoalCycle(goalCycleIdFromGoal as number),
    {
      select: r => r.data,
      enabled: !isNil(goalCycleIdFromGoal),
    },
  );

  const goalUserId = goal?.goalOwners?.[0]?.userId;
  const { data: userBosses, isLoading: bossesLoading } = useQuery(
    profileKeys.bosses(goalUserId ?? 0),
    () => getUserBosses(goalUserId as number),
    {
      enabled: !isNil(goalUserId),
      select: r => r.data?.items?.map(u => u.id),
    },
  );

  const isLoading = goalLoading || bossesLoading || goalCycleLoading;
  const isOwner = user?.id === goalUserId;
  const isBoss = userBosses?.includes(user?.id || 0) ?? false;
  const canAddProgress =
    !isLoading &&
    goalCycle &&
    !isGoalCycleFinishedStatus(goalCycle.status) &&
    !isGoalFinishedStatus(goal?.status) &&
    canLogProgressByConfig(goalCycle.progressControlConfig, {
      isOwner,
      isBoss,
    });

  return (
    <HuGoThemeProvider>
      <Helmet>
        <title>{formatTitle(t('detail.title'))}</title>
      </Helmet>
      <Stack
        id="goal-layout"
        sx={{
          backgroundColor: theme.palette.new.background.layout.default,
          height: '100%',
          flexDirection: 'column',
          minHeight: 0,
        }}
      >
        <Stack
          sx={{
            flexDirection: 'row',
            alignItems: 'center',
            justifyContent: 'space-between',
            backgroundColor: theme.palette.new.background.layout.tertiary,
            px: 2,
            py: 1.5,
            gap: 1,
            position: 'sticky',
            top: 0,
            left: 0,
            zIndex: 200,
          }}
        >
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              gap: 1,
            }}
          >
            <IconButton
              aria-label="back"
              sx={{ p: 0 }}
              onClick={handleClose}
            >
              <IconArrowLeft />
            </IconButton>
            <Typography
              variant="globalL"
              fontWeight="fontWeightSemiBold"
              color="new.text.neutral.default"
            >
              {t('detail.title')}
            </Typography>
          </Stack>
          <IconButton
            aria-label="close"
            sx={{ p: 0 }}
            onClick={handleClose}
          >
            <CloseIcon />
          </IconButton>
        </Stack>
        {isLoading && <Spinner sx={{ mt: 1 }} />}
        {!isLoading && !goal && (
          <Stack
            sx={{ px: 8, py: 4 }}
            data-testid="goal-detail-load-error"
          >
            <HuAlert
              severity="error"
              title={t('detail.goal_detail_error')}
            />
          </Stack>
        )}
        {!isLoading && goal && user && (
          <Stack
            sx={{
              flexDirection: 'row',
              flex: 1,
              minHeight: 0,
              overflow: 'auto',
              // Avoid default stretch: with stretch, columns match the viewport height of this
              // scroll container, so backgrounds end mid-scroll and the dashboard shows white below.
              alignItems: 'flex-start',
              backgroundColor: theme.palette.new.background.layout.default,
            }}
          >
            <Stack
              sx={{
                flex: 1,
                backgroundColor: theme.palette.new.background.layout.default,
                px: 4,
                py: 3,
                gap: 3,
                alignItems: 'stretch',
              }}
            >
              <ProgressBar goal={goal} />
              {canAddProgress && <AddProgress goal={goal} />}
              <ProgressHistoryTable goalId={goal.id} />
            </Stack>
            <Stack
              sx={{
                width: '360px',
                flexShrink: 0,
                alignSelf: 'stretch',
                backgroundColor: theme.palette.new.background.layout.default,
                px: 3,
                py: 3,
                gap: 3,
              }}
            >
              <Responsible
                goal={goal}
                goalCycleTitle={goalCycle?.name || ''}
              />
              {!!goal.description?.trim() && (
                <Stack
                  sx={{
                    border: `1px solid ${theme.palette.new.border.neutral.default}`,
                    borderRadius: '16px',
                    backgroundColor:
                      theme.palette.new.background.elements.default,
                    p: 3,
                    gap: 0,
                  }}
                >
                  <Typography
                    variant="globalM"
                    fontWeight="fontWeightSemiBold"
                    color="new.text.neutral.default"
                  >
                    {t('detail.description')}
                  </Typography>
                  <RichText
                    text={goal.description}
                    sx={{
                      color: theme.palette.new.text.neutral.lighter,
                      mb: 0,
                      textAlign: 'justify',
                      wordBreak: 'break-word',
                      overflowWrap: 'anywhere',
                      fontSize: '14px',
                      fontWeight: 400,
                    }}
                  />
                </Stack>
              )}
            </Stack>
          </Stack>
        )}
      </Stack>
    </HuGoThemeProvider>
  );
};

export default GoalDetail;
