import { useMemo } from 'react';
import { type UseMutationResult } from 'react-query';
import { useNavigate } from 'react-router';

import { isNil } from 'lodash-es';
import {
  IconEdit,
  IconTargetArrow,
  IconTrash,
} from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuListItem from '@material-hu/components/design-system/List/components/ListItem';
import HuProgressBar from '@material-hu/components/design-system/ProgressIndicators/ProgressBar';
import HuTitle from '@material-hu/components/design-system/Title';

import { useAuth } from 'src/contexts/JWTContext';
import {
  isGoalDraftStatus,
  isGoalFinishedStatus,
  isGoalInProgressStatus,
} from 'src/pages/dashboard/goals/utils';
import { insertIf } from 'src/utils/arrays';
import { formatDateFromISO } from 'src/utils/date';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getFullName, getInitials } from 'src/utils/userUtils';

import { GoalCardVariant } from '../constants';
import { goalsRoutes } from '../routes';
import { type Goal, type GoalTeamUser } from '../types';

import { useDeleteGoalModal } from './DeleteGoalModal';
import GoalCardMenu, { type GoalCardMenuOption } from './GoalCardMenu';
import { useGoalFeaturesConfigContext } from './GoalFeaturesConfigContext';
import GoalStatusPill from './GoalStatusPill';

type GoalCardProps = {
  goal: Goal;
  deleteGoal: UseMutationResult<unknown, unknown, { id: number }, unknown>;
  variant?: GoalCardVariant;
  weight?: number;
  customBackLink?: string;
  goalCycleId?: number;
  goalUser?: GoalTeamUser;
  isBoss?: boolean;
};

const GoalCard = ({
  goal,
  deleteGoal,
  variant = GoalCardVariant.INDIVIDUAL,
  weight,
  customBackLink,
  goalCycleId,
  goalUser,
  isBoss,
}: GoalCardProps) => {
  const navigate = useNavigate();
  const { t } = useLokaliseTranslation('goals');
  const { user: loggedUser } = useAuth();
  const { isApprovalFlowEnabled, isBossCanEditPublishedObjectives } =
    useGoalFeaturesConfigContext();
  const { showDeleteModal } = useDeleteGoalModal(deleteGoal);

  const isOwner = goal.responsibleId === loggedUser?.id;
  const isOwnerOrBoss = isOwner || !!isBoss;
  const isDraft = isGoalDraftStatus(goal.status);
  const isInProgress = isGoalInProgressStatus(goal.status);
  const canEditByRole = useMemo(() => {
    if (!isApprovalFlowEnabled) return true;
    if (isOwnerOrBoss) return isDraft || isInProgress;
    return isDraft;
  }, [isApprovalFlowEnabled, isOwnerOrBoss, isDraft, isInProgress]);

  const isEditDisabled =
    isGoalFinishedStatus(goal.status) ||
    (!isBossCanEditPublishedObjectives && !isDraft && !isBoss);
  const canEdit = canEditByRole && !isEditDisabled && (isDraft || isInProgress);

  const handleCardClick = () => {
    const navigateState = customBackLink
      ? {
          state: {
            backLink: customBackLink,
            goalUser,
            goalCycleId,
          },
        }
      : undefined;

    if (canEdit && isDraft) {
      navigate(goalsRoutes.edit(goal.id), navigateState);
    } else {
      navigate(goalsRoutes.detail(goal.id), navigateState);
    }
  };

  const getDescriptionText = () => {
    if (variant === GoalCardVariant.GENERAL) {
      return t('new.status_updated', {
        end: formatDateFromISO(goal.endDate),
        updated: formatDateFromISO(goal.updatedAt),
      });
    }
    return t('new.end_updated', {
      end: formatDateFromISO(goal.endDate),
      start: formatDateFromISO(goal.startDate),
    });
  };

  const weightValue = weight ?? goal?.weight;

  const goalCardOptions: GoalCardMenuOption[] = useMemo(
    () => [
      {
        id: `goal-${goal.id}-view`,
        icon: IconTargetArrow,
        title: t('list.menu.view'),
        onClick: () =>
          navigate(
            goalsRoutes.detail(goal.id),
            customBackLink
              ? {
                  state: {
                    backLink: customBackLink,
                    goalUser,
                    goalCycleId,
                  },
                }
              : undefined,
          ),
      },
      ...insertIf(canEdit, {
        id: `goal-${goal.id}-edit`,
        icon: IconEdit,
        title: t('list.menu.edit'),
        onClick: () =>
          navigate(
            goalsRoutes.edit(goal.id),
            customBackLink
              ? {
                  state: {
                    backLink: customBackLink,
                    goalUser,
                    goalCycleId,
                  },
                }
              : undefined,
          ),
      }),
      ...insertIf(canEdit, {
        id: `goal-${goal.id}-delete`,
        icon: IconTrash,
        title: t('list.menu.delete'),
        onClick: () => showDeleteModal(goal.id),
        showChevron: false,
      }),
    ],
    [
      navigate,
      goal.id,
      customBackLink,
      goalUser,
      goalCycleId,
      canEdit,
      t,
      showDeleteModal,
    ],
  );

  return (
    <HuListItem
      sx={{
        borderRadius: 2,
        overflow: 'hidden',
        backgroundColor: theme => theme.palette.new?.background.layout.tertiary,
        border: theme =>
          `1px solid ${theme.palette.new?.border.neutral.default}`,
        transition: 'all 0.2s ease-in-out',
        '&:hover': {
          borderRadius: 2,
          boxShadow: 'none',
        },
      }}
      {...(variant === GoalCardVariant.GENERAL && {
        avatar: {
          color: 'primary',
          src: goal.goalOwners[0]?.ownerUser?.profilePicture,
          text: getInitials(getFullName(goal.goalOwners[0]?.ownerUser)),
        },
      })}
      onClick={handleCardClick}
      actionMenuList={
        <GoalCardMenu
          menuId={`goal-${goal.id}-menu`}
          label={t('list.menu')}
          options={goalCardOptions}
        />
      }
      sideContent={
        <Stack
          sx={{
            gap: 2,
            width: '100%',
            flexDirection: 'row',
            alignItems: 'center',
          }}
        >
          {!isNil(weightValue) && (
            <HuTitle
              variant="M"
              copetin={t('my_team.weight')}
              title={`${weightValue}%`}
            />
          )}
          <GoalStatusPill goalStatus={goal.status} />
          <Stack
            sx={{ width: variant === GoalCardVariant.GENERAL ? 425 : '25vw' }}
          >
            {variant === GoalCardVariant.GENERAL && (
              <Typography
                variant="globalXXS"
                color="new.text.neutral.lighter"
              >
                {t('my_team.progress')}
              </Typography>
            )}
            <HuProgressBar
              variant="determinate"
              current={
                isGoalFinishedStatus(goal.status) ? 100 : goal.progress || 0
              }
              hasPercentage
              sx={{ width: '100%' }}
            />
          </Stack>
        </Stack>
      }
      text={{
        title: goal?.title,
        copetin:
          variant === GoalCardVariant.GENERAL
            ? getFullName(goal.goalOwners[0]?.ownerUser)
            : undefined,
        description: getDescriptionText(),
      }}
    />
  );
};

export default GoalCard;
