import { type FC, useMemo, useState } from 'react';

import { type HuTableSortingHeaderProps } from '@material-hu/hooks/TableSorting/useHuServerTableSorting';
import { type PaginationControllerProps } from '@material-hu/hooks/useHuPagination';
import { IconInfoCircle, IconUser } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import { alpha } from '@material-hu/mui/styles';
import useTheme from '@material-hu/mui/styles/useTheme';
import Typography from '@material-hu/mui/Typography';

import TypographyOverflowTooltip from '@material-hu/components/composed-components/TypographyOverflowTooltip';
import HuBadge from '@material-hu/components/design-system/Badge';
import Button from '@material-hu/components/design-system/Buttons/Button';
import HuCheckbox from '@material-hu/components/design-system/Checkbox/Checkbox';
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 HuTableRow from '@material-hu/components/design-system/Table/components/TableRow';
import HuTableToolbar from '@material-hu/components/design-system/Table/components/TableToolbar';
import HuTooltip from '@material-hu/components/design-system/Tooltip';

import { useAuth } from 'src/contexts/JWTContext';
import useFeatureFlag from 'src/hooks/useFeatureFlag';
import { serviceManagementRoutes } from 'src/pages/dashboard/serviceManagement/routes';
import {
  type HydratedTask,
  type Task,
} from 'src/pages/dashboard/serviceManagement/types';
import {
  getSla,
  getSlaPillProps,
  getSlaTime,
  getSlaTooltipMessage,
  getStatusPillProps,
  getTaskID,
  hasExpired,
} from 'src/pages/dashboard/serviceManagement/utils';
import { FeatureFlags } from 'src/types/featureFlags';
import { type Pagination } from 'src/types/services';
import { formatDateDifference, formatLocalizedDate } from 'src/utils/date';
import { useLokaliseTranslation } from 'src/utils/i18n';

import UserTooltip from '../../servicePortal/requestedDetails/components/Information/UserTooltip';
import { getUserDisplayName } from '../../utils';

import AgentColumnHugo from './AgentColumn';
import TaskTableSkeleton from './TaskTableSkeleton';

type Props = {
  tasks: Pagination<Task[] | HydratedTask[]> | undefined;
  selectedTasks: Task[];
  hasFilters: boolean;
  hasSearch: boolean;
  isLoadingTasks: boolean;
  isError: boolean;
  isPreviousData: boolean;
  handleRowClick: (task: Task) => void;
  handleCheckboxClick: (task: Task) => void;
  handleSelectAll: () => void;
  handleOpenSingleReassign: (task: Task, index: number) => void;
  allChecked: boolean;
  hasSlasConfigured: boolean;
  assignButtonDisabled: boolean;
  handleOpenMultipleAssignmentMenu: (e: React.MouseEvent<HTMLElement>) => void;
  MultipleAssignmentPopoverComponent: React.ReactNode;
  Pagination: (props: PaginationControllerProps) => JSX.Element;
  SortingHeader: (props: HuTableSortingHeaderProps) => JSX.Element;
  onRefetch: () => void;
  showAgentGroup: boolean;
};

