import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useInfiniteQuery } from 'react-query';

import { zodResolver } from '@hookform/resolvers/zod';
import { type TFunction } from 'i18next';
import { isEqual } from 'lodash-es';
import { parseAsString, useQueryState } from 'nuqs';
import { type z } from 'zod';
import { useDebounce } from '@material-hu/hooks/useDebounce';
import { useHuPagination } from '@material-hu/hooks/useHuPagination';
import { IconFilter } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import BadgeCountButton from '@material-hu/components/composed-components/BadgeCountButton';
import HuBadge from '@material-hu/components/design-system/Badge';
import HuPills from '@material-hu/components/design-system/Pills';
import StateCard from '@material-hu/components/design-system/StateCard';
import HuTable from '@material-hu/components/design-system/Table';
import HuTableBody from '@material-hu/components/design-system/Table/components/TableBody';
import HuTableCell from '@material-hu/components/design-system/Table/components/TableCell';
import HuTableContainer from '@material-hu/components/design-system/Table/components/TableContainer';
import HuTableHead from '@material-hu/components/design-system/Table/components/TableHead';
import HuTableLoader from '@material-hu/components/design-system/Table/components/TableLoader';
import HuTableRow from '@material-hu/components/design-system/Table/components/TableRow';
import HuTitle from '@material-hu/components/design-system/Title';
import { useDrawerLayer } from '@material-hu/components/layers/Drawers';

import { queryClient } from 'src/config/react-query';
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 { serviceManagementKeys } from 'src/pages/dashboard/serviceManagement/queries';
import { getTasks } from 'src/pages/dashboard/serviceManagement/services';
import {
  ServiceItemTypes,
  type Task,
  TasksType,
} from 'src/pages/dashboard/serviceManagement/types';
import {
  getStateName,
  getTaskID,
  parseSubtasksFilters,
} from 'src/pages/dashboard/serviceManagement/utils';
import { FeatureFlags } from 'src/types/featureFlags';
import { formatDistanceToNow, formatLocalizedDate } from 'src/utils/date';
import { useLokaliseTranslation } from 'src/utils/i18n';

import useTaskCommentsUpdater from '../hooks/useTaskCommentsUpdater';
import useVisitTask from '../hooks/useVisitTask';
import UserTooltip from '../servicePortal/requestedDetails/components/Information/UserTooltip';
import SubtaskDetailDrawer from '../servicePortal/requestedDetails/components/SubtaskDetailDrawer';
import { getTaskPillType } from '../servicePortal/requestedDetails/components/TasksTab';
import { getUserDisplayName } from '../utils';

import AgentColumnHugo from './components/AgentColumn';
import SubtasksFiltersDrawer from './components/Subtasks/SubtasksFiltersDrawer';
import TasksTableRowSkeleton from './components/TasksTableRowSkeleton';
import { ORDER_BY_DEFAULT_VALUE, ORDER_DEFAULT_VALUE } from './constants';
import { subtasksFormSchema } from './form/schemas';
import { subtasksFiltersSchema } from './types';
import { createFilterParser, parseToValidURLDate } from './utils';

const SUBTASK_ID_PARAM = 'subtaskId';
const FILTERS_PARAM = 'filters';

const defaultFilters = {
  role: TasksType.AGENT,
  type: ServiceItemTypes.SUBTASK,
  usePage: true,
};

const EmptyRowFeedback = ({
  title,
  description,
}: {
  title: string;
  description: string;
}) => {
  return (
    <HuTableRow>
      <HuTableCell colSpan={33}>
        <Stack
          sx={{
            position: 'sticky',
            left: '50%',
            transform: 'translateX(-50%)',
            width: 'fit-content',
          }}
        >
          <StateCard
            variant="primary"
            title={title}
            description={description}
          />
        </Stack>
      </HuTableCell>
    </HuTableRow>
  );
};

export type SubtasksFormValues = z.infer<ReturnType<typeof subtasksFormSchema>>;

