/**
 * ImagePreview Component
 * Full-screen image preview with left/right swipe navigation
 * 
 * Requirements: 4.6, 4.14
 */

import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Icon } from '@iconify/react';
import type { TransactionImage } from '../../../types';
import './ImagePreview.css';

export interface ImagePreviewProps {
  images: TransactionImage[];
  initialIndex: number;
  open: boolean;
  onClose: () => void;
}

export const ImagePreview: React.FC<ImagePreviewProps> = ({
  images,
  initialIndex,
  open,
  onClose,
}) => {
  const [currentIndex, setCurrentIndex] = useState(initialIndex);
  const [touchStart, setTouchStart] = useState<number | null>(null);
  const [touchEnd, setTouchEnd] = useState<number | null>(null);
  const imageContainerRef = useRef<HTMLDivElement>(null);

  // Minimum swipe distance (in px) to trigger navigation
  const minSwipeDistance = 50;

  // Reset index when initialIndex changes
  useEffect(() => {
    setCurrentIndex(initialIndex);
  }, [initialIndex]);

  // Prevent body scroll when modal is open
  useEffect(() => {
    if (open) {
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = '';
    }

    return () => {
      document.body.style.overflow = '';
    };
  }, [open]);

  // Keyboard navigation
  useEffect(() => {
    if (!open) return;

    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        onClose();
      } else if (e.key === 'ArrowLeft') {
        handlePrevious();
      } else if (e.key === 'ArrowRight') {
        handleNext();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [open, currentIndex, images.length]);

  const handlePrevious = useCallback(() => {
    setCurrentIndex((prev) => (prev > 0 ? prev - 1 : images.length - 1));
  }, [images.length]);

  const handleNext = useCallback(() => {
    setCurrentIndex((prev) => (prev < images.length - 1 ? prev + 1 : 0));
  }, [images.length]);

  // Touch event handlers for swipe navigation
  const onTouchStart = (e: React.TouchEvent) => {
    setTouchEnd(null);
    setTouchStart(e.targetTouches[0].clientX);
  };

  const onTouchMove = (e: React.TouchEvent) => {
    setTouchEnd(e.targetTouches[0].clientX);
  };

  const onTouchEnd = () => {
    if (!touchStart || !touchEnd) return;

    const distance = touchStart - touchEnd;
    const isLeftSwipe = distance > minSwipeDistance;
    const isRightSwipe = distance < -minSwipeDistance;

    if (isLeftSwipe) {
      handleNext();
    } else if (isRightSwipe) {
      handlePrevious();
    }

    setTouchStart(null);
    setTouchEnd(null);
  };

  // Mouse drag handlers for desktop swipe
  const [isDragging, setIsDragging] = useState(false);
  const [dragStart, setDragStart] = useState<number | null>(null);
  const [dragEnd, setDragEnd] = useState<number | null>(null);

  const onMouseDown = (e: React.MouseEvent) => {
    setIsDragging(true);
    setDragEnd(null);
    setDragStart(e.clientX);
  };

  const onMouseMove = (e: React.MouseEvent) => {
    if (!isDragging) return;
    setDragEnd(e.clientX);
  };

  const onMouseUp = () => {
    if (!isDragging || !dragStart || !dragEnd) {
      setIsDragging(false);
      return;
    }

    const distance = dragStart - dragEnd;
    const isLeftSwipe = distance > minSwipeDistance;
    const isRightSwipe = distance < -minSwipeDistance;

    if (isLeftSwipe) {
      handleNext();
    } else if (isRightSwipe) {
      handlePrevious();
    }

    setIsDragging(false);
    setDragStart(null);
    setDragEnd(null);
  };

  const onMouseLeave = () => {
    if (isDragging) {
      setIsDragging(false);
      setDragStart(null);
      setDragEnd(null);
    }
  };

  if (!open || images.length === 0) {
    return null;
  }

  const currentImage = images[currentIndex];
  const imageUrl = `${import.meta.env.VITE_API_BASE_URL || 'http://localhost:2612/api/v1'}/images/${currentImage.id}`;

  return (
    <div
      className="image-preview"
      onClick={onClose}
      role="dialog"
      aria-modal="true"
      aria-label="图片预览"
    >
      {/* Close button */}
      <button
        className="image-preview__close"
        onClick={(e) => {
          e.stopPropagation();
          onClose();
        }}
        type="button"
        aria-label="关闭预览"
      >
        <Icon icon="mdi:close" width="32" />
      </button>

      {/* Image counter */}
      <div className="image-preview__counter">
        {currentIndex + 1} / {images.length}
      </div>

      {/* Previous button */}
      {images.length > 1 && (
        <button
          className="image-preview__nav image-preview__nav--prev"
          onClick={(e) => {
            e.stopPropagation();
            handlePrevious();
          }}
          type="button"
          aria-label="上一张"
        >
          <Icon icon="mdi:chevron-left" width="48" />
        </button>
      )}

      {/* Image container */}
      <div
        ref={imageContainerRef}
        className="image-preview__container"
        onClick={(e) => e.stopPropagation()}
        onTouchStart={onTouchStart}
        onTouchMove={onTouchMove}
        onTouchEnd={onTouchEnd}
        onMouseDown={onMouseDown}
        onMouseMove={onMouseMove}
        onMouseUp={onMouseUp}
        onMouseLeave={onMouseLeave}
      >
        <img
          src={imageUrl}
          alt={currentImage.fileName}
          className="image-preview__image"
          draggable={false}
        />
      </div>

      {/* Next button */}
      {images.length > 1 && (
        <button
          className="image-preview__nav image-preview__nav--next"
          onClick={(e) => {
            e.stopPropagation();
            handleNext();
          }}
          type="button"
          aria-label="下一张"
        >
          <Icon icon="mdi:chevron-right" width="48" />
        </button>
      )}

      {/* Image info */}
      <div className="image-preview__info">
        <span className="image-preview__filename">{currentImage.fileName}</span>
        <span className="image-preview__filesize">
          {(currentImage.fileSize / 1024).toFixed(1)} KB
        </span>
      </div>
    </div>
  );
};

export default ImagePreview;
