import { type FC, useEffect, useMemo, useRef, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { FormProvider, useForm } from 'react-hook-form';
import { useInfiniteQuery, useQuery } from 'react-query';
import { useNavigate } from 'react-router';

import { parseAsArrayOf, parseAsString, useQueryState } from 'nuqs';
import { useDebounce } from '@material-hu/hooks/useDebounce';
import {
  IconChevronRight,
  IconFileCheck,
  IconLayoutGrid,
} from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuBadge from '@material-hu/components/design-system/Badge';
import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';
import HuListItem from '@material-hu/components/design-system/List/components/ListItem';
import HuListItemSkeleton from '@material-hu/components/design-system/List/components/ListItemSkeleton';
import Skeleton from '@material-hu/components/design-system/Skeleton';
import StateCard from '@material-hu/components/design-system/StateCard';

import { logEvent } from 'src/config/logging';
import { EVENTS_SOCKETS } from 'src/constants/sockets';
import { useAuth } from 'src/contexts/JWTContext';
import { useSocket } from 'src/contexts/SocketContext';
import useFeatureFlag from 'src/hooks/useFeatureFlag';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import ServiceBanner from 'src/pages/dashboard/serviceManagement/general/ServiceBanner';
import useBubbalooCount from 'src/pages/dashboard/serviceManagement/hooks/useBubbalooCount';
import { serviceManagementKeys } from 'src/pages/dashboard/serviceManagement/queries';
import { serviceManagementRoutes } from 'src/pages/dashboard/serviceManagement/routes';
import {
  getCountForTaskType,
  getStates,
  getTasks,
} from 'src/pages/dashboard/serviceManagement/services';
import {
  ServiceItemTypes,
  ServiceManagementRole,
  type Task,
  TasksType,
  type TicketListParams,
} from 'src/pages/dashboard/serviceManagement/types';
import {
  getStateName,
  getStatusPillProps,
  getTaskID,
} from 'src/pages/dashboard/serviceManagement/utils';
import { EventName } from 'src/types/amplitude';
import { BubbleCode } from 'src/types/bubbaloo';
import { FeatureFlags } from 'src/types/featureFlags';
import { formatDateDifference } from 'src/utils/date';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import InfiniteList from 'src/components/list/InfiniteList';

import {
  ORDER_BY_DEFAULT_VALUE,
  ORDER_DEFAULT_VALUE,
} from '../agentWorkspace/constants';
import { useModuleConfiguration } from '../contexts/ModuleConfigurationContext';
import ContainerLayout from '../general/ContainerLayout';
import useTaskCommentsUpdater from '../hooks/useTaskCommentsUpdater';
import useTaskStateListUpdater from '../hooks/useTaskStateListUpdater';

import StatesFilterDrawer from './StatesFilterDrawer';

export type ServicePortalFormValues = {
  states: string[];
};

const PortalLoadingSkeleton: FC = () => {
  return (
    <Stack
      sx={{
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
        gap: 2,
      }}
    >
      {Array.from({ length: 2 }).map((_, index) => (
        <HuCardContainer
          key={index}
          hasShadow
          padding={0}
          fullWidth
        >
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              gap: 2,
              py: 1,
              px: 2,
            }}
          >
            <Skeleton
              width={70}
              height={60}
              variant="rounded"
            />
            <Skeleton
              width="100%"
              height={80}
              variant="text"
            />
            <Skeleton
              width={30}
              height={30}
              variant="rounded"
            />
          </Stack>
        </HuCardContainer>
      ))}
    </Stack>
  );
};

