import React, { useEffect, useState, useRef, useCallback } from 'react';
import styles from './Gallery.module.css';
import apiService from '../services/api';
import { GeneratedImage, PendingTask } from '../types/api';
import ImageViewer from '../components/shared/ImageViewer';
import ImageWithFallback from '../components/shared/ImageWithFallback';
import NotificationModal from '../components/shared/NotificationModal';

const GalleryScreen: React.FC = () => {
  const [images, setImages] = useState<GeneratedImage[]>([]);
  const [pendingTasks, setPendingTasks] = useState<PendingTask[]>([]);
  const [loading, setLoading] = useState(true);
  const [loadingPendingTasks, setLoadingPendingTasks] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedImage, setSelectedImage] = useState<string | null>(null);
  const [refreshing, setRefreshing] = useState(false);
  const [pullDistance, setPullDistance] = useState(0);
  const containerRef = useRef<HTMLDivElement>(null);
  const startY = useRef<number | null>(null);
  const threshold = 80; // Порог для активации обновления
  
  // Состояния для режима удаления
  const [isDeleteMode, setIsDeleteMode] = useState(false);
  const [selectedForDelete, setSelectedForDelete] = useState<GeneratedImage | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);
  const longPressTimer = useRef<number | null>(null);

  // Функция для расчета времени ожидания
  const getEstimatedWaitTime = (queuePosition: number | null): string => {
    if (queuePosition === null) return 'Генерация началась';
    
    const seconds = apiService.calculateEstimatedWaitTime(queuePosition);
    if (seconds < 60) return `${seconds} сек`;
    return `${Math.floor(seconds / 60)} мин ${seconds % 60} сек`;
  };

  // Обработчики для режима удаления
  const handleLongPress = useCallback((image: GeneratedImage) => {
    setIsDeleteMode(true);
  }, []);

  const startLongPressTimer = useCallback((image: GeneratedImage) => {
    longPressTimer.current = setTimeout(() => {
      handleLongPress(image);
    }, 800); // 800ms для долгого нажатия
  }, [handleLongPress]);

  const cancelLongPressTimer = useCallback(() => {
    if (longPressTimer.current) {
      clearTimeout(longPressTimer.current);
      longPressTimer.current = null;
    }
  }, []);

  const handleDeleteClick = useCallback((image: GeneratedImage) => {
    setSelectedForDelete(image);
  }, []);

  const handleConfirmDelete = useCallback(async () => {
    if (selectedForDelete) {
      try {
        setIsDeleting(true);
        await apiService.deleteImage(selectedForDelete.link);
        
        // Обновляем список изображений
        setImages(prevImages => 
          prevImages.filter(img => img.id !== selectedForDelete.id)
        );
        
        setIsDeleting(false);
        setSelectedForDelete(null);
      } catch (error) {
        console.error('Error deleting image:', error);
        setIsDeleting(false);
      }
    }
  }, [selectedForDelete]);

  const exitDeleteMode = useCallback(() => {
    setIsDeleteMode(false);
    setSelectedForDelete(null);
  }, []);

  // Обработчик клика по контейнеру для выхода из режима удаления
  const handleGridClick = useCallback((e: React.MouseEvent) => {
    // Проверяем, что клик был не по крестику удаления
    if (isDeleteMode && !(e.target as HTMLElement).closest(`.${styles.deleteButton}`)) {
      setIsDeleteMode(false);
      setSelectedForDelete(null);
    }
  }, [isDeleteMode]);

  // Функция для обновления всех данных
  const refreshAll = async () => {
    // Выходим из режима удаления при обновлении
    setIsDeleteMode(false);
    setRefreshing(true);
    try {
      // Загружаем изображения
      const fetchedImages = await apiService.getGeneratedImages();
      setImages(fetchedImages);
      
      // Загружаем задачи в очереди
      const fetchedPendingTasks = await apiService.getUserPendingTasks();
      setPendingTasks(fetchedPendingTasks);
      
      setError(null);
    } catch (err) {
      setError('Не удалось обновить данные');
      console.error(err);
    } finally {
      // Задержка для лучшего UX, чтобы пользователь видел, что происходит обновление
      setTimeout(() => {
        setRefreshing(false);
      }, 500);
    }
  };

  // Обработчики для pull-to-refresh
  const handleTouchStart = (e: React.TouchEvent) => {
    if (containerRef.current && containerRef.current.scrollTop === 0) {
      startY.current = e.touches[0].clientY;
    }
  };

  const handleTouchMove = (e: React.TouchEvent) => {
    if (!startY.current) return;
    
    // Только если контейнер в верхней позиции
    if (containerRef.current && containerRef.current.scrollTop === 0) {
      const currentY = e.touches[0].clientY;
      const diff = currentY - startY.current;
      
      // Применяем сопротивление - чем дальше тянем, тем сложнее
      if (diff > 0) {
        const resistance = 0.4;
        const distance = Math.min(diff * resistance, threshold * 1.5);
        setPullDistance(distance);
      }
    }
  };

  const handleTouchEnd = async () => {
    // Если достигли порога, запускаем обновление
    if (pullDistance >= threshold) {
      setRefreshing(true);
      // Сбрасываем расстояние вытягивания
      setPullDistance(0);
      // Обновляем данные
      await refreshAll();
    } else {
      // Анимированно возвращаем к исходному состоянию
      setPullDistance(0);
    }
    
    startY.current = null;
  };

  // Загрузка данных при монтировании компонента
  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true);
        setLoadingPendingTasks(true);
        
        // Загружаем изображения
        const fetchedImages = await apiService.getGeneratedImages();
        setImages(fetchedImages);
        
        // Загружаем задачи в очереди
        const fetchedPendingTasks = await apiService.getUserPendingTasks();
        setPendingTasks(fetchedPendingTasks);
        
        setError(null);
      } catch (err) {
        setError('Не удалось загрузить данные');
        console.error(err);
      } finally {
        setLoading(false);
        setLoadingPendingTasks(false);
      }
    };

    fetchData();
  }, []);
  
  // Отслеживание задач в очереди
  useEffect(() => {
    // Если в очереди нет задач, не запускаем интервал
    if (pendingTasks.length === 0) return;
    
    console.log('Запускаем отслеживание задач в очереди:', pendingTasks);
    
    // Запускаем интервал только если есть задачи в очереди
    const intervalId = setInterval(async () => {
      try {
        // Сохраняем предыдущий список задач для сравнения
        const previousTasks = [...pendingTasks];
        
        // Получаем обновленный список задач
        const fetchedPendingTasks = await apiService.getUserPendingTasks();
        console.log('Обновленные задачи в очереди:', fetchedPendingTasks);
        
        // Обновляем список задач
        setPendingTasks(fetchedPendingTasks);
        
        // Проверяем, исчезла ли задача из очереди
        if (previousTasks.length > fetchedPendingTasks.length) {
          console.log('Задача исчезла из очереди, обновляем галерею');
          const fetchedImages = await apiService.getGeneratedImages();
          setImages(fetchedImages);
        }
        
        // Если все задачи завершены, очищаем интервал
        if (fetchedPendingTasks.length === 0) {
          console.log('Все задачи завершены, останавливаем отслеживание');
          clearInterval(intervalId);
        }
      } catch (err) {
        console.error('Ошибка при обновлении статуса задач:', err);
      }
    }, 15000); // Обновляем каждые 15 секунд
    
    // Очищаем интервал при размонтировании компонента
    return () => clearInterval(intervalId);
  }, [pendingTasks.length]); // Зависимость от количества задач

  return (
    <div className={styles.pullToRefreshContainer}>
      <div 
        className={`${styles.refreshIndicator} ${refreshing ? styles.refreshing : ''}`}
        style={{ '--pull-distance': `${pullDistance}px` } as React.CSSProperties}
      >
        <div className={styles.refreshSpinner}></div>
        {refreshing && <span>Обновление...</span>}
      </div>
      
      <div 
        ref={containerRef}
        className={styles.content}
        style={{ '--pull-distance': `${pullDistance}px` } as React.CSSProperties}
        onTouchStart={handleTouchStart}
        onTouchMove={handleTouchMove}
        onTouchEnd={handleTouchEnd}
      >
        <div className={styles.header}>
          <h1 className={styles.title}>
            Галерея стикеров
          </h1>
        </div>

        {loading && (
          <div className={styles.placeholder}>
            Загрузка изображений...
          </div>
        )}

        {error && (
          <div className={styles.error}>
            {error}
          </div>
        )}

        {!loading && !error && images.length === 0 && pendingTasks.length === 0 && (
          <div className={styles.placeholder}>
            У вас пока нет сгенерированных стикеров
          </div>
        )}
        
        {!loading && !loadingPendingTasks && pendingTasks.length > 0 && (
          <div className={styles.pendingTasksSection}>
            <h2 className={styles.sectionTitle}>В процессе генерации</h2>
            <div className={styles.pendingTasksGrid}>
              {pendingTasks.map((task) => (
                <div key={task.task_id} className={styles.pendingTaskItem}>
                  <div className={styles.pendingTaskPlaceholder}>
                    <div className={styles.spinner}></div>
                  </div>
                  <div className={styles.pendingTaskInfo}>
                    <p className={styles.pendingTaskStatus}>
                      {task.status === 'PENDING' 
                        ? `В очереди: ${task.queue_position}` 
                        : 'Генерация...'}
                    </p>
                    <p className={styles.pendingTaskTime}>
                      Осталось: {getEstimatedWaitTime(task.queue_position)}
                    </p>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        {!loading && !error && images.length > 0 && (
          <div 
            className={`${styles.imageGrid} ${isDeleteMode ? styles.deleteMode : ''}`}
            onClick={handleGridClick}
          >
            {images.map((image, index) => (
              <div 
                key={image.id} 
                className={styles.imageItem}
                onTouchStart={() => !isDeleteMode && startLongPressTimer(image)}
                onTouchEnd={() => !isDeleteMode && cancelLongPressTimer()}
                onTouchMove={() => !isDeleteMode && cancelLongPressTimer()}
              >
                <ImageWithFallback 
                  src={image.url || ''} 
                  alt={`Стикер ${index + 1}`} 
                  className={styles.image}
                  onClick={() => !isDeleteMode && image.url && setSelectedImage(image.url)}
                  onContextMenu={(e: React.MouseEvent<HTMLDivElement>) => e.preventDefault()}
                  maxRetries={3}
                  isDeleteMode={isDeleteMode}
                />
                {isDeleteMode && (
                  <div 
                    className={styles.deleteButton}
                    onClick={() => handleDeleteClick(image)}
                  >
                    ✕
                  </div>
                )}
              </div>
            ))}
          </div>
        )}

      </div>

      {/* Полноэкранный просмотр */}
      {selectedImage && (
        <ImageViewer 
          imageUrl={selectedImage} 
          onClose={() => setSelectedImage(null)} 
        />
      )}

      {/* Модальное окно подтверждения удаления */}
      <NotificationModal
        isVisible={!!selectedForDelete}
        title="Удаление стикера"
        message="Вы уверены, что хотите удалить этот стикер?"
        isLoading={isDeleting}
        showGalleryButton={true}
        galleryButtonText="Отмена"
        continueButtonText="Удалить"
        onContinueClick={handleConfirmDelete}
        onGalleryClick={() => setSelectedForDelete(null)}
        isPrimaryGalleryButton={false}
      />
    </div>
  );
};

export default GalleryScreen;