const defaultFiltersForm: SubtasksFormValues = {
  statesIn: [],
  parentTaskCatalogItemsIn: [],
  parentTaskInitiatorsIn: [],
  createdAtFrom: null,
  createdAtTo: null,
  dateOptions: {
    lastSevenDays: false,
    lastFourteenDays: false,
    lastThirtyDays: false,
    dateRange: false,
  },
};

const subtasksFiltersParser = createFilterParser<SubtasksFormValues>(
  subtasksFiltersSchema,
).withDefault(defaultFiltersForm);

// Strip passthrough fields from filter entities to keep the encoded URL blob small
const minimizeFilters = (filters: SubtasksFormValues): SubtasksFormValues => ({
  ...filters,
  statesIn: filters.statesIn?.map(state => ({
    id: state.id,
    name: state.name,
    terminal: state.terminal,
  })),
  parentTaskCatalogItemsIn: filters.parentTaskCatalogItemsIn?.map(item => ({
    id: item.id,
    name: item.name,
  })),
  parentTaskInitiatorsIn: filters.parentTaskInitiatorsIn?.map(initiator => ({
    id: initiator.id,
    firstName: initiator.firstName,
    lastName: initiator.lastName,
    profilePicture: initiator.profilePicture ?? null,
    employeeInternalId: initiator.employeeInternalId,
  })),
  createdAtFrom: filters.createdAtFrom
    ? parseToValidURLDate(filters.createdAtFrom)
    : null,
  createdAtTo: filters.createdAtTo
    ? parseToValidURLDate(filters.createdAtTo)
    : null,
});

