import { type FC, useEffect, useId, useMemo, useRef, useState } from 'react';
import { useMutation, useQueryClient } from 'react-query';

import { format } from 'date-fns';
import { IconChevronDown } from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';
import IconButton from '@material-hu/mui/IconButton';
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 HuMenuList from '@material-hu/components/composed-components/MenuList';
import HuAvatar from '@material-hu/components/design-system/Avatar';
import {
  useDialogLayer,
  useDialogLayerItem,
} from '@material-hu/components/layers/Dialogs';

import robot from 'src/assets/svg/robot.svg';
import { useAuth } from 'src/contexts/JWTContext';
import TypographyLinkSensitive from 'src/pages/dashboard/serviceManagement/general/TypographyLinkSensitive';
import useSnackbar from 'src/pages/dashboard/serviceManagement/hooks/useSnackbar';
import { serviceManagementKeys } from 'src/pages/dashboard/serviceManagement/queries';
import { deleteComment } from 'src/pages/dashboard/serviceManagement/services';
import { type Event } from 'src/pages/dashboard/serviceManagement/types';
import { FileTypes } from 'src/types/attachments';
import {
  getFileNameExtension,
  isPdf,
  safeConvertFileAssetToAttachment,
} from 'src/utils/files';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getFullName } from 'src/utils/userUtils';

import FullMediaCarousel from 'src/components/attachment/FullMediaCarousel';
import PdfViewer from 'src/components/attachment/PdfViewer';

import { IMG_GAP_IN_PX, MAX_CONTAINER_WIDTH } from '../../../../constants';
import { calculateFileCardWidth, getImgDimensions } from '../../../../utils';

import AttachedFileCard from './AttachedFileCard';

export type CommentProps = {
  comment: Event;
  isTaskTerminal?: boolean;
};

