import { useCallback, useEffect, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { useMutation } from 'react-query';
import { useLocation, useNavigate, useParams } from 'react-router-dom';

import useSnackbar from '@material-hu/components/design-system/Snackbar';
import { useDialogLayer } from '@material-hu/components/layers/Dialogs';

import { logEvent } from 'src/config/logging';
import { useAuth } from 'src/contexts/JWTContext';
import useCustomServerTranslation from 'src/hooks/useCustomServerTranslation';
import useGeneralError from 'src/hooks/useGeneralError';
import { EventName } from 'src/types/amplitude';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { MODULE_NAME } from '../constants';
import { goalsRoutes } from '../routes';
import { createGoal, updateGoal } from '../services';
import {
  type Goal,
  GoalErrorCodes,
  type GoalPayload,
  type GoalTeamUser,
} from '../types';
import {
  getNoSaveModalText,
  isGoalFinishedStatus,
  isSouthbayInstance,
  isTissurInstance,
} from '../utils';

import NewGoalForm from './components/NewGoalForm';
import { useNewGoalQueries } from './hooks/useNewGoalQueries';
import { buildGoalPayload } from './utils/goalForm';

const NewGoalPage = () => {
  const { t } = useLokaliseTranslation('goals');
  const navigate = useNavigate();
  const location = useLocation();
  const showGeneralError = useGeneralError();
  const { enqueueSnackbar } = useSnackbar();
  const { user: loggedUser, instance } = useAuth();
  const goalsTitle = useCustomServerTranslation({
    module: MODULE_NAME,
    defaultTranslationKey: 'general:goals',
  });
  const { openDialog, closeDialog } = useDialogLayer();

  const { id } = useParams();
  const goalId = id ? parseInt(id, 10) : null;
  const instanceId = instance?.id;

  const routerState = location.state as {
    goalCycleId?: number;
    backLink?: string;
    goalUser?: GoalTeamUser;
  } | null;
  const cycleIdFromRouter = routerState?.goalCycleId || null;
  const goalUserFromRouter = routerState?.goalUser || null;

  const [createdGoalId, setCreatedGoalId] = useState(goalId);

  const isTissur = isTissurInstance(instanceId);
  const isSouthbay = isSouthbayInstance(instanceId);

  const { goal, isGoalLoading, subordinates } = useNewGoalQueries({
    goalId,
    loggedUserId: loggedUser?.id,
  });

  useEffect(() => {
    if (!goalId || !goal || isGoalLoading) return;
    if (!isGoalFinishedStatus(goal.status)) return;
    navigate(goalsRoutes.detail(goalId), {
      state: {
        backLink: routerState?.backLink,
        goalUser: goalUserFromRouter,
        goalCycleId: cycleIdFromRouter,
      },
    });
  }, [
    goalId,
    goal,
    isGoalLoading,
    navigate,
    routerState?.backLink,
    goalUserFromRouter,
    cycleIdFromRouter,
  ]);

  const { mutate: createGoalMutate } = useMutation(
    ({ body, publish }: { body: GoalPayload; publish: boolean }) =>
      createGoal(body, publish),
  );

  const { mutate: updateGoalMutate } = useMutation(
    ({ id: goalIdParam, body }: { id: number; body: GoalPayload }) =>
      updateGoal(goalIdParam, body),
  );

  const handleMutationError = useCallback(
    (err: unknown) => {
      const code = (err as { response?: { data?: { code?: string } } })
        ?.response?.data?.code;
      if (
        [
          GoalErrorCodes.INVALID_GOAL_OWNER,
          GoalErrorCodes.BAD_REQUEST,
          GoalErrorCodes.INVALID_GOAL_PUBLISH,
          GoalErrorCodes.INVALID_GOAL_FORMULA_CONFIGURATION,
        ].includes(code as GoalErrorCodes)
      ) {
        const errorMessage =
          (err as { response?: { data?: { message?: string; code?: string } } })
            ?.response?.data?.message || code;
        enqueueSnackbar({ title: errorMessage, variant: 'error' });
      } else {
        showGeneralError(err);
      }
    },
    [enqueueSnackbar, showGeneralError],
  );

  const handleSave = useCallback(
    (formValues: Goal) => {
      const updatedGoal = buildGoalPayload(formValues);
      const idToUse = goalId || createdGoalId;
      const responsible = formValues.responsible;
      const goalCycleIdFromForm = formValues.goalCycleId;

      const navigateOnSuccess = () => {
        navigate(routerState?.backLink || goalsRoutes.goals(), {
          state: {
            goalCycleId: goalCycleIdFromForm,
            goalUser: goalUserFromRouter,
          },
        });
      };

      const handleCreateError = (err: unknown) => {
        const code = (err as { response?: { data?: { code?: string } } })
          ?.response?.data?.code;
        if (code === GoalErrorCodes.GOAL_CYCLE_INVALID_GOAL_COUNT_BOUNDS) {
          const text = getNoSaveModalText(responsible, loggedUser, t);
          openDialog({
            title: t('new.no_save_modal_title'),
            textBody: text,
            onClose: () => closeDialog(),
            primaryButtonProps: {
              children: t('general:accept'),
              onClick: () => closeDialog(),
            },
          });
          return;
        }
        handleMutationError(err);
      };

      if (idToUse) {
        updateGoalMutate(
          { id: idToUse, body: updatedGoal },
          {
            onSuccess: () => {
              navigateOnSuccess();
              enqueueSnackbar({ title: t('success_edit'), variant: 'success' });
            },
            onError: handleMutationError,
          },
        );
      } else {
        createGoalMutate(
          { body: updatedGoal, publish: false },
          {
            onSuccess: ({ data }) => {
              const isLoggedUserResponsible = Array.isArray(responsible)
                ? responsible?.some(
                    user => (user?.userId ?? user?.id) === loggedUser?.id,
                  )
                : (responsible?.userId ?? responsible?.id) === loggedUser?.id;

              if (!isLoggedUserResponsible) {
                setCreatedGoalId(data.id);
              }

              navigateOnSuccess();
              enqueueSnackbar({
                title: t('success_created'),
                variant: 'success',
              });
              logEvent(EventName.GOAL_CREATED, {
                goalId: data?.id,
                cycleId: data?.goalCycleId,
                type: data?.valueType,
                userType: subordinates?.length ? 'BOSS' : 'SUBORDINATE',
              });
            },
            onError: handleCreateError,
          },
        );
      }
    },
    [
      goalId,
      createdGoalId,
      loggedUser,
      subordinates,
      navigate,
      routerState?.backLink,
      goalUserFromRouter,
      t,
      openDialog,
      closeDialog,
      enqueueSnackbar,
      handleMutationError,
      updateGoalMutate,
      createGoalMutate,
    ],
  );

  const handleClose = useCallback(
    (formValues: Goal) => {
      navigate(routerState?.backLink || goalsRoutes.goals(), {
        state: {
          goalCycleId: formValues.goalCycleId,
          goalUser: goalUserFromRouter,
        },
      });
    },
    [navigate, routerState?.backLink, goalUserFromRouter],
  );

  return (
    <>
      <Helmet>
        <title>{formatTitle(goalsTitle)}</title>
      </Helmet>
      <NewGoalForm
        goalId={goalId}
        goal={goal}
        isGoalLoading={isGoalLoading}
        isTissur={isTissur}
        isSouthbay={isSouthbay}
        cycleIdFromRouter={cycleIdFromRouter}
        onSave={handleSave}
        onClose={handleClose}
      />
    </>
  );
};

export default NewGoalPage;
