import { useRef, useState } from 'react';

import { IconFileUpload, IconPlus, IconX } from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';
import CardMedia from '@material-hu/mui/CardMedia';
import CircularProgress from '@material-hu/mui/CircularProgress';
import IconButton from '@material-hu/mui/IconButton';
import ImageListItem from '@material-hu/mui/ImageListItem';
import ImageListItemBar from '@material-hu/mui/ImageListItemBar';
import Input from '@material-hu/mui/Input';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';
import { type FileAsset } from '@material-hu/types/attachments';

import Avatar from '@material-hu/components/design-system/Avatar';
import {
  useDialogLayer,
  useDialogLayerItem,
} from '@material-hu/components/layers/Dialogs';

import { FileTypes } from 'src/types/attachments';
import { getFileIcon } from 'src/utils/files';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  fileAccept,
  imageAccept,
  MAX_ATTACHMENTS,
} from '../../../../constants';

import { type AttachmentType } from './utils';

const { VIDEO, IMAGE, FILE } = FileTypes;

const ATTACHMENT_MODAL_ID = 'attachment-modal';

type UseAttachmentModalParams = {
  type: AttachmentType;
  images?: FileAsset[];
  files?: FileAsset[];
  loadingFiles?: File[];
  disabled?: boolean;
  onAccept?: () => void;
  onCancel?: () => void;
  onAddMore?: (files: File[]) => void;
  addMoreDisabled?: boolean;
  onDelete?: (file: FileAsset, index: number) => void;
};

