import { useRef, useState } from 'react';

import {
  IconEdit,
  IconInfoCircle,
  IconPlus,
  IconTrash,
} from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import MenuList from '@material-hu/components/composed-components/MenuList';
import Button from '@material-hu/components/design-system/Buttons/Button';
import Search from '@material-hu/components/design-system/Inputs/Search';
import { useDialogLayer } from '@material-hu/components/layers/Dialogs';
import HuTable from '@material-hu/components/design-system/Table';
import TableBody from '@material-hu/components/design-system/Table/components/TableBody';
import TableCell from '@material-hu/components/design-system/Table/components/TableCell';
import TableContainer from '@material-hu/components/design-system/Table/components/TableContainer';
import TableHead from '@material-hu/components/design-system/Table/components/TableHead';
import TableLoader from '@material-hu/components/design-system/Table/components/TableLoader';
import TableRow from '@material-hu/components/design-system/Table/components/TableRow';

import { useDebounce } from 'src/hooks/useDebounce';
import { type ShiftRotation } from 'src/types/shifts';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { displayHoursAndMinutes } from 'src/utils/timeTracking';

import EmptyState from 'src/components/HuEmptyState';

import { useDeleteShiftRotationMutation } from '../../hooks/useDeleteShiftRotationMutation';
import { useGetShiftRotations } from '../../hooks/useGetShiftRotations';
import { capitalize } from 'lodash-es';
import {
  TemplatesTableLoadMoreSkeleton,
  TemplatesTableSkeletonRows,
} from './TemplatesTableSkeleton';
import { formatRotationDaysSummary } from '../../utils';

type Props = {
  onCreate: () => void;
  onEdit: (rotation: ShiftRotation) => void;
};

const TOTAL_COLUMNS = 4;

const TemplatesTab = ({ onCreate, onEdit }: Props) => {
  const [search, setSearch] = useState('');
  const { debouncedValue: debouncedSearch } = useDebounce(search, 300);
  const { t } = useLokaliseTranslation('shifts');
  const { openDialog, closeDialog } = useDialogLayer();
  const containerRef = useRef<HTMLDivElement | null>(null);

  const {
    registers,
    isLoading,
    isFetchingNextPage,
    hasNextPage,
    fetchNextPage,
    totalCount,
  } = useGetShiftRotations({ search: debouncedSearch });

  const { mutate: deleteRotation, isLoading: isDeleting } =
    useDeleteShiftRotationMutation();

  const isEmpty = !isLoading && !registers.length;
  const hasRegisters = registers.length > 0;

  const confirmDeleteRotation = (rotation: ShiftRotation) => {
    openDialog({
      title: t('templates.modal.delete_title'),
      textBody: t('templates.modal.delete_description'),
      onClose: () => closeDialog(),
      primaryButtonProps: {
        children: t('templates.modal.delete_confirmation'),
        onClick: () => {
          closeDialog();
          deleteRotation(rotation.id);
        },
      },
      secondaryButtonProps: {
        children: t('general:cancel'),
        onClick: () => closeDialog(),
      },
      dialogProps: { fullWidth: true, maxWidth: 'sm' },
    });
  };

  const rotationMenuOptions = (rotation: ShiftRotation) => [
    {
      Icon: IconEdit,
      title: t('templates.edit'),
      onClick: () => onEdit(rotation),
    },
    {
      Icon: IconTrash,
      title: t('templates.delete'),
      onClick: () => confirmDeleteRotation(rotation),
    },
  ];

  const handleLoadMore = () => {
    if (isFetchingNextPage || !hasNextPage) return;
    fetchNextPage();
  };

  const handleScrollToTop = () => {
    containerRef.current?.scrollIntoView({
      behavior: 'smooth',
      block: 'start',
    });
  };

  return (
    <Stack
      ref={containerRef}
      sx={{ gap: 2, flex: 1, minHeight: 0 }}
    >
      <Typography
        variant="globalL"
        sx={{
          fontWeight: 'fontWeightSemiBold',
        }}
      >
        {t('templates.your_templates')}
      </Typography>
      <Stack
        sx={{
          flexDirection: 'row',
          gap: 1,
          alignItems: 'center',
        }}
      >
        <Stack sx={{ flex: 1 }}>
          <Search
            value={search}
            placeholder={t('search_by_name')}
            onChange={setSearch}
          />
        </Stack>
        <Button
          variant="primary"
          color="primary"
          startIcon={<IconPlus size={16} />}
          onClick={onCreate}
        >
          {t('templates.create')}
        </Button>
      </Stack>

      <TableContainer>
        <HuTable stickyHeader>
          <TableHead>
            <TableRow headerRow>
              <TableCell headerCell>{t('general:name')}</TableCell>
              <TableCell headerCell>{t('general:description')}</TableCell>
              <TableCell headerCell>
                {capitalize(t('general:day_other'))}
              </TableCell>
              <TableCell
                headerCell
                aria-label={t('general:action_label')}
              />
            </TableRow>
          </TableHead>
          <TableBody>
            {isLoading && !hasRegisters && <TemplatesTableSkeletonRows />}
            {isEmpty && (
              <TableRow>
                <TableCell colSpan={TOTAL_COLUMNS}>
                  <EmptyState
                    titleProps={{
                      title: t('templates.empty_templates'),
                      description: t('templates.empty_templates_description'),
                    }}
                    avatarProps={{
                      Icon: IconInfoCircle,
                      color: 'highlight',
                    }}
                    buttonProps={{
                      text: t('templates.create'),
                      onClick: onCreate,
                    }}
                    sx={{ backgroundColor: 'transparent' }}
                  />
                </TableCell>
              </TableRow>
            )}
            {registers.map(rotation => {
              const { total: daysTotal, detail: daysDetail } =
                formatRotationDaysSummary(t, rotation);
              return (
                <TableRow key={rotation.id}>
                  <TableCell>
                    <Stack sx={{ gap: 0.25 }}>
                      <Typography variant="globalS">{rotation.name}</Typography>
                      <Typography
                        variant="globalXS"
                        sx={{
                          color: ({ palette }) =>
                            palette.new.text.neutral.lighter,
                        }}
                      >
                        {t('templates.total_hours_count', {
                          hours: displayHoursAndMinutes(rotation.totalHours),
                        })}
                      </Typography>
                    </Stack>
                  </TableCell>
                  <TableCell>{rotation.description}</TableCell>
                  <TableCell>
                    <Typography
                      component="span"
                      variant="globalS"
                      sx={{ fontWeight: 'fontWeightSemiBold' }}
                    >
                      {daysTotal}
                    </Typography>
                    {daysDetail}
                  </TableCell>
                  <TableCell
                    align="right"
                    sx={{ whiteSpace: 'nowrap' }}
                  >
                    <MenuList
                      size="small"
                      position="left"
                      disableMenu={isDeleting}
                      options={rotationMenuOptions(rotation)}
                    />
                  </TableCell>
                </TableRow>
              );
            })}
            {isFetchingNextPage && (
              <TemplatesTableLoadMoreSkeleton totalColumns={TOTAL_COLUMNS} />
            )}
          </TableBody>
        </HuTable>
      </TableContainer>

      {hasRegisters && (
        <TableLoader
          loadedCount={registers.length}
          totalCount={totalCount}
          onLoadMore={handleLoadMore}
          onScrollToTop={handleScrollToTop}
        />
      )}
    </Stack>
  );
};

export default TemplatesTab;