const TasksTable: FC<Props> = ({
  tasks,
  selectedTasks,
  hasFilters,
  hasSearch,
  isLoadingTasks,
  isPreviousData,
  isError,
  handleRowClick,
  handleCheckboxClick,
  handleSelectAll,
  handleOpenSingleReassign,
  allChecked,
  hasSlasConfigured,
  assignButtonDisabled,
  handleOpenMultipleAssignmentMenu,
  MultipleAssignmentPopoverComponent,
  Pagination,
  SortingHeader,
  onRefetch,
  showAgentGroup,
}) => {
  const { t } = useLokaliseTranslation('service_management');
  const theme = useTheme();
  const bubblesEnabled = useFeatureFlag(
    FeatureFlags.SERVICE_MANAGEMENT_BUBBLES_ENABLED,
  );

  const { user: loggedUser } = useAuth();

  const [agentHoveredRow, setAgentHoveredRow] = useState<number | null>(null);
  const [hoveredRow, setHoveredRow] = useState<number | null>(null);

  // Improves performance by extracting theme colors once
  const colors = useMemo(() => {
    const hoveredColor = theme.palette.new.background.secondary.default;
    const selectedColor = theme.palette.new.background.layout.brand;
    const defaultColor = theme.palette.new.background.layout.tertiary;
    return {
      hoveredColor,
      selectedColor,
      defaultColor,
    };
  }, [theme]);

  const getColumnColor = useMemo(() => {
    return (isSelected: boolean, isHovered: boolean) => {
      if (isHovered && isSelected) return colors.selectedColor;
      if (isHovered) return colors.hoveredColor;
      if (isSelected) return colors.selectedColor;
      return colors.defaultColor;
    };
  }, [colors]);

  const isEmpty = !tasks?.count && !isLoadingTasks && !isError;
  const showNoResults = isEmpty && !hasSearch && !hasFilters;
  const showEmptySearch = isEmpty && hasSearch;
  const showEmptyFilters = isEmpty && hasFilters && !hasSearch;
  const showError = isError && !isLoadingTasks && !tasks?.count;
  const showPagination =
    !isLoadingTasks && !isError && (tasks?.totalPages || 0) >= 1;

  if (isLoadingTasks) {
    return <TaskTableSkeleton showGroupColumn={showAgentGroup} />;
  }

  return (
    <Stack sx={{ gap: 3 }}>
      <HuTableContainer sx={{ overflowX: 'auto' }}>
        <HuTableToolbar sx={{ position: 'sticky', top: 0, left: 0, p: 2.5 }}>
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              justifyContent: 'flex-start',
              gap: 1,
              minHeight: '36px',
            }}
          >
            <Typography
              variant="globalS"
              fontWeight="fontWeightSemiBold"
              sx={{
                color: ({ palette }) => palette.new.text.neutral.lighter,
              }}
            >
              {t('selected_amount', { count: selectedTasks.length })}
            </Typography>
            {selectedTasks.length > 0 && (
              <HuTooltip
                disableTooltip={!assignButtonDisabled}
                description={t('disabled_assignment')}
                direction="top"
              >
                <Stack
                  sx={{
                    cursor: assignButtonDisabled ? 'not-allowed' : 'pointer',
                  }}
                >
                  <Button
                    size="small"
                    startIcon={<IconUser />}
                    variant="tertiary"
                    disabled={assignButtonDisabled}
                    onClick={handleOpenMultipleAssignmentMenu}
                  >
                    {t('assign_to')}
                  </Button>
                  {MultipleAssignmentPopoverComponent}
                </Stack>
              </HuTooltip>
            )}
          </Stack>
        </HuTableToolbar>
        <HuTable>
          <HuTableHead>
            <HuTableRow headerRow>
              <HuTableCell
                headerCell
                selectionCell
                sx={{
                  position: 'sticky',
                  left: 0,
                  zIndex: 1000,
                  backgroundColor: ({ palette }) =>
                    alpha(palette.new.action.background.neutral.hover, 1),
                }}
              >
                <HuCheckbox
                  checked={!!allChecked}
                  indeterminate={selectedTasks?.length > 0 && !allChecked}
                  onClick={e => {
                    e.stopPropagation(); // Prevent triggering row click
                    handleSelectAll();
                  }}
                />
              </HuTableCell>
              <HuTableCell headerCell>{t('number')}</HuTableCell>
              <HuTableCell headerCell>{t('service')}</HuTableCell>
              <HuTableCell headerCell>{t('agent')}</HuTableCell>
              {showAgentGroup && (
                <HuTableCell headerCell>{t('group')}</HuTableCell>
              )}
              <HuTableCell headerCell>{t('state')}</HuTableCell>
              <HuTableCell headerCell>{t('requester')}</HuTableCell>
              {hasSlasConfigured && (
                <HuTableCell
                  headerCell
                  sx={{ minWidth: '170px' }}
                >
                  {t('time_left')}
                </HuTableCell>
              )}
              <SortingHeader
                id="CREATED_AT"
                sx={{ minWidth: '190px' }}
              >
                {t('creation_date')}
              </SortingHeader>
              <SortingHeader id="UPDATED_AT">{t('updated')}</SortingHeader>
            </HuTableRow>
          </HuTableHead>
          <HuTableBody sx={{ opacity: isPreviousData ? 0.5 : 1 }}>
            {!!tasks?.count &&
              tasks?.items.map((task, index) => {
                const hasSlas = task.taskSlas?.length > 0;
                const sla = getSla(task.taskSlas, task.state);
                const showSla = sla != null && hasSlasConfigured && hasSlas;

                const isSelected = selectedTasks.includes(task);
                const showBubble = bubblesEnabled
                  ? task.bubbleCount > 0
                  : (task.unreadCommentsCount ?? 0) > 0;

                return (
                  <HuTableRow
                    key={task.id}
                    selected={isSelected}
                    onClick={e => {
                      const target = e.target as HTMLElement;
                      if (target.id === `id-selection-cell-${index}`) {
                        if (task.state.terminal) {
                          return;
                        }

                        handleCheckboxClick(task);
                      } else {
                        handleRowClick(task);
                      }
                    }}
                    onMouseEnter={() => setHoveredRow(index)}
                    onMouseLeave={() => setHoveredRow(null)}
                    sx={{
                      minHeight: '68px',
                    }}
                  >
                    <HuTableCell
                      id={`id-selection-cell-${index}`}
                      selectionCell
                      sx={{
                        position: 'sticky',
                        left: 0,
                        zIndex: 1000,
                        backgroundColor: getColumnColor(
                          isSelected,
                          hoveredRow === index,
                        ),
                      }}
                    >
                      <HuTooltip
                        description={t('cant_reassign_terminal_state')}
                        disableTooltip={!task.state.terminal}
                      >
                        <span
                          onClick={e => {
                            e.stopPropagation(); // Prevent triggering row click when checkbox is disabled
                          }}
                        >
                          <HuCheckbox
                            sx={{ zIndex: 10000 }}
                            disabled={task.state.terminal}
                            checked={isSelected}
                            onClick={e => {
                              e.stopPropagation(); // Prevent triggering row click
                              handleCheckboxClick(task);
                            }}
                          />
                        </span>
                      </HuTooltip>
                    </HuTableCell>
                    <HuTableCell>
                      <Stack
                        sx={{
                          flexDirection: 'row',
                          alignItems: 'center',
                          gap: 0.5,
                        }}
                      >
                        {showBubble && (
                          <HuBadge
                            variant="dot"
                            color="primary"
                          />
                        )}
                        <Typography
                          component="a"
                          href={serviceManagementRoutes.agentSide.detail(
                            task.id,
                          )}
                          sx={{
                            color: ({ palette }) =>
                              palette.new.text.neutral.default,
                            textDecoration: 'none',
                            '&:hover': {
                              textDecoration: 'underline',
                            },
                          }}
                          onClick={e => {
                            const isModifierClick =
                              e.ctrlKey ||
                              e.metaKey ||
                              e.shiftKey ||
                              e.button === 1;
                            if (isModifierClick) {
                              // Let the browser open the link in a new tab and
                              // prevent the row click from also firing.
                              e.stopPropagation();
                            } else {
                              // Defer to the existing row click so in-app
                              // navigation state is preserved.
                              e.preventDefault();
                            }
                          }}
                          onAuxClick={e => e.stopPropagation()}
                        >
                          {getTaskID(task)}
                        </Typography>
                      </Stack>
                    </HuTableCell>
                    <HuTableCell
                      sx={{
                        minWidth: '250px',
                        maxWidth: '320px',
                      }}
                    >
                      <TypographyOverflowTooltip
                        tooltipProps={{
                          description: task.catalogItem.name,
                        }}
                      >
                        {task.catalogItem.name}
                      </TypographyOverflowTooltip>
                    </HuTableCell>
                    <HuTableCell
                      onMouseEnter={() => setAgentHoveredRow(index)}
                      onMouseLeave={() => setAgentHoveredRow(null)}
                      sx={{
                        maxWidth: '320px',
                        minWidth: '250px',
                      }}
                    >
                      <AgentColumnHugo
                        task={task}
                        index={index}
                        onOpenSingleReassign={handleOpenSingleReassign}
                        showButton={
                          selectedTasks.length === 0 &&
                          agentHoveredRow === index &&
                          !task.state.terminal
                        }
                      />
                    </HuTableCell>
                    {showAgentGroup && (
                      <HuTableCell
                        sx={{
                          minWidth: '200px',
                          maxWidth: '320px',
                        }}
                      >
                        <TypographyOverflowTooltip
                          tooltipProps={{
                            description: (task as HydratedTask).agentGroup
                              ?.name,
                          }}
                        >
                          {(task as HydratedTask).agentGroup?.name}
                        </TypographyOverflowTooltip>
                      </HuTableCell>
                    )}
                    <HuTableCell>
                      <HuPills {...getStatusPillProps(task.state, t)} />
                    </HuTableCell>
                    <HuTableCell
                      sx={{
                        minWidth: '200px',
                        maxWidth: '320px',
                      }}
                    >
                      <UserTooltip
                        user={task.initiator!}
                        tooltipProps={{
                          direction: 'top',
                        }}
                      >
                        <TypographyOverflowTooltip
                          tooltipProps={{
                            description: getUserDisplayName(
                              task.initiator!,
                              loggedUser!,
                              t,
                            ),
                          }}
                          typographyProps={{
                            variant: 'globalS',
                            sx: {
                              '&:hover': {
                                textDecoration: 'underline',
                              },
                            },
                          }}
                        >
                          {getUserDisplayName(task.initiator!, loggedUser!, t)}
                        </TypographyOverflowTooltip>
                      </UserTooltip>
                    </HuTableCell>
                    {!showSla && hasSlasConfigured && <HuTableCell />}
                    {showSla && (
                      <HuTableCell>
                        <Stack
                          sx={{
                            flexDirection: 'row',
                            alignItems: 'center',
                            gap: 0.5,
                          }}
                        >
                          <HuPills
                            label={
                              hasExpired(sla, task.state)
                                ? t('TIME_EXPIRED')
                                : getSlaTime(sla, task.state)
                            }
                            {...getSlaPillProps(sla, task.state)}
                          />
                          <HuTooltip
                            description={t(
                              getSlaTooltipMessage(sla, task.state),
                            )}
                          >
                            <IconInfoCircle
                              color={theme.palette.new.text.neutral.default}
                              size={16}
                            />
                          </HuTooltip>
                        </Stack>
                      </HuTableCell>
                    )}
                    <HuTableCell>
                      <Typography variant="globalS">
                        {formatLocalizedDate(task.createdAt) || '-'}
                      </Typography>
                    </HuTableCell>
                    <HuTableCell sx={{ minWidth: '240px' }}>
                      <Typography variant="globalS">
                        {formatDateDifference(task.updatedAt, t)}
                      </Typography>
                    </HuTableCell>
                  </HuTableRow>
                );
              })}
            {showEmptyFilters && (
              <HuTableRow>
                <HuTableCell colSpan={30}>
                  <StateCard
                    slotProps={{
                      card: {
                        sx: {
                          border: 'none',
                        },
                      },
                    }}
                    title={t('no_results_for_selection')}
                    description={t('try_with_other_filters')}
                  />
                </HuTableCell>
              </HuTableRow>
            )}
            {showEmptySearch && (
              <HuTableRow>
                <HuTableCell colSpan={30}>
                  <StateCard
                    slotProps={{
                      card: {
                        sx: {
                          border: 'none',
                        },
                      },
                    }}
                    title={t('no_results_found_search')}
                    description={t('try_with_other_search')}
                  />
                </HuTableCell>
              </HuTableRow>
            )}
            {showNoResults && (
              <HuTableRow>
                <HuTableCell colSpan={30}>
                  <StateCard
                    slotProps={{
                      card: {
                        sx: {
                          border: 'none',
                        },
                      },
                    }}
                    title={t('no_results')}
                    description={t('no_results_description_agent')}
                  />
                </HuTableCell>
              </HuTableRow>
            )}
            {showError && (
              <HuTableRow>
                <HuTableCell colSpan={12}>
                  <StateCard
                    variant="error"
                    slotProps={{
                      card: {
                        sx: {
                          border: 'none',
                        },
                      },
                    }}
                    title={t('error_cant_show_results')}
                    description={t('try_again_later')}
                    primaryAction={{
                      label: t('try_again'),
                      onClick: onRefetch,
                    }}
                  />
                </HuTableCell>
              </HuTableRow>
            )}
          </HuTableBody>
        </HuTable>
      </HuTableContainer>
      {showPagination && (
        <Pagination
          inputProps={{
            totalPages: tasks?.totalPages || 0,
            type: 'changer',
          }}
        />
      )}
    </Stack>
  );
};

export default TasksTable;