export function useAttachmentModal({
  type,
  images = [],
  files = [],
  disabled = false,
  onDelete,
  onCancel,
  onAccept,
  onAddMore,
  loadingFiles = [],
  addMoreDisabled,
}: UseAttachmentModalParams) {
  const { t } = useLokaliseTranslation('service_management');
  const theme = useTheme();

  const [selectedIndex, setSelectedIndex] = useState(0);
  const fileInputRef = useRef<HTMLInputElement | null>(null);

  const { closeDialog: contextCloseDialog } = useDialogLayer();
  const close = () => contextCloseDialog(ATTACHMENT_MODAL_ID);

  const attachments = [...images, ...files];
  const focusedAttachment = attachments[selectedIndex];

  const handleAttach = (): void => {
    fileInputRef.current?.click();
  };

  const handleDelete = (
    event: React.MouseEvent<HTMLButtonElement>,
    item: FileAsset,
    index: number,
  ) => {
    event.stopPropagation();

    let indexToDelete = index;

    if (selectedIndex >= indexToDelete) {
      const newIndex = indexToDelete > 0 ? selectedIndex - 1 : 0;
      setSelectedIndex(newIndex);
    }
    if ([VIDEO, FILE].includes(item.type as FileTypes)) {
      indexToDelete = indexToDelete - images.length;
    }
    onDelete?.(item, indexToDelete);
  };

  const handleAccept = () => {
    onAccept?.();
    setSelectedIndex(0);
    close();
  };

  const handleCancel = () => {
    onCancel?.();
    setSelectedIndex(0);
    close();
  };

  const handleAddMore = (event: React.ChangeEvent<HTMLInputElement>) => {
    const inputFiles = event.target.files;
    const newFiles = [];

    if (inputFiles) {
      for (let i = 0; i < inputFiles.length; i++) {
        newFiles.push(inputFiles[i]);
      }
    }

    onAddMore?.(newFiles);

    // Reset the file input value to allow re-selection of the same file
    event.target.value = '';
  };

  const miniIconToShow = (item: FileAsset) =>
    ({
      [FILE]: getFileIcon(item),
      [IMAGE]: item.url,
    })[item.type as keyof typeof miniIconToShow] || '';

  const isLoading = loadingFiles.length > 0;

  const focusedFileAttachment =
    !!focusedAttachment && focusedAttachment.type === 'FILE';
  const focusedImgAttachment =
    !!focusedAttachment && focusedAttachment.type === 'IMAGE';

  const inputProps = {
    multiple: true,
    accept: type === 'images' ? imageAccept : fileAccept,
  };

  const body = (
    <Stack sx={{ display: 'flex', flexDirection: 'column' }}>
      {!focusedAttachment && (
        <Stack
          sx={{
            width: '100%',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            p: 3,
          }}
        >
          <Stack
            sx={{
              cursor: 'pointer',
              height: '111px',
              borderRadius: '8px',
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            <CircularProgress />
          </Stack>
        </Stack>
      )}
      {focusedFileAttachment && (
        <Stack
          sx={{
            width: 1,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            gap: 1,
            p: 3,
          }}
        >
          <Avatar
            Icon={IconFileUpload}
            color="primary"
            size="large"
          />
          <Typography
            noWrap
            variant="globalS"
            sx={{ maxWidth: '90%' }}
          >
            {focusedAttachment.name}
          </Typography>
        </Stack>
      )}
      {focusedImgAttachment && (
        <Stack
          sx={{
            position: 'relative',
            width: 1,
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            textAlign: 'center',
            p: 3,
            gap: 1,
          }}
        >
          <CardMedia
            src={focusedAttachment?.url}
            component={focusedAttachment?.type === VIDEO ? 'video' : 'img'}
            alt={focusedAttachment?.name}
            sx={{
              borderRadius: '8px',
              objectFit: 'cover',
              height: '78px',
              width: '78px',
            }}
            controls
          />
          <Typography
            variant="subtitle1"
            noWrap
            sx={{ maxWidth: '90%' }}
          >
            {focusedAttachment?.name}
          </Typography>
        </Stack>
      )}
      <Box
        sx={{
          display: 'flex',
          flexDirection: 'row',
          justifyContent: 'center',
          gap: '10px',
          alignItems: 'end',
        }}
      >
        {attachments.map((item, index) => (
          <ImageListItem
            onClick={() => setSelectedIndex(index)}
            key={item.url}
            sx={{
              cursor: 'pointer',
              width: '70px !important',
              height: '70px !important',
              mr: 1,
              mt: 1,
            }}
          >
            {item.type === IMAGE && (
              <img
                src={miniIconToShow(item)}
                alt={item.name}
                style={{
                  objectFit: 'cover',
                  width: '100%',
                  height: '100%',
                  padding: item.type !== IMAGE ? '6px' : '0',
                  borderRadius: '6px',
                  border:
                    index === selectedIndex
                      ? `2px solid ${theme.palette.new.border.neutral.brand}`
                      : '',
                }}
              />
            )}
            {item.type === FILE && (
              <Stack
                sx={{
                  backgroundColor: theme.palette.new.background.elements.grey,
                  height: '70px',
                  width: '70px',
                  borderRadius: 1,
                  alignItems: 'center',
                  justifyContent: 'center',
                  border: ({ palette }) => palette.new.border.neutral.default,
                }}
              >
                <Avatar
                  Icon={IconFileUpload}
                  color="primary"
                  size="large"
                />
              </Stack>
            )}
            <ImageListItemBar
              sx={{ backgroundColor: 'transparent' }}
              position="top"
              actionIcon={
                <IconButton
                  variant="tertiary-filled"
                  size="small"
                  disabled={disabled}
                  onClick={event => handleDelete(event, item, index)}
                >
                  <IconX />
                </IconButton>
              }
            />
          </ImageListItem>
        ))}
        {loadingFiles.map(item => (
          <Stack
            key={item.name}
            sx={{
              cursor: 'pointer',
              width: '70px',
              height: '70px',
              mr: 1,
              mt: 1,
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            <CircularProgress />
          </Stack>
        ))}
        {!addMoreDisabled && attachments.length < MAX_ATTACHMENTS && (
          <>
            <IconButton
              disabled={isLoading}
              onClick={handleAttach}
              variant="tertiary-filled"
              sx={{
                padding: '12px',
                margin: '0',
                height: '70px',
                width: '70px',
              }}
              size={'large'}
            >
              <IconPlus size={24} />
            </IconButton>
            <Input
              type="file"
              sx={{
                display: 'none',
              }}
              inputRef={fileInputRef}
              onChange={handleAddMore}
              inputProps={inputProps}
            />
          </>
        )}
      </Box>
    </Stack>
  );

  const { openDialog } = useDialogLayerItem(ATTACHMENT_MODAL_ID, {
    onClose: handleCancel,
    body,
    primaryButtonProps: {
      children: t('add'),
      disabled: isLoading,
      onClick: handleAccept,
    },
    dialogProps: {
      maxWidth: 'lg',
      PaperProps: { style: { width: '600px' } },
    },
  });

  return {
    openAttachmentModal: () => openDialog(),
    closeAttachmentModal: close,
  };
}
