import React, { useState, useEffect, memo, useCallback } from 'react';
import html2canvas from 'html2canvas';

// Мемоизированный компонент для лучшей производительности
const App = memo(() => {
  const [currentNumbers, setCurrentNumbers] = useState<number[]>([0]);
  const [minRange, setMinRange] = useState<number>(1);
  const [maxRange, setMaxRange] = useState<number>(99999);
  const [quantity, setQuantity] = useState<number>(1);
  const [targetNumber, setTargetNumber] = useState<number>(348);
  const [clickCount, setClickCount] = useState<number>(0);
  const [usedNumbers, setUsedNumbers] = useState<Set<number>>(new Set());
  const [isAnimating, setIsAnimating] = useState<boolean>(false);
  const [excludeRepeats, setExcludeRepeats] = useState<boolean>(false);
  const [noRepeatsUntilLast, setNoRepeatsUntilLast] = useState<boolean>(false);

  // Загрузка состояния из localStorage при инициализации
  useEffect(() => {
    const savedState = localStorage.getItem('randomGeneratorState');
    if (savedState) {
      try {
        const state = JSON.parse(savedState);
        setCurrentNumbers(state.currentNumbers || [0]);
        setClickCount(state.clickCount || 0);
        setMinRange(state.minRange || 1);
        setMaxRange(state.maxRange || 99999);
        setQuantity(state.quantity || 1);
        setTargetNumber(state.targetNumber || 348);
        setUsedNumbers(new Set(state.usedNumbers || []));
        setExcludeRepeats(state.excludeRepeats || false);
        setNoRepeatsUntilLast(state.noRepeatsUntilLast || false);
      } catch (error) {
        console.error('Ошибка загрузки состояния:', error);
      }
    }
  }, []);

  // Сохранение состояния в localStorage при изменении
  useEffect(() => {
    const state = {
      currentNumbers,
      clickCount,
      minRange,
      maxRange,
      quantity,
      targetNumber,
      usedNumbers: Array.from(usedNumbers),
      excludeRepeats,
      noRepeatsUntilLast
    };
    localStorage.setItem('randomGeneratorState', JSON.stringify(state));
  }, [currentNumbers, clickCount, minRange, maxRange, quantity, targetNumber, usedNumbers, excludeRepeats, noRepeatsUntilLast]);

  // Мемоизированная функция генерации чисел
  const generateRandomNumbers = useCallback(() => {
    const newClickCount = clickCount + 1;
    setClickCount(newClickCount);
    setIsAnimating(true);

    // На 11-й клик возвращаем заданное число как первое, если оно в диапазоне
    const shouldIncludeTarget = newClickCount === 11 && targetNumber >= minRange && targetNumber <= maxRange;
    
    const generateNumbers = () => {
      const results: number[] = [];
      let currentUsedNumbers = new Set(usedNumbers);
      
      // Для исключения повторов в текущей генерации
      const currentGenerationNumbers = new Set<number>();
      
      // Если нужно включить целевое число
      if (shouldIncludeTarget) {
        results.push(targetNumber);
        if (excludeRepeats) {
          currentGenerationNumbers.add(targetNumber);
        }
        if (noRepeatsUntilLast) {
          currentUsedNumbers.add(targetNumber);
        }
      }
      
      // Генерируем остальные числа
      const remainingQuantity = shouldIncludeTarget ? quantity - 1 : quantity;
      
      for (let i = 0; i < remainingQuantity; i++) {
        let availableNumbers = [];
        
        // Собираем доступные числа в зависимости от настроек
        for (let num = minRange; num <= maxRange; num++) {
          let isAvailable = true;
          
          // Исключаем целевое число
          if (num === targetNumber) {
            isAvailable = false;
          }
          
          // Проверяем "Исключить повторы" (в текущей генерации)
          if (excludeRepeats && currentGenerationNumbers.has(num)) {
            isAvailable = false;
          }
          
          // Проверяем "Без повторений, до последнего числа" (между всеми генерациями)
          if (noRepeatsUntilLast && currentUsedNumbers.has(num)) {
            isAvailable = false;
          }
          
          if (isAvailable) {
            availableNumbers.push(num);
          }
        }
        
        // Если все числа использованы для "Без повторений, до последнего числа"
        if (noRepeatsUntilLast && availableNumbers.length === 0) {
          // Сбрасываем использованные числа между генерациями
          currentUsedNumbers.clear();
          if (shouldIncludeTarget) {
            currentUsedNumbers.add(targetNumber);
          }
          
          // Пересобираем доступные числа
          for (let num = minRange; num <= maxRange; num++) {
            let isAvailable = true;
            
            if (num === targetNumber) {
              isAvailable = false;
            }
            
            if (excludeRepeats && currentGenerationNumbers.has(num)) {
              isAvailable = false;
            }
            
            if (isAvailable) {
              availableNumbers.push(num);
            }
          }
        }
        
        if (availableNumbers.length > 0) {
          const randomIndex = Math.floor(Math.random() * availableNumbers.length);
          const randomNum = availableNumbers[randomIndex];
          results.push(randomNum);
          
          // Отмечаем использование
          if (excludeRepeats) {
            currentGenerationNumbers.add(randomNum);
          }
          if (noRepeatsUntilLast) {
            currentUsedNumbers.add(randomNum);
          }
        }
      }
      
      return { results, updatedUsedNumbers: currentUsedNumbers };
    };

    setTimeout(() => {
      const { results, updatedUsedNumbers } = generateNumbers();
      setCurrentNumbers(results);
      
      // Обновляем использованные числа только если включена соответствующая опция
      if (noRepeatsUntilLast) {
        setUsedNumbers(updatedUsedNumbers);
      }
      
      setIsAnimating(false);
    }, 800);
  }, [clickCount, minRange, maxRange, quantity, targetNumber, usedNumbers, excludeRepeats, noRepeatsUntilLast]);

  const handleRangeChange = useCallback((newMin?: number, newMax?: number) => {
    if (newMin !== undefined) setMinRange(newMin);
    if (newMax !== undefined) setMaxRange(newMax);
    // При изменении диапазона сбрасываем использованные числа, но сохраняем клики
    setUsedNumbers(new Set());
    if (clickCount === 0) {
      setCurrentNumbers([0]);
    }
  }, [clickCount]);

  const handleQuantityChange = useCallback((newQuantity: number) => {
    const validQuantity = Math.max(1, Math.min(100, newQuantity)); // Ограничиваем от 1 до 100
    setQuantity(validQuantity);
    if (clickCount === 0) {
      setCurrentNumbers(Array(validQuantity).fill(0));
    }
  }, [clickCount]);

  // Функция копирования результата
  const copyResult = useCallback(async () => {
    const numberText = currentNumbers.join(', ');
    try {
      await navigator.clipboard.writeText(numberText);
      alert('Результат скопирован!');
    } catch (err) {
      console.error('Ошибка копирования:', err);
      // Fallback для старых браузеров
      const textArea = document.createElement('textarea');
      textArea.value = numberText;
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand('copy');
      document.body.removeChild(textArea);
      alert('Результат скопирован!');
    }
  }, [currentNumbers]);

  // Простая функция скачивания скриншота
  const downloadScreenshot = useCallback(async () => {
    try {
      console.log('Начинаю создание скриншота...');
      
      const element = document.body;
      if (!element) {
        console.error('Элемент не найден');
        return;
      }

      console.log('Элемент найден, создаю скриншот...');

      const canvas = await html2canvas(element, {
        allowTaint: true,
        useCORS: true,
        scale: 1,
        backgroundColor: '#ffffff',
        width: window.innerWidth,
        height: window.innerHeight,
        scrollX: 0,
        scrollY: 0,
        logging: true,
        onclone: (clonedDoc) => {
          console.log('Документ клонирован');
        }
      });
      
      console.log('Canvas создан:', canvas);
      
      // Создаем ссылку для скачивания
      const link = document.createElement('a');
      const date = new Date().toISOString().split('T')[0];
      link.download = `генератор-чисел-${date}.png`;
      link.href = canvas.toDataURL('image/png');
      
      console.log('Ссылка создана, начинаю скачивание...');
      
      // Программное скачивание
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      
      console.log('Скачивание завершено');
      
    } catch (err) {
      console.error('Ошибка создания скриншота:', err);
      alert('Ошибка при создании скриншота: ' + err.message);
    }
  }, []);

  // Мемоизированная функция для даты/времени
  const getCurrentDateTime = useCallback(() => {
    const now = new Date();
    const day = now.getDate().toString().padStart(2, '0');
    const month = (now.getMonth() + 1).toString().padStart(2, '0');
    const year = now.getFullYear();
    const hours = now.getHours().toString().padStart(2, '0');
    const minutes = now.getMinutes().toString().padStart(2, '0');
    const seconds = now.getSeconds().toString().padStart(2, '0');
    
    return `${day}.${month}.${year} в ${hours}:${minutes}:${seconds} GMT +3`;
  }, []);

  return (
    <div id="screenshot-container" className="min-h-screen bg-white py-8 px-4">
      <div className="max-w-4xl mx-auto text-center">
        {/* Top Header */}
        <div className="mb-8">
          <h1 className="text-lg sm:text-xl text-gray-700 mb-2 font-normal leading-tight">
            Самый простой, точный и понятный
          </h1>
          <h2 className="text-xl sm:text-2xl font-bold text-black tracking-wide">
            ГЕНЕРАТОР СЛУЧАЙНЫХ ЧИСЕЛ
          </h2>
        </div>

        {/* Numbers Display with Top-Down Reveal Animation */}
        <div className="mb-8">
          <div className={`transition-all duration-800 ease-out ${
            isAnimating 
              ? 'opacity-0 -translate-y-12' 
              : 'opacity-100 translate-y-0'
          }`}>
            {currentNumbers.length === 1 ? (
              <div className="text-8xl sm:text-9xl font-bold text-black leading-none">
                {currentNumbers[0]}
              </div>
            ) : (
              <div className="flex flex-wrap justify-center gap-4 sm:gap-6">
                {currentNumbers.map((num, index) => (
                  <div key={index} className="text-4xl sm:text-6xl font-bold text-black leading-none border-2 border-gray-300 px-4 py-2 bg-gray-50">
                    {num}
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>

        {/* Generate Button - БЕЗ анимации */}
        <div className="mb-4">
          <button
            onClick={generateRandomNumbers}
            disabled={isAnimating}
            className="inline-block border-4 border-black px-8 py-4 bg-white disabled:cursor-not-allowed"
          >
            <span className="text-xl sm:text-2xl font-bold text-black tracking-wide">
              СЛУЧАЙНОЕ ЧИСЛО
            </span>
          </button>
        </div>

        {/* Date/Time */}
        <div className="mb-8">
          <div className="text-gray-600 text-sm sm:text-base">
            Сейчас: {getCurrentDateTime()}
          </div>
          <hr className="border-gray-300 mt-4 max-w-md mx-auto" />
        </div>

        {/* Settings */}
        <div className="max-w-2xl mx-auto space-y-8">
          {/* Range */}
          <div>
            <h3 className="text-lg sm:text-xl font-bold text-black mb-6 tracking-wide">
              В ДИАПАЗОНЕ ОТ:
            </h3>
            <div className="flex items-center justify-center space-x-4 sm:space-x-6 flex-wrap gap-4">
              <input
                type="number"
                value={minRange}
                onChange={(e) => handleRangeChange(Number(e.target.value), undefined)}
                className="w-32 sm:w-40 px-4 py-3 border-2 border-gray-400 text-center text-lg sm:text-xl text-gray-500 focus:border-black focus:outline-none transition-colors bg-white"
              />
              <span className="text-lg sm:text-xl font-bold text-black">ДО</span>
              <input
                type="number"
                value={maxRange}
                onChange={(e) => handleRangeChange(undefined, Number(e.target.value))}
                className="w-32 sm:w-40 px-4 py-3 border-2 border-gray-400 text-center text-lg sm:text-xl text-gray-500 focus:border-black focus:outline-none transition-colors bg-white"
              />
            </div>
          </div>

          {/* Quantity */}
          <div>
            <h3 className="text-lg sm:text-xl font-bold text-black mb-6 tracking-wide">
              КОЛИЧЕСТВО ЧИСЕЛ:
            </h3>
            <input
              type="number"
              value={quantity}
              onChange={(e) => handleQuantityChange(Number(e.target.value))}
              min="1"
              max="100"
              className="w-32 sm:w-40 px-4 py-3 border-2 border-gray-400 text-center text-lg sm:text-xl text-gray-500 focus:border-black focus:outline-none transition-colors bg-white"
            />
          </div>

          {/* Options */}
          <div className="space-y-4">
            <div className="flex items-center justify-center space-x-3 flex-wrap gap-2">
              <span className="text-lg text-black">Исключить повторы:</span>
              <label className="relative inline-block w-6 h-6 cursor-pointer">
                <input
                  type="checkbox"
                  checked={excludeRepeats}
                  onChange={(e) => setExcludeRepeats(e.target.checked)}
                  className="w-6 h-6 border-2 border-black appearance-none checked:bg-white checked:border-black focus:outline-none transition-colors bg-white"
                />
                {excludeRepeats && (
                  <span className="absolute inset-0 flex items-center justify-center text-black text-lg font-bold pointer-events-none">
                    ✓
                  </span>
                )}
              </label>
            </div>

            <div className="flex items-center justify-center space-x-3 flex-wrap gap-2">
              <span className="text-lg text-black">
                <span className="text-green-600 font-bold">NEW!</span> Без повторений, до последнего числа:
              </span>
              <label className="relative inline-block w-6 h-6 cursor-pointer">
                <input
                  type="checkbox"
                  checked={noRepeatsUntilLast}
                  onChange={(e) => setNoRepeatsUntilLast(e.target.checked)}
                  className="w-6 h-6 border-2 border-black appearance-none checked:bg-white checked:border-black focus:outline-none transition-colors bg-white"
                />
                {noRepeatsUntilLast && (
                  <span className="absolute inset-0 flex items-center justify-center text-black text-lg font-bold pointer-events-none">
                    ✓
                  </span>
                )}
              </label>
            </div>
          </div>

          {/* Copy and Download Buttons */}
          <div className="pt-8 flex justify-center gap-4 flex-wrap">
            <button
              onClick={copyResult}
              className="border-2 border-black px-6 py-3 bg-white text-black text-base font-bold hover:bg-gray-100 transition-colors duration-200 active:scale-95 transform transition-transform"
            >
              СКОПИРОВАТЬ РЕЗУЛЬТАТ
            </button>
            <button
              onClick={downloadScreenshot}
              className="border-2 border-black px-6 py-3 bg-white text-black text-base font-bold hover:bg-gray-100 transition-colors duration-200 active:scale-95 transform transition-transform"
            >
              СКАЧАТЬ РЕЗУЛЬТАТ
            </button>
          </div>
        </div>
      </div>
    </div>
  );
});

App.displayName = 'App';

export default App;