const Subtasks = () => {
  const HugoThemeProvider = useHuGoTheme();
  const { t } = useLokaliseTranslation('service_management');
  const { user } = useAuth();
  const socket = useSocket();
  const [subtaskIdParam, setSubtaskIdParam] = useQueryState(
    SUBTASK_ID_PARAM,
    parseAsString,
  );
  const hasOpenedFromUrl = useRef(false);
  const { mutate: visitTaskMutate } = useVisitTask();
  const bubblesEnabled = useFeatureFlag(
    FeatureFlags.SERVICE_MANAGEMENT_BUBBLES_ENABLED,
  );

  // Intentionally NOT called when the flag is OFF: the `visit` endpoint exists
  // exclusively for the red-bubbles lifecycle (no analytics, audit or read-
  // state side effects beyond it). No body is sent so the backend keeps the
  // bubble until comments are read inside the parent task (mirrors mobile behavior).
  const visitSubtask = useCallback(
    (task: Task) => {
      if (!bubblesEnabled) return;
      visitTaskMutate({ taskId: task.id });
    },
    [bubblesEnabled, visitTaskMutate],
  );

  const { Search, params, form } = useHuPagination({
    limitOptions: [10, 20, 30],
    defaultOrderBy: ORDER_BY_DEFAULT_VALUE,
    defaultOrder: ORDER_DEFAULT_VALUE,
    defaultLimit: 10,
    defaultFilters,
  });

  const debouncedSearch = useDebounce(params.search, 500);

  const pageRef = useRef<HTMLDivElement>(null);

  const [filterDrawerOpen, setFilterDrawerOpen] = useState(false);
  const [appliedFilters, setAppliedFilters] = useQueryState(
    FILTERS_PARAM,
    subtasksFiltersParser,
  );
  const [filtersHydrated, setFiltersHydrated] = useState(false);

  const filtersForm = useForm<SubtasksFormValues>({
    defaultValues: defaultFiltersForm,
    mode: 'onChange',
    resolver: zodResolver(subtasksFormSchema(t as TFunction)),
  });

  // One-shot: hydrate the drawer form from the URL on mount when non-default
  // filters are present (e.g. after a hard refresh on a deep-linked URL).
  useEffect(() => {
    if (filtersHydrated) return;

    if (!isEqual(appliedFilters, defaultFiltersForm)) {
      filtersForm.reset(appliedFilters);
    }

    setFiltersHydrated(true);
  }, [filtersHydrated, appliedFilters, filtersForm]);

  const handleScrollToTop = () => {
    pageRef.current?.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const parsedParams = useMemo(() => {
    const { pagination, search, ...restParams } = params;
    return {
      ...restParams,
      limit: pagination.limit,
      page: pagination.page,
      q: debouncedSearch,
      ...parseSubtasksFilters(appliedFilters),
    };
  }, [debouncedSearch, params, appliedFilters]);

  useTaskCommentsUpdater({
    socket,
    params: parsedParams,
    event: EVENTS_SOCKETS.SERVICE_MANAGER_TASK_NEW_COMMENT,
  });

  const { data, isLoading, fetchNextPage, isFetching, isFetchingNextPage } =
    useInfiniteQuery(
      serviceManagementKeys.tasks.list(parsedParams),
      ({ pageParam = 1 }) =>
        getTasks({ ...parsedParams, page: pageParam, usePage: true }),
      {
        getNextPageParam: lastPage => {
          const { page, totalPages } = lastPage.data;
          return page < totalPages ? page + 1 : undefined;
        },
        select: response => ({
          ...response,
          pages: response.pages.map(page => page.data),
        }),
        onError: () => {
          // Prevent global error handler
        },
      },
    );

  const appliedFiltersCount = useMemo(() => {
    let count = 0;

    // Count array filters that have at least one item
    const arrayFilters = [
      'statesIn',
      'parentTaskCatalogItemsIn',
      'parentTaskInitiatorsIn',
    ] as const;

    arrayFilters.forEach(key => {
      const value = appliedFilters[key];
      if (Array.isArray(value) && value.length > 0) {
        count += 1;
      }
    });

    // Count dateOptions if any predefined option is true,
    // or if dateRange is true with at least one date selected
    if (appliedFilters.dateOptions) {
      const { dateRange, ...predefinedOptions } = appliedFilters.dateOptions;
      const hasPredefinedOption =
        Object.values(predefinedOptions).some(Boolean);
      const hasValidDateRange =
        dateRange &&
        (appliedFilters.createdAtFrom || appliedFilters.createdAtTo);

      if (hasPredefinedOption || hasValidDateRange) {
        count += 1;
      }
    }

    return count;
  }, [appliedFilters]);

  const { openDrawer, closeDrawer } = useDrawerLayer();

  const handleCloseDetailDrawer = useCallback(() => {
    queryClient.invalidateQueries(
      serviceManagementKeys.tasks.list(parsedParams),
    );
    setSubtaskIdParam(null);
    closeDrawer();
  }, [parsedParams, setSubtaskIdParam, closeDrawer]);

  const showDrawer = useCallback(
    ({ task }: { task: Task }) => {
      openDrawer({
        children: (
          <SubtaskDetailDrawer
            parentData={{ parentTask: task?.parentTask, params }}
            taskData={task}
            onClose={handleCloseDetailDrawer}
            showParentTask={true}
          />
        ),
        title: task?.name || '',
        hasBackButton: false,
        onClose: handleCloseDetailDrawer,
      });
    },
    [openDrawer, params, handleCloseDetailDrawer],
  );

  const handleApplyFilters = () => {
    const values = filtersForm.getValues();
    if (isEqual(values, defaultFiltersForm)) {
      setAppliedFilters(null);
    } else {
      setAppliedFilters(minimizeFilters(values));
    }
    setFilterDrawerOpen(false);
  };

  const handleCloseFilterDrawer = async () => {
    setFilterDrawerOpen(false);
    filtersForm.reset(appliedFilters);
  };

  const handleResetFilters = () => {
    filtersForm.reset(defaultFiltersForm);
  };

  const handleRowClick = (task: Task) => {
    hasOpenedFromUrl.current = true;
    setSubtaskIdParam(task.id);
    showDrawer({ task });
    visitSubtask(task);
  };

  const allSubTasks = data?.pages?.flatMap(page => page.items) || [];

  useEffect(() => {
    if (hasOpenedFromUrl.current || !allSubTasks.length || !subtaskIdParam)
      return;

    const matchingTask = allSubTasks.find(task => task.id === subtaskIdParam);
    if (matchingTask) {
      hasOpenedFromUrl.current = true;
      showDrawer({ task: matchingTask });
      visitSubtask(matchingTask);
    }
  }, [allSubTasks, subtaskIdParam, showDrawer, visitSubtask]);

  const totalCount = data?.pages?.[0]?.count ?? 0;

  const isEmpty =
    !allSubTasks.length && !isLoading && !isFetching && !isFetchingNextPage;
  const showEmptySearch = isEmpty && !!debouncedSearch;
  const showEmptyFilters =
    isEmpty && appliedFiltersCount > 0 && !showEmptySearch;
  const showEmpty = isEmpty && !showEmptySearch && !showEmptyFilters;

  return (
    <HugoThemeProvider>
      <FormProvider {...form}>
        <Stack
          ref={pageRef}
          sx={{
            overflow: 'auto',
            height: '100%',
            width: '100%',
            backgroundColor: theme =>
              theme.palette.new.background.layout.default,
            flex: 1,
          }}
        >
          <Stack
            sx={{
              position: 'sticky',
              top: 0,
              zIndex: 10,
              backgroundColor: theme =>
                theme.palette.new.background.layout.default,
              pt: 5,
              px: {
                xs: 8,
                md: 10,
                lg: 12,
              },
              pb: 3,
            }}
          >
            <Stack
              sx={{
                flexDirection: 'row',
                alignItems: 'center',
                justifyContent: 'space-between',
              }}
            >
              <Typography
                variant="globalL"
                fontWeight="fontWeightSemiBold"
              >
                {t('subtasks.title')}
              </Typography>
            </Stack>
          </Stack>
          <Stack
            sx={{
              flex: 1,
              px: {
                xs: 8,
                md: 10,
                lg: 12,
              },
              pb: 5,
              gap: 2,
            }}
          >
            <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 2 }}>
              <Search />
              <BadgeCountButton
                count={appliedFiltersCount}
                buttonProps={{
                  variant: 'secondary',
                  startIcon: <IconFilter />,
                  onClick: () => setFilterDrawerOpen(true),
                }}
              >
                {appliedFiltersCount > 0 ? t('general:filtered') : t('filter')}
              </BadgeCountButton>
              <FormProvider {...filtersForm}>
                <SubtasksFiltersDrawer
                  open={filterDrawerOpen}
                  onClose={handleCloseFilterDrawer}
                  onApply={handleApplyFilters}
                  onReset={handleResetFilters}
                />
              </FormProvider>
            </Stack>
            <HuTableContainer sx={{ overflowX: 'auto' }}>
              <HuTable
                sx={{
                  tableLayout: 'fixed',
                  minWidth: 1900,
                }}
              >
                <HuTableHead>
                  <HuTableRow headerRow>
                    <HuTableCell
                      colSpan={2}
                      headerCell
                    >
                      {t('number')}
                    </HuTableCell>
                    <HuTableCell
                      colSpan={6}
                      headerCell
                    >
                      {t('subtasks.task')}
                    </HuTableCell>
                    <HuTableCell
                      colSpan={5}
                      headerCell
                    >
                      {t('subtasks.request')}
                    </HuTableCell>
                    <HuTableCell
                      colSpan={4}
                      headerCell
                    >
                      {t('requester')}
                    </HuTableCell>
                    <HuTableCell
                      colSpan={3}
                      headerCell
                    >
                      {t('status')}
                    </HuTableCell>
                    <HuTableCell
                      colSpan={5}
                      headerCell
                    >
                      {t('agent')}
                    </HuTableCell>
                    <HuTableCell
                      colSpan={4}
                      headerCell
                    >
                      {t('subtasks.request_date')}
                    </HuTableCell>
                    <HuTableCell
                      colSpan={4}
                      headerCell
                    >
                      {t('updated')}
                    </HuTableCell>
                  </HuTableRow>
                </HuTableHead>
                <HuTableBody sx={{ opacity: isFetchingNextPage ? 0.5 : 1 }}>
                  {isLoading && <TasksTableRowSkeleton />}
                  {showEmpty && (
                    <EmptyRowFeedback
                      title={t('subtasks.empty.title')}
                      description={t('subtasks.empty.description')}
                    />
                  )}
                  {showEmptySearch && (
                    <EmptyRowFeedback
                      title={t('no_results_found')}
                      description={t('try_with_other_search')}
                    />
                  )}
                  {showEmptyFilters && (
                    <EmptyRowFeedback
                      title={t('no_results_found_search_with_filters')}
                      description={t('try_with_other_filters')}
                    />
                  )}
                  {!isLoading &&
                    !!allSubTasks.length &&
                    allSubTasks.map((task, index) => {
                      const showBubble = bubblesEnabled
                        ? (task.bubbleCount ?? 0) > 0
                        : (task.unreadCommentsCount ?? 0) > 0;
                      return (
                        <HuTableRow
                          key={task.id}
                          onClick={() => handleRowClick(task)}
                        >
                          <HuTableCell colSpan={2}>
                            <Stack
                              direction="row"
                              alignItems="center"
                              gap={0.5}
                            >
                              {showBubble && (
                                <HuBadge
                                  variant="dot"
                                  color="primary"
                                />
                              )}
                              <Typography variant="globalS">
                                {getTaskID(task)}
                              </Typography>
                            </Stack>
                          </HuTableCell>
                          <HuTableCell colSpan={6}>
                            <Typography
                              sx={{
                                display: '-webkit-box',
                                WebkitBoxOrient: 'vertical',
                                WebkitLineClamp: 1,
                                overflow: 'hidden',
                              }}
                              variant="globalS"
                            >
                              {task.name}
                            </Typography>
                          </HuTableCell>
                          <HuTableCell colSpan={5}>
                            <HuTitle
                              variant="S"
                              fontWeight="fontWeightRegular"
                              withEllipsis
                              overflow="tooltip"
                              title={task.parentTask?.catalogItem.name}
                              description={getTaskID(task.parentTask)}
                            />
                          </HuTableCell>
                          <HuTableCell colSpan={4}>
                            {task.parentTask?.initiator && (
                              <UserTooltip
                                user={task.parentTask?.initiator}
                                tooltipProps={{
                                  direction: 'top',
                                }}
                              >
                                <Typography
                                  variant="globalS"
                                  sx={{
                                    whiteSpace: 'nowrap',
                                    overflow: 'hidden',
                                    textOverflow: 'ellipsis',
                                    display: 'block',
                                    '&:hover': {
                                      textDecoration: 'underline',
                                    },
                                  }}
                                >
                                  {getUserDisplayName(
                                    task.parentTask?.initiator,
                                    user,
                                    t,
                                  )}
                                </Typography>
                              </UserTooltip>
                            )}
                            {!task.parentTask?.initiator && (
                              <Typography variant="globalS">-</Typography>
                            )}
                          </HuTableCell>
                          <HuTableCell colSpan={3}>
                            <HuPills
                              label={t(getStateName(task.state.name))}
                              type={getTaskPillType(task.state.name)}
                              hasIcon={false}
                            />
                          </HuTableCell>
                          <HuTableCell colSpan={5}>
                            <AgentColumnHugo
                              task={task}
                              index={index}
                              onOpenSingleReassign={() => null}
                              showButton={false}
                            />
                          </HuTableCell>
                          <HuTableCell colSpan={4}>
                            <Typography variant="globalS">
                              {formatLocalizedDate(task.createdAt) || '-'}
                            </Typography>
                          </HuTableCell>
                          <HuTableCell colSpan={4}>
                            <Typography variant="globalS">
                              {formatDistanceToNow(
                                new Date(task.updatedAt),
                                user,
                              ) || '-'}
                            </Typography>
                          </HuTableCell>
                        </HuTableRow>
                      );
                    })}
                </HuTableBody>
              </HuTable>
            </HuTableContainer>
            {allSubTasks.length > 0 && (
              <HuTableLoader
                loadedCount={allSubTasks.length}
                totalCount={totalCount}
                onLoadMore={fetchNextPage}
                onScrollToTop={handleScrollToTop}
              />
            )}
          </Stack>
        </Stack>
      </FormProvider>
    </HugoThemeProvider>
  );
};

export default Subtasks;