const Comment: FC<CommentProps> = ({ comment, isTaskTerminal = false }) => {
  const theme = useTheme();
  const { t } = useLokaliseTranslation('service_management');
  const { user } = useAuth();
  const queryClient = useQueryClient();
  const { showSnackbar } = useSnackbar();

  const [expandedImg, setExpandedImg] = useState<FileAsset | null>(null);
  const [expandedPdfFile, setExpandedPdfFile] = useState<FileAsset | null>(
    null,
  );
  const containerRef = useRef<HTMLDivElement>(null);
  const [containerWidth, setContainerWidth] = useState<number>(0);

  // Keep track of the container width dynamically
  useEffect(() => {
    if (containerRef.current) {
      setContainerWidth(containerRef.current.offsetWidth);
    }
    const handleResize = () => {
      if (containerRef.current) {
        setContainerWidth(containerRef.current.offsetWidth);
      }
    };
    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  const maxContainerWidth = useMemo(() => {
    return Math.min(containerWidth - 100, MAX_CONTAINER_WIDTH);
  }, [containerWidth]);

  const confirmDialogId = useId();
  const { closeDialog } = useDialogLayer();
  const closeConfirmModal = () => closeDialog(confirmDialogId);

  const { mutate: deleteMutation, isLoading } = useMutation(
    () => deleteComment(comment?.task.id, comment?.id),
    {
      onSuccess: () => {
        queryClient.invalidateQueries(
          serviceManagementKeys.comments.list(comment?.task.id),
        );
        showSnackbar({
          title: t('comment_deleted'),
          variant: 'success',
        });
        closeConfirmModal();
      },
    },
  );

  const { openDialog: showConfirmModal } = useDialogLayerItem(confirmDialogId, {
    title: t('delete_comment'),
    textBody: t('delete_comment_confirmation'),
    primaryButtonProps: {
      children: t('general:accept'),
      onClick: () => deleteMutation(),
      loading: isLoading,
    },
    secondaryButtonProps: {
      children: t('general:cancel'),
      onClick: () => closeConfirmModal(),
    },
    dialogProps: { fullWidth: true, maxWidth: 'xs' },
  });

  const handleOpenFile = (file: FileAsset) => {
    if (isPdf(getFileNameExtension(file.name))) {
      setExpandedPdfFile(file);
    } else {
      window.open(file.url, '_blank', 'noopener,noreferrer');
    }
  };

  const renderAttachments = (
    attachments: FileAsset[],
    isLoggedUser: boolean,
  ) => {
    if (!attachments?.length) return null;

    const imgs = attachments.filter(a => a.type === FileTypes.IMAGE);
    const files = attachments.filter(a => a.type === FileTypes.FILE);

    const imageDimensions = getImgDimensions(imgs.length);
    const fileCardWidth = calculateFileCardWidth(
      imageDimensions,
      imgs.length,
      maxContainerWidth,
      IMG_GAP_IN_PX,
    );

    return (
      <Stack sx={{ width: 1, gap: 1 }}>
        {imgs.length > 0 && (
          <Stack
            sx={{
              gap: 1,
              width: 1,
              flexDirection: 'row',
              justifyContent: isLoggedUser ? 'flex-end' : 'flex-start',
              flexWrap: 'wrap',
            }}
          >
            {imgs.map((img, index) => (
              <Stack
                key={img.id}
                onClick={() => setExpandedImg(img)}
                sx={{
                  width: imageDimensions,
                  height: imageDimensions,
                  position: 'relative',
                  borderRadius: '8px',
                  cursor: 'pointer',
                }}
              >
                <img
                  src={img.url}
                  alt={`attached-img-${index}`}
                  style={{
                    width: '100%',
                    height: '100%',
                    objectFit: 'cover',
                    borderRadius: '8px',
                  }}
                />
              </Stack>
            ))}
          </Stack>
        )}
        {files.length > 0 && (
          <Stack
            sx={{
              width: 1,
              gap: 1,
            }}
          >
            {files.map((file, index) => (
              <AttachedFileCard
                key={file.id}
                file={file}
                index={index}
                onClick={() => handleOpenFile(file)}
                width={fileCardWidth}
                backgroundColor={theme.palette.new.background.layout.tertiary}
              />
            ))}
          </Stack>
        )}
      </Stack>
    );
  };

  const isLoggedUser = comment?.user?.id === user?.id;
  const commentDate = new Date(comment?.timestamp);

  return (
    <Stack
      ref={containerRef}
      sx={{
        px: 3,
        gap: 0.5,
        width: '100%',
        alignItems: isLoggedUser ? 'flex-end' : 'flex-start',
      }}
    >
      <Stack sx={{ flexDirection: 'row', gap: 1 }}>
        {!isLoggedUser && !comment?.user && (
          <img
            src={robot}
            alt="robot"
            style={{ width: '40px', height: '40px', borderRadius: '50%' }}
          />
        )}
        {!isLoggedUser && !!comment?.user && (
          <HuAvatar
            src={comment?.user?.profilePicture || ''}
            size="small"
          />
        )}
        <Stack sx={{ gap: 0.5 }}>
          <Stack
            sx={{
              position: 'relative',
              borderRadius: isLoggedUser
                ? '16px 0 16px 16px'
                : '0 16px 16px 16px',
              p: 1.5,
              gap: 1,
              backgroundColor: isLoggedUser
                ? theme => theme.palette.new.background.layout.brand
                : theme => theme.palette.new.background.layout.tertiary,
              border: '1px solid',
              borderColor: isLoggedUser
                ? theme => theme.palette.new.border.neutral.brand
                : theme => theme.palette.new.border.neutral.default,
              maxWidth: `${maxContainerWidth}px`,
              '&:hover .more-icon': {
                visibility: 'visible',
              },
            }}
          >
            {isLoggedUser && !isTaskTerminal && (
              <Box
                sx={{
                  position: 'absolute',
                  top: 8,
                  right: 8,
                  zIndex: 1,
                }}
              >
                <HuMenuList
                  customButton={
                    <IconButton
                      sx={{
                        p: 0.5,
                        visibility: 'hidden',
                        backgroundColor: theme =>
                          theme.palette.new.background.layout.default,
                        '&:hover': {
                          backgroundColor: theme =>
                            theme.palette.new.background.layout.brand,
                        },
                      }}
                      className="more-icon"
                    >
                      <IconChevronDown size="16px" />
                    </IconButton>
                  }
                  position="right"
                  options={[
                    {
                      title: t('delete_comment'),
                      onClick: () => showConfirmModal(),
                    },
                  ]}
                />
              </Box>
            )}
            {!isLoggedUser && (
              <Typography
                variant="globalXXS"
                fontWeight="semiBold"
              >
                {comment?.user
                  ? getFullName(comment?.user)
                  : t('automatic_message')}
              </Typography>
            )}
            <Stack
              sx={{
                flexDirection: 'row',
                textWrap: 'wrap',
                wordBreak: 'break-word',
                whiteSpace: 'break-spaces',
              }}
            >
              <TypographyLinkSensitive variant="globalXS">
                {comment?.message}
              </TypographyLinkSensitive>
            </Stack>
            {renderAttachments(comment?.attachments, isLoggedUser)}
            <Stack
              sx={{
                width: '100%',
                flexDirection: 'row',
                justifyContent: 'flex-end',
                alignItems: 'center',
              }}
            >
              <Typography variant="globalXXS">
                {format(commentDate, 'HH:mm')}
              </Typography>
            </Stack>
          </Stack>
        </Stack>
      </Stack>
      {expandedImg && (
        <Box sx={{ pointerEvents: 'auto' }}>
          <FullMediaCarousel
            open={!!expandedImg}
            mediaList={[safeConvertFileAssetToAttachment(expandedImg)]}
            showName
            showDownload
            onClose={(): void => setExpandedImg(null)}
          />
        </Box>
      )}
      {expandedPdfFile && (
        <PdfViewer
          file={safeConvertFileAssetToAttachment(expandedPdfFile)}
          onClose={() => setExpandedPdfFile(null)}
        />
      )}
    </Stack>
  );
};

export default Comment;
