import { type FC, useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { type TFunction, Trans } from 'react-i18next';
import { useInfiniteQuery } from 'react-query';

import {
  IconAlertTriangle,
  IconInfoSquareRounded,
} from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';

import HuStateCard from '@material-hu/components/composed-components/StateCard';
import HuDrawer from '@material-hu/components/design-system/Drawer';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';
import HuCircularProgress from '@material-hu/components/design-system/ProgressIndicators/Spinner';

import useDebounceSearchQuery from 'src/hooks/useDebounceSearch';
import { type User } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { InfiniteList } from 'src/components/InfiniteList';

import AgentListDrawer from '../../../AgentManagement/components/AgentListDrawer';
import { serviceManagementKeys } from '../../../queries';
import { getAgentGroupsHydrated } from '../../../services';
import { type AgentGroupHydrated, AgentGroupStatus } from '../../../types';
import { newServiceItemFields } from '../../forms';

import AgentGroupSelectionCard from './AgentGroupSelectionCard';

type Props = {
  open: boolean;
  onClose: () => void;
  onApply: () => void;
  onCancel: () => void;
};

const LIMIT = 10;
const agentGroupFormName = newServiceItemFields.assignment.agentGroup();

const AssignAgentGroupDrawer: FC<Props> = ({
  open,
  onClose,
  onApply,
  onCancel,
}) => {
  const { t } = useLokaliseTranslation(['service_management', 'general']);
  const { debouncedQuery, query, onChange } = useDebounceSearchQuery({
    initialQuery: '',
    debounceTime: 500,
  });

  const [isAgentListDrawerOpen, setIsAgentListDrawerOpen] = useState(false);
  const [agentGroupToShowMembers, setAgentGroupToShowMembers] =
    useState<AgentGroupHydrated | null>(null);

  const { setValue, watch } = useFormContext();

  const selectedAgentGroup = watch(agentGroupFormName);

  const {
    data,
    isLoading,
    fetchNextPage,
    hasNextPage,
    isSuccess,
    isError,
    refetch,
    isFetchingNextPage,
  } = useInfiniteQuery(
    serviceManagementKeys.agentGroups.list(LIMIT, debouncedQuery),
    ({ pageParam = 1 }) =>
      getAgentGroupsHydrated({
        page: pageParam,
        limit: LIMIT,
        name: debouncedQuery,
        status: AgentGroupStatus.ACTIVE,
      }),
    {
      refetchOnMount: false,
      enabled: !!open,
      getNextPageParam: lastPage =>
        lastPage.data.page === lastPage.data.totalPages
          ? undefined
          : lastPage.data.page + 1,
    },
  );

  const agentGroups = data?.pages.flatMap(page => page.data.items);

  const handleSelectAgentGroup = (agentGroup: AgentGroupHydrated) => {
    setValue(agentGroupFormName, agentGroup);
  };

  const handleShowAgentGroupMembers = (agentGroup: AgentGroupHydrated) => {
    setAgentGroupToShowMembers(agentGroup);
    setIsAgentListDrawerOpen(true);
  };

  const handleCloseAgentListDrawer = () => {
    setIsAgentListDrawerOpen(false);
    setAgentGroupToShowMembers(null);
  };

  const noAgentGroups = (agentGroups?.length ?? 0) === 0;
  const showNoAgentGroupsCreated =
    isSuccess && !debouncedQuery && noAgentGroups;
  const showEmptySearch = !isLoading && agentGroups?.length === 0 && !!query;

  return (
    <HuDrawer
      title={t('agent_groups')}
      open={open}
      onClose={onClose}
      primaryButtonProps={{
        onClick: onApply,
        disabled: !selectedAgentGroup,
        children: t('general:apply'),
        fullWidth: true,
      }}
      secondaryButtonProps={{
        onClick: onCancel,
        children: t('general:cancel'),
        fullWidth: true,
      }}
    >
      {agentGroupToShowMembers && (
        <AgentListDrawer
          open={isAgentListDrawerOpen}
          onClose={handleCloseAgentListDrawer}
          agents={agentGroupToShowMembers.agents as User[]}
        />
      )}
      <Stack sx={{ gap: 2 }}>
        {!showNoAgentGroupsCreated && (
          <HuSearch
            value={query}
            onChange={onChange}
            placeholder={t('search_agent_group')}
          />
        )}
        {isError && (
          <HuStateCard
            slotProps={{
              avatar: {
                Icon: IconAlertTriangle,
                size: 'large',
                color: 'error',
              },
              title: {
                title: t('error_search_agent_group'),
                description: t('try_again_later'),
              },
              button: {
                variant: 'secondary',
                children: t('try_again'),
                onClick: () => {
                  refetch();
                },
              },
            }}
            sx={{
              border: 'none',
              backgroundColor: ({ palette }) =>
                palette.new.background.elements.grey,
            }}
          />
        )}
        {showEmptySearch && (
          <HuStateCard
            slotProps={{
              avatar: {
                Icon: IconInfoSquareRounded,
                size: 'large',
                color: 'primary',
              },
              title: {
                title: t('empty_search_service_item_list_title'),
                description: t('try_with_other_search'),
              },
            }}
            sx={{
              border: 'none',
              backgroundColor: ({ palette }) =>
                palette.new.background.elements.grey,
            }}
          />
        )}
        {showNoAgentGroupsCreated && (
          <HuStateCard
            slotProps={{
              avatar: {
                Icon: IconInfoSquareRounded,
                size: 'large',
                color: 'primary',
              },
              title: {
                title: t('no_agent_groups_created'),
                description: (
                  <Trans
                    i18nKey={t('no_agent_groups_created_description')}
                    t={t as TFunction}
                    components={{ b: <b /> }}
                  />
                ),
              },
            }}
            sx={{
              border: 'none',
              backgroundColor: ({ palette }) =>
                palette.new.background.elements.grey,
            }}
          />
        )}
        {isLoading && <HuCircularProgress />}
        {!isLoading && agentGroups && agentGroups.length > 0 && (
          <InfiniteList
            isSuccess={isSuccess}
            isLoading={isLoading}
            isFetchingNextPage={isFetchingNextPage}
            fetchNextPage={fetchNextPage}
            hasNextPage={!!hasNextPage}
            sx={{ flexDirection: 'column', display: 'flex', gap: 2 }}
          >
            {agentGroups.map(agentGroup => (
              <AgentGroupSelectionCard
                key={agentGroup.id}
                agentGroup={agentGroup}
                onSelect={handleSelectAgentGroup}
                onShowMembers={handleShowAgentGroupMembers}
                selected={agentGroup.id === selectedAgentGroup?.id}
              />
            ))}
          </InfiniteList>
        )}
      </Stack>
    </HuDrawer>
  );
};

export default AssignAgentGroupDrawer;