const MyRequests: FC = () => {
  const { t } = useLokaliseTranslation(['service_management', 'general']);
  const HuGoThemeProvider = useHuGoTheme();
  const navigate = useNavigate();
  const socket = useSocket();
  const { user } = useAuth();
  const [filterDrawerOpen, setFilterDrawerOpen] = useState(false);

  const form = useForm<ServicePortalFormValues>({
    defaultValues: {
      states: [],
    },
    mode: 'onChange',
  });

  useEffect(() => {
    logEvent(EventName.SERVICE_MGMT_PORTAL_LIST_VIEWED, {
      role: ServiceManagementRole.INITIATOR,
    });
  }, []);

  const {
    moduleQuery: { data: moduleConfiguration, isLoading: loadingConfiguration },
  } = useModuleConfiguration();

  const { data: statesData, isLoading: statesLoading } = useQuery(
    serviceManagementKeys.states.all(),
    () => getStates(ServiceItemTypes.INCIDENT),
    {
      select: response => response.data,
      enabled: !!moduleConfiguration?.stateMachineEnabled,
    },
  );

  const handleApply = async () => {
    const values = form?.getValues();
    await setStatesParam(values.states);
    setFilterDrawerOpen(false);
  };

  const handleReset = async () => {
    await setStatesParam(null);
    setFilterDrawerOpen(false);
  };

  const handleToggle = () => setFilterDrawerOpen(!filterDrawerOpen);

  const [isSticky, setIsSticky] = useState(false);
  const sentinelRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const sentinel = sentinelRef.current;
    if (!sentinel) return;
    const observer = new IntersectionObserver(([entry]) =>
      setIsSticky(!entry.isIntersecting),
    );
    observer.observe(sentinel);
    return () => observer.disconnect();
  }, []);

  const [query, setQuery] = useState<string>('');
  const debouncedQuery = useDebounce(query);

  const [selectedStates, setStatesParam] = useQueryState(
    'states',
    parseAsArrayOf(parseAsString),
  );

  useEffect(() => {
    form.reset({
      states: selectedStates || [],
    });
  }, [selectedStates, form]);

  const params: Omit<TicketListParams, 'page'> = useMemo(
    () => ({
      q: debouncedQuery,
      limit: 10,
      order: ORDER_DEFAULT_VALUE,
      orderBy: ORDER_BY_DEFAULT_VALUE,
      role: TasksType.USER,
      statesIn: selectedStates?.join(',') || null,
    }),
    [debouncedQuery, selectedStates],
  );

  const {
    data,
    isLoading,
    isError,
    fetchNextPage,
    hasNextPage,
    isFetching,
    isFetchingNextPage,
  } = useInfiniteQuery(
    serviceManagementKeys.tasks.list(params),
    ({ pageParam = '' }) => getTasks({ ...params, cursor: pageParam }),
    {
      keepPreviousData: true,
      getNextPageParam: lastPage => lastPage.data.cursor,
      select: response => ({
        ...response,
        pages: response.pages.map(page => page.data),
      }),
      onError: () => {
        // Prevent global error handler
      },
    },
  );

  const { data: approvalsCount, isLoading: isLoadingApprovalsCount } = useQuery(
    serviceManagementKeys.tasks.count({
      role: TasksType.AGENT,
      type: ServiceItemTypes.APPROVAL,
    }),
    () => getCountForTaskType(TasksType.AGENT, ServiceItemTypes.APPROVAL),
    {
      select: response => response.data.count,
    },
  );

  const bubblesEnabled = useFeatureFlag(
    FeatureFlags.SERVICE_MANAGEMENT_BUBBLES_ENABLED,
  );
  const { data: approvalsBubble = 0 } = useBubbalooCount(
    BubbleCode.SM_APPROVAL,
  );
  useTaskCommentsUpdater({
    socket,
    params,
    event: EVENTS_SOCKETS.SERVICE_MANAGER_TASK_NEW_COMMENT,
  });
  useTaskStateListUpdater({ socket, params });

  const handleRowClick = (task: Task) =>
    navigate(serviceManagementRoutes.userSide.detail(task.id), {
      state: { navigatedFromServiceMgmt: true },
    });

  const allTasks = data?.pages?.flatMap(page => page.items) || [];
  const noSearch =
    !debouncedQuery && (!selectedStates || selectedStates?.length === 0);

  const emptyTitle = noSearch
    ? t('no_results')
    : t(
        !selectedStates?.length
          ? 'no_results_found_search'
          : 'no_results_found_search_with_filters',
      );
  const emptyDescription = noSearch
    ? t('no_results_description_user')
    : t(
        !selectedStates?.length
          ? 'try_again_search'
          : 'try_again_search_with_filters',
      );

  const loading =
    (!isLoading && !(isFetching && !isFetchingNextPage)) ||
    isLoadingApprovalsCount;

  const filterLoading = statesLoading || loadingConfiguration;
  const showApprovals = !!approvalsCount && approvalsCount > 0;

  return (
    <HuGoThemeProvider>
      <Helmet>
        <title>{formatTitle(t('my_requests'))}</title>
      </Helmet>
      <Stack
        sx={{
          backgroundColor: theme => theme.palette.new.background.layout.default,
        }}
      >
        <ContainerLayout
          sx={{
            pt: 3,
            px: 3,
            pb: 0,
            display: 'flex',
            flexDirection: 'column',
          }}
        >
          <ServiceBanner
            color={moduleConfiguration?.coverColor}
            loading={loadingConfiguration}
          />
        </ContainerLayout>
        <div ref={sentinelRef} />
        <Stack
          sx={{
            position: 'sticky',
            top: 0,
            zIndex: 10,
            backgroundColor: theme =>
              theme.palette.new.background.layout.default,
            boxShadow: isSticky
              ? theme =>
                  `0px 4px 8px -2px ${theme.palette?.new?.shadows['4dp']}`
              : 'none',
          }}
        >
          <ContainerLayout
            sx={{
              px: 3,
              pt: 4,
              pb: 4,
              gap: 3,
              display: 'flex',
              flexDirection: 'column',
            }}
          >
            {!isLoadingApprovalsCount && (
              <Stack
                sx={{
                  flexDirection: 'row',
                  alignItems: 'center',
                  justifyContent: 'space-between',
                  gap: 2,
                }}
              >
                <HuCardContainer
                  hasShadow
                  padding={0}
                  sx={{ width: '100%' }}
                  onClick={() => {
                    navigate(serviceManagementRoutes.userSide.serviceItems());
                    logEvent(EventName.SERVICE_MGMT_CATALOG_VIEWED, {
                      role: ServiceManagementRole.INITIATOR,
                    });
                  }}
                >
                  <HuListItem
                    avatar={{
                      Icon: IconLayoutGrid,
                      variant: 'square',
                      color: 'primary',
                    }}
                    slotProps={{
                      avatar: {
                        sx: {
                          height: '64px',
                          width: '64px',
                          mr: 1,
                        },
                        size: 'large',
                      },
                    }}
                    text={{
                      title: t('service_catalog'),
                      description: t('service_catalog_description'),
                    }}
                    action={{
                      Icon: IconChevronRight,
                      onClick: () => {
                        navigate(
                          serviceManagementRoutes.userSide.serviceItems(),
                        );
                        logEvent(EventName.SERVICE_MGMT_CATALOG_VIEWED, {
                          role: ServiceManagementRole.INITIATOR,
                        });
                      },
                    }}
                  />
                </HuCardContainer>
                {showApprovals && (
                  <HuCardContainer
                    hasShadow
                    padding={0}
                    sx={{ width: '100%' }}
                    onClick={() => {
                      navigate(serviceManagementRoutes.approvalsPortal());
                    }}
                  >
                    <HuListItem
                      avatar={{
                        Icon: IconFileCheck,
                        variant: 'square',
                        color: 'info',
                      }}
                      slotProps={{
                        avatar: {
                          sx: {
                            height: '64px',
                            width: '64px',
                            mr: 1,
                          },
                          size: 'large',
                        },
                      }}
                      text={{
                        title: t('approvals.portal.title'),
                        description: t('approvals.portal.description'),
                      }}
                      sideContent={
                        !!bubblesEnabled &&
                        approvalsBubble > 0 &&
                        !user?.isAgent && (
                          <HuBadge
                            badgeContent={approvalsBubble}
                            color="primary"
                            sx={{ mr: 2.5 }}
                          />
                        )
                      }
                      action={{
                        Icon: IconChevronRight,
                        onClick: () => {
                          navigate(serviceManagementRoutes.approvalsPortal());
                        },
                      }}
                    />
                  </HuCardContainer>
                )}
              </Stack>
            )}
            {isLoadingApprovalsCount && <PortalLoadingSkeleton />}
            <Typography
              variant="globalS"
              fontWeight="semiBold"
              sx={{ ml: 1, mt: 1 }}
            >
              {t('my_requests')}
            </Typography>
            <Stack
              sx={{
                flexDirection: 'row',
                alignItems: 'center',
                gap: 2,
              }}
            >
              <HuSearch
                placeholder={t('search_ticket')}
                value={query}
                onChange={value => setQuery(value)}
              />
              {!filterLoading && (
                <FormProvider {...form}>
                  <StatesFilterDrawer
                    open={filterDrawerOpen}
                    onToggle={handleToggle}
                    onApply={handleApply}
                    onReset={handleReset}
                    statesData={statesData || []}
                    filterCount={selectedStates?.length ? 1 : 0}
                  />
                </FormProvider>
              )}
              {filterLoading && (
                <Skeleton
                  width={116}
                  height={35}
                  variant="rounded"
                />
              )}
            </Stack>
          </ContainerLayout>
        </Stack>
        <ContainerLayout
          sx={{
            px: 3,
            pt: 2,
            pb: 3,
            display: 'flex',
            flexDirection: 'column',
          }}
        >
          <InfiniteList
            isLoading={isLoading || (isFetching && !isFetchingNextPage)}
            isSuccess={
              !isLoading && !(isFetching && !isFetchingNextPage) && !isError
            }
            isEmpty={!allTasks.length}
            fetchNextPage={fetchNextPage}
            hasNextPage={hasNextPage}
            isFetchingNextPage={isFetchingNextPage}
            loadingSkeleton
            sx={{ gap: 2, alignItems: 'center' }}
            noResultsLabel={
              <StateCard
                variant="primary"
                title={t(emptyTitle)}
                description={t(emptyDescription)}
              />
            }
            renderSkeleton={
              <HuCardContainer
                sx={{ width: '100%', py: 1 }}
                padding={0}
              >
                <HuListItemSkeleton />
              </HuCardContainer>
            }
          >
            {loading &&
              allTasks.map(task => (
                <HuCardContainer
                  key={task.id}
                  padding={0}
                  sx={{ width: '100%', mb: 2 }}
                  onClick={() => handleRowClick(task)}
                >
                  <HuListItem
                    text={{
                      title: (
                        <Stack
                          sx={{
                            flexDirection: 'row',
                            gap: 1,
                            alignItems: 'center',
                          }}
                        >
                          {(bubblesEnabled
                            ? task.bubbleCount > 0
                            : (task.unreadCommentsCount ?? 0) > 0) && (
                            <HuBadge
                              variant="dot"
                              color="primary"
                            />
                          )}
                          <Typography
                            variant="globalS"
                            fontWeight="fontWeightSemiBold"
                          >
                            {task.catalogItem.name}
                          </Typography>
                        </Stack>
                      ),
                      copetin: formatDateDifference(task.updatedAt, t),
                      description: getTaskID(task),
                    }}
                    sidePill={{
                      label: t(getStateName(task.state.name)),
                      type: getStatusPillProps(task.state, t)?.type,
                    }}
                  />
                </HuCardContainer>
              ))}
          </InfiniteList>
        </ContainerLayout>
      </Stack>
    </HuGoThemeProvider>
  );
};

export default MyRequests;
