import { type FC, useCallback, useEffect, useState } from 'react';

import { MAX_ZOOM } from 'src/pages/dashboard/Conversations/constants';
import {
  type HuDataMessage,
  type SendFilesList,
} from 'src/pages/dashboard/Conversations/types';
import { isImageAttachment } from 'src/pages/dashboard/Conversations/utils';

import MediaVisualizerBody from './Body';
import MediaVisualizerHeader from './Header';

type MediaVisualizerProps = {
  onClose: () => void;
  attachments: SendFilesList;
  huData?: HuDataMessage;
  username: string;
  text?: string;
  isSecure?: boolean;
  initialIndex?: number;
  conversationId?: string;
  onReply?: () => void;
};

const MediaVisualizer: FC<MediaVisualizerProps> = ({
  onClose,
  attachments,
  huData,
  username,
  text,
  isSecure = false,
  initialIndex = 0,
  conversationId,
  onReply,
}) => {
  const [selectedIndex, setSelectedIndex] = useState(initialIndex);
  const [zoom, setZoom] = useState(1);

  const selectedAttachment = attachments[selectedIndex];
  const isImage = !!selectedAttachment && isImageAttachment(selectedAttachment);

  useEffect(() => {
    setZoom(1);
  }, [selectedIndex]);

  useEffect(() => {
    if (!isImage) return;
    const handleWheel = (e: WheelEvent) => {
      if (!e.ctrlKey) return;
      e.preventDefault();
      const factor = Math.exp(-e.deltaY * 0.01);
      setZoom(prev => Math.min(Math.max(prev * factor, 1), MAX_ZOOM));
    };
    window.addEventListener('wheel', handleWheel, { passive: false });
    return () => window.removeEventListener('wheel', handleWheel);
  }, [isImage]);

  const navigate = useCallback(
    (delta: 1 | -1) => {
      setSelectedIndex(
        prev => (prev + delta + attachments.length) % attachments.length,
      );
    },
    [attachments.length],
  );

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'ArrowLeft') navigate(-1);
      if (e.key === 'ArrowRight') navigate(1);
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [navigate]);

  const handleZoomIn = () => setZoom(prev => Math.min(prev * 2, MAX_ZOOM));

  const handleZoomOut = () => setZoom(prev => Math.max(prev / 2, 1));

  const handleZoom = (newZoom: number) =>
    setZoom(Math.min(Math.max(newZoom, 1), MAX_ZOOM));

  if (!selectedAttachment) return null;

  return (
    <>
      <MediaVisualizerHeader
        onClose={onClose}
        onBack={onClose}
        onZoomIn={handleZoomIn}
        onZoomOut={handleZoomOut}
        zoom={zoom}
        huData={huData}
        username={username}
        selectedAttachment={selectedAttachment}
      />
      <MediaVisualizerBody
        onClose={onClose}
        onPrev={() => navigate(-1)}
        onNext={() => navigate(1)}
        attachments={attachments}
        selectedAttachment={selectedAttachment}
        selectedIndex={selectedIndex}
        onSelectIndex={setSelectedIndex}
        huData={huData}
        text={text}
        zoom={zoom}
        onZoom={handleZoom}
        isSecure={isSecure}
        conversationId={conversationId}
        onReply={onReply}
      />
    </>
  );
};

export default MediaVisualizer;
