import { useState } from 'react';
import { useMutation, useQuery } from 'react-query';
import { useNavigate } from 'react-router';

import { queryClient } from 'src/config/react-query';
import { RequestError } from 'src/types/services';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { logEvent, LogEvents } from 'src/utils/logging';

import useSnackbar from '../../hooks/useSnackbar';
import { serviceManagementKeys } from '../../queries';
import { serviceManagementRoutes } from '../../routes';
import {
  activateAgentGroup,
  createAgentGroup,
  deactivateAgentGroup,
  deleteAgentGroup,
  editAgentGroup,
  getAgentGroup,
} from '../../services';
import {
  AgentGroup,
  AgentGroupForm,
  AgentGroupStatus,
  ServiceManagementRole,
} from '../../types';
import { HELP_DESKS_LIMIT } from '../HelpDesks';

type Props = {
  helpDeskId?: string;
  agentGroupId?: string;
  onDuplicateError?: (duplicateName: string) => void;
};

const useAgentGroup = ({
  agentGroupId,
  helpDeskId,
  onDuplicateError,
}: Props) => {
  const { t } = useLokaliseTranslation('service_management');
  const navigate = useNavigate();
  const { showSnackbar } = useSnackbar();

  const [duplicateName, setDuplicateName] = useState<string | null>(null);

  const {
    data: agentGroup,
    isLoading: agentGroupLoading,
    isError: agentGroupError,
    refetch: refetchAgentGroup,
    isRefetching: agentGroupRefetching,
  } = useQuery(
    serviceManagementKeys.agentGroups.detail(agentGroupId!),
    () => getAgentGroup(agentGroupId!),
    {
      enabled: !!agentGroupId,
      select: data => data.data,
    },
  );

  const createGroupMutation = useMutation({
    mutationFn: ({
      formValues,
    }: {
      formValues: Omit<AgentGroupForm, 'segmentations'>;
    }) =>
      createAgentGroup({
        ...formValues,
        helpDeskId: helpDeskId as string,
        agents: formValues.agents.map(agent => agent.id),
      }),
    onSuccess: createdAgentGroup => {
      setDuplicateName(null);
      showSnackbar({
        title: t('CREATE_GROUP_SUCCESS', {
          name: createdAgentGroup.data.name,
        }),
        variant: 'success',
      });
      logEvent(LogEvents.SERVICE_MGMT_AGENT_GROUP_CREATED, {
        role: ServiceManagementRole.ADMIN,
        agent_group_id: createdAgentGroup.data.id,
      });
      navigate(`${serviceManagementRoutes.helpDesks()}?hd=${helpDeskId}`);
    },
    onError: (error: RequestError, res) => {
      if (error?.response?.data.code === 'DUPLICATE_ENTITY') {
        setDuplicateName(res.formValues.name);
        onDuplicateError?.(res.formValues.name);
      } else {
        showSnackbar({
          title: t('CREATE_GROUP_ERROR'),
          description: t('TRY_AGAIN_LATER'),
          variant: 'error',
        });
      }
    },
  });

  const editGroupMutation = useMutation({
    mutationFn: ({
      formValues,
    }: {
      formValues: Omit<AgentGroupForm, 'segmentations'>;
    }) =>
      editAgentGroup(agentGroupId!, {
        ...formValues,
        helpDeskId: helpDeskId as string,
        agents: formValues.agents.map(agent => agent.id),
      }),
    onSuccess: editedAgentGroup => {
      setDuplicateName(null);
      showSnackbar({
        title: t('EDIT_GROUP_SUCCESS', {
          name: editedAgentGroup.data.name,
        }),
        variant: 'success',
      });
      queryClient.invalidateQueries(
        serviceManagementKeys.agentGroups.detail(agentGroupId!),
      );
      navigate(`${serviceManagementRoutes.helpDesks()}?hd=${helpDeskId}`);
    },
    onError: (error: RequestError, res) => {
      if (error?.response?.data.code === 'DUPLICATE_ENTITY') {
        setDuplicateName(res.formValues.name);
        onDuplicateError?.(res.formValues.name);
      } else {
        showSnackbar({
          title: t('EDIT_GROUP_ERROR'),
          description: t('TRY_AGAIN_LATER'),
          variant: 'error',
        });
      }
    },
  });

  const deleteAgentGroupMutation = useMutation({
    mutationFn: (groupToDelete: AgentGroup) =>
      deleteAgentGroup(groupToDelete.id),
    onSuccess: (_: unknown, groupToDelete: AgentGroup) => {
      queryClient.invalidateQueries(
        serviceManagementKeys.helpDesks.list(HELP_DESKS_LIMIT),
      );
      showSnackbar({
        title: t('AGENT_GROUP_DELETE_SUCCESS', {
          name: groupToDelete.name,
        }),
        variant: 'success',
      });
      logEvent(LogEvents.SERVICE_MGMT_AGENT_GROUP_DELETED, {
        role: ServiceManagementRole.ADMIN,
        agent_group_id: groupToDelete.id,
      });
    },
    onError: () => {
      showSnackbar({
        title: t('AGENT_GROUP_DELETE_ERROR'),
        description: t('TRY_AGAIN_LATER'),
        variant: 'error',
      });
    },
  });

  const deactivateAgentGroupMutation = useMutation({
    mutationFn: (groupToDeactivate: AgentGroup) =>
      deactivateAgentGroup(groupToDeactivate.id),
    onSuccess: (_: unknown, deactivatedGroup: AgentGroup) => {
      queryClient.invalidateQueries(
        serviceManagementKeys.helpDesks.list(HELP_DESKS_LIMIT),
      );
      showSnackbar({
        title: t('AGENT_GROUP_STATUS_DEACTIVATED_SUCCESS', {
          name: deactivatedGroup.name,
        }),
        variant: 'success',
      });
      logEvent(LogEvents.SERVICE_MGMT_AGENT_GROUP_STATUS_CHANGE, {
        role: ServiceManagementRole.ADMIN,
        agent_group_id: deactivatedGroup.id,
        status: AgentGroupStatus.INACTIVE,
      });
    },
    onError: () => {
      showSnackbar({
        title: t('AGENT_GROUP_STATUS_DEACTIVATED_ERROR'),
        description: t('TRY_AGAIN_LATER'),
        variant: 'error',
      });
    },
  });

  const activateAgentGroupMutation = useMutation({
    mutationFn: (groupToActivate: AgentGroup) =>
      activateAgentGroup(groupToActivate.id),
    onSuccess: (_: unknown, activatedGroup: AgentGroup) => {
      queryClient.invalidateQueries(
        serviceManagementKeys.helpDesks.list(HELP_DESKS_LIMIT),
      );
      showSnackbar({
        title: t('AGENT_GROUP_STATUS_ACTIVATED_SUCCESS', {
          name: activatedGroup.name,
        }),
        variant: 'success',
      });
      logEvent(LogEvents.SERVICE_MGMT_AGENT_GROUP_STATUS_CHANGE, {
        role: ServiceManagementRole.ADMIN,
        agent_group_id: activatedGroup.id,
        status: AgentGroupStatus.ACTIVE,
      });
    },
    onError: () => {
      showSnackbar({
        title: t('AGENT_GROUP_STATUS_ACTIVATED_ERROR'),
        description: t('TRY_AGAIN_LATER'),
        variant: 'error',
      });
    },
  });

  const clearDuplicateName = () => {
    setDuplicateName(null);
  };

  return {
    createGroupMutation,
    editGroupMutation,
    agentGroup,
    agentGroupLoading,
    agentGroupError,
    refetchAgentGroup,
    agentGroupRefetching,
    duplicateName,
    clearDuplicateName,
    deleteAgentGroupMutation,
    deactivateAgentGroupMutation,
    activateAgentGroupMutation,
  };
};

export default useAgentGroup;
