'use client';

import { useState, useRef, useEffect, Suspense } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';

function UniqueizerContent() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const fileUploadRef = useRef<HTMLDivElement>(null);

  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [preview, setPreview] = useState<string | null>(null);
  const [uploading, setUploading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [status, setStatus] = useState('');
  const [error, setError] = useState('');
  const [videoKey, setVideoKey] = useState<string | null>(null);
  
  // generationUuid получаем из URL (передаётся из дашборда)
  const generationUuidFromUrl = searchParams.get('generationUuid');
  const [generationUuid, setGenerationUuid] = useState<string | null>(generationUuidFromUrl);

  const [scenarioStarted, setScenarioStarted] = useState(false);

  // Проверяем generationUuid из URL
  useEffect(() => {
    const uuidFromUrl = searchParams.get('generationUuid');
    if (uuidFromUrl) {
      setGenerationUuid(uuidFromUrl);
      setScenarioStarted(true);
      setStatus('Сценарий запущен');
    } else {
      setError('generationUuid не указан. Вернитесь на дашборд и запустите сценарий.');
    }
  }, [searchParams]);

  // Drag and drop
  useEffect(() => {
    const el = fileUploadRef.current;
    if (!el) return;

    ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
      el.addEventListener(eventName, preventDefaults, false);
    });

    ['dragenter', 'dragover'].forEach(eventName => {
      el.addEventListener(eventName, () => el.classList.add('dragover'), false);
    });

    ['dragleave', 'drop'].forEach(eventName => {
      el.addEventListener(eventName, () => el.classList.remove('dragover'), false);
    });

    el.addEventListener('drop', handleDrop, false);
  }, []);

  function preventDefaults(e: Event) {
    e.preventDefault();
    e.stopPropagation();
  }

  function handleDrop(e: DragEvent) {
    const dt = e.dataTransfer;
    if (dt?.files.length) {
      handleFileSelect(dt.files[0]);
    }
  }

  function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
    if (e.target.files?.length) {
      handleFileSelect(e.target.files[0]);
    }
  }

  function handleFileSelect(file: File) {
    const allowedTypes = ['video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/webm'];
    if (!allowedTypes.includes(file.type)) {
      setError('Недопустимый тип файла. Разрешены: MP4, MOV, AVI, WebM');
      return;
    }
    const maxSize = 500 * 1024 * 1024;
    if (file.size > maxSize) {
      setError('Файл слишком большой. Максимум: 500MB');
      return;
    }
    setSelectedFile(file);
    setPreview(URL.createObjectURL(file));
    setError('');
    setVideoKey(null);
  }

  function removeFile() {
    setSelectedFile(null);
    setPreview(null);
    setVideoKey(null);
    if (fileInputRef.current) fileInputRef.current.value = '';
  }

  function formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
  }

  async function handleUploadVideo() {
    try {
      const s3Key = await uploadVideoMultipart();
      setVideoKey(s3Key);  // Сохраняем ключ после загрузки
    } catch (err: unknown) {
      // Ошибка уже обработана в uploadVideoMultipart
    }
  }

  async function uploadVideoMultipart() {
    if (!selectedFile) throw new Error('Файл не выбран');
    if (!generationUuid) throw new Error('generationUuid не получен');

    setUploading(true);
    setUploadProgress(0);
    setError('');
    setStatus('Инициализация загрузки...');

    try {
      const csrfToken = await getCsrfToken();

      // 1. Инициализация multipart upload
      const initResponse = await fetch('/api/upload/video/init', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': csrfToken,
        },
        credentials: 'same-origin',
        body: JSON.stringify({
          filename: selectedFile.name,
          contentType: selectedFile.type,
          fileSize: selectedFile.size,
          generationUuid,
        }),
      });

      if (!initResponse.ok) {
        const errorData = await initResponse.json();
        throw new Error(errorData.message || 'Ошибка инициализации загрузки');
      }

      const initData = await initResponse.json();
      const { fileId, uploadId, parts, s3Key } = initData.data;

      setStatus(`Загрузка видео... 0%`);

      // 2. Параллельная загрузка частей напрямую в S3
      const uploadedParts = new Array(parts.length);
      const PART_SIZE = 10 * 1024 * 1024; // 10MB (увеличено для эффективности)
      const MAX_CONCURRENT = 6; // До 6 частей параллельно

      // Функция загрузки одной части с retry и прогрессом
      const uploadPartWithRetry = async (partIndex: number, maxRetries = 3): Promise<{ PartNumber: number; ETag: string } | undefined> => {
        const part = parts[partIndex];
        const start = partIndex * PART_SIZE;
        const end = Math.min(start + PART_SIZE, selectedFile.size);
        const chunk = selectedFile.slice(start, end);

        for (let attempt = 1; attempt <= maxRetries; attempt++) {
          try {
            const startTime = Date.now();
            console.log(`[Upload] Часть ${part.partNumber}: начало загрузки, размер: ${(chunk.size / 1024 / 1024).toFixed(2)} MB`);
            
            // Используем XMLHttpRequest для лучшей производительности с бинарными данными
            const etag = await new Promise<string>((resolve, reject) => {
              const xhr = new XMLHttpRequest();
              xhr.open('PUT', part.presignedUrl, true);
              
              // Отслеживаем прогресс загрузки
              xhr.upload.onprogress = function(e) {
                if (e.lengthComputable) {
                  const percent = (e.loaded / e.total * 100).toFixed(1);
                  const speed = (e.loaded / ((Date.now() - startTime) / 1000) / 1024 / 1024).toFixed(2);
                  console.log(`[Upload] Часть ${part.partNumber}: ${percent}% (${speed} MB/s)`);
                }
              };
              
              // Устанавливаем таймаут 120 секунд
              xhr.timeout = 120000;
              
              xhr.onload = function() {
                const duration = ((Date.now() - startTime) / 1000).toFixed(2);
                const speed = (chunk.size / 1024 / 1024 / parseFloat(duration)).toFixed(2);
                console.log(`[Upload] Часть ${part.partNumber}: завершено за ${duration}s (${speed} MB/s)`);
                
                if (xhr.status === 200) {
                  const etag = xhr.getResponseHeader('ETag');
                  if (etag) {
                    resolve(etag.replace(/"/g, '')); // MinIO возвращает ETag в кавычках
                  } else {
                    reject(new Error('Нет ETag'));
                  }
                } else {
                  reject(new Error(`HTTP ${xhr.status}: ${xhr.responseText}`));
                }
              };
              
              xhr.onerror = function() {
                console.error(`[Upload] Часть ${part.partNumber}: ошибка сети`);
                reject(new Error('Network error'));
              };
              
              xhr.ontimeout = function() {
                console.error(`[Upload] Часть ${part.partNumber}: таймаут`);
                reject(new Error('Timeout'));
              };
              
              xhr.send(chunk);
            });

            return {
              PartNumber: part.partNumber,
              ETag: etag,
            };
          } catch (err) {
            if (attempt === maxRetries) {
              throw new Error(`Часть ${part.partNumber}: ${err instanceof Error ? err.message : 'ошибка'}`);
            }
            // Ждём перед retry
            await new Promise(r => setTimeout(r, 100 * attempt));
          }
        }
      };

      // Загружаем части пачками по MAX_CONCURRENT
      for (let i = 0; i < parts.length; i += MAX_CONCURRENT) {
        const batch = [];
        const batchEnd = Math.min(i + MAX_CONCURRENT, parts.length);
        
        for (let j = i; j < batchEnd; j++) {
          batch.push(uploadPartWithRetry(j));
        }

        const results = await Promise.all(batch);
        
        // Сохраняем результаты
        for (let k = 0; k < results.length; k++) {
          uploadedParts[i + k] = results[k];
        }

        // Обновляем прогресс
        const progress = Math.round(((i + batch.length) / parts.length) * 100);
        setUploadProgress(progress);
        setStatus(`Загрузка видео... ${progress}%`);
      }

      // 3. Завершение multipart upload
      setStatus('Завершение загрузки...');
      const completeResponse = await fetch('/api/upload/video/complete', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': csrfToken,
        },
        credentials: 'same-origin',
        body: JSON.stringify({
          fileId,
          uploadId,
          parts: uploadedParts.filter(p => p !== undefined),
        }),
      });

      if (!completeResponse.ok) {
        const errorData = await completeResponse.json();
        throw new Error(errorData.message || 'Ошибка завершения загрузки');
      }

      setUploadProgress(100);
      setStatus('Видео загружено');
      setUploading(false);

      return s3Key;
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : 'Ошибка загрузки');
      setUploading(false);
      throw err;
    }
  }

  async function handleUniqueize() {
    setError('');

    try {
      if (!generationUuid) throw new Error('generationUuid не получен');

      let s3Key = videoKey;

      // Если видео ещё не загружено, загружаем
      if (!s3Key) {
        setUploading(true);
        setStatus('Загрузка видео...');
        s3Key = await uploadVideoMultipart();
        setVideoKey(s3Key);
        setUploading(false);
      }

      setStatus('Видео отправлено на обработку');

      const csrfToken = await getCsrfToken();

      // Вызываем step/1 с url видео
      const stepPayload = {
        input: {
          url: s3Key,
        },
      };

      const stepResponse = await fetch('/api/scenario/uniqueizer/step/1', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': csrfToken,
        },
        credentials: 'same-origin',
        body: JSON.stringify(stepPayload),
      });

      if (!stepResponse.ok) {
        const data = await stepResponse.json();
        throw new Error(data.message || 'Ошибка выполнения шага');
      }

      // Переход на страницу результата
      setTimeout(() => {
        router.push(`/result?generationUuid=${generationUuid}`);
      }, 1000);

    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : 'Ошибка обработки');
      setUploading(false);
    }
  }

  async function getCsrfToken(): Promise<string> {
    const response = await fetch('/api/auth/csrf', { credentials: 'same-origin' });
    const data = await response.json();
    return data.csrfToken || '';
  }

  function handleClose() {
    router.push('/dashboard');
  }

  return (
    <div style={styles.page}>
      <div style={styles.container}>
        <div style={styles.card}>
          <h1 style={styles.title}>Уникализация видео</h1>

          {error && <div style={styles.error}>{error}</div>}
          {status && (
            <div style={styles.status}>
              <span>{status}</span>
            </div>
          )}

          {/* Статус сценария */}
          {!scenarioStarted && (
            <div style={styles.infoBox}>
              <span style={styles.spinner}></span>
              Запуск сценария...
            </div>
          )}
          {scenarioStarted && !error && (
            <div style={styles.infoBox}>
              ✓ Сценарий запущен (ID: {generationUuid?.slice(0, 8)}...)
            </div>
          )}

          {/* Загрузка видео */}
          <div style={styles.section}>
            <h2 style={styles.sectionTitle}>1. Загрузите видео</h2>

            {!selectedFile ? (
              <div
                ref={fileUploadRef}
                style={styles.fileUpload}
                onClick={() => fileInputRef.current?.click()}
              >
                <input
                  ref={fileInputRef}
                  type="file"
                  accept="video/mp4,video/quicktime,video/x-msvideo,video/webm"
                  onChange={handleFileChange}
                  style={{ display: 'none' }}
                />
                <div style={styles.fileUploadIcon}>🎬</div>
                <div style={styles.fileUploadText}>
                  Нажмите для загрузки или перетащите файл
                </div>
                <div style={styles.fileUploadHint}>
                  MP4, MOV, AVI, WebM до 500MB
                </div>
              </div>
            ) : (
              <div style={styles.filePreview}>
                <video src={preview!} controls style={styles.previewVideo} />
                <div style={styles.filePreviewInfo}>
                  <div style={styles.filePreviewName}>{selectedFile.name}</div>
                  <div>{formatFileSize(selectedFile.size)}</div>
                </div>
                <button
                  type="button"
                  onClick={removeFile}
                  style={styles.fileRemove}
                  disabled={uploading}
                >
                  ×
                </button>
              </div>
            )}

            {selectedFile && !videoKey && (
              <div>
                {uploading && uploadProgress > 0 && (
                  <div style={styles.progressContainer}>
                    <div style={{
                      ...styles.progressBar,
                      width: `${uploadProgress}%`,
                    }}></div>
                    <span style={styles.progressText}>{uploadProgress}%</span>
                  </div>
                )}
                <button
                  onClick={handleUploadVideo}
                  disabled={uploading || !scenarioStarted}
                  style={{
                    ...styles.btn,
                    ...styles.btnPrimary,
                    ...((uploading || !scenarioStarted) ? styles.btnDisabled : {}),
                  }}
                >
                  {uploading ? 'Загрузка...' : 'Загрузить видео'}
                </button>
              </div>
            )}
          </div>

          {/* Кнопка уникализации */}
          {(videoKey || selectedFile) && (
            <div style={styles.section}>
              <h2 style={styles.sectionTitle}>2. Уникализируйте</h2>
              <p style={styles.sectionDesc}>
                После нажатия видео будет отправлено на обработку
              </p>
              <button
                onClick={handleUniqueize}
                disabled={uploading || !scenarioStarted}
                style={{
                  ...styles.btn,
                  ...styles.btnPrimary,
                  ...((uploading || !scenarioStarted) ? styles.btnDisabled : {}),
                }}
              >
                {uploading ? 'Загрузка...' : 'Уникализировать'}
              </button>
            </div>
          )}

          {/* Кнопка закрытия */}
          <button onClick={handleClose} style={styles.btnSecondary}>
            Закрыть
          </button>
        </div>
      </div>
    </div>
  );
}

const styles: Record<string, React.CSSProperties> = {
  page: {
    minHeight: '100vh',
    background: '#f5f5f5',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    padding: '40px 20px',
  },
  container: {
    maxWidth: '700px',
    width: '100%',
  },
  emptyState: {
    textAlign: 'center',
    padding: '60px 20px',
    color: '#666',
    fontSize: '16px',
  },
  card: {
    background: 'white',
    padding: '40px',
    borderRadius: '8px',
    boxShadow: '0 2px 10px rgba(0,0,0,0.1)',
  },
  title: {
    fontSize: '24px',
    fontWeight: 600,
    marginBottom: '24px',
    color: '#333',
    textAlign: 'center',
  },
  infoBox: {
    display: 'flex',
    alignItems: 'center',
    gap: '10px',
    padding: '12px',
    background: '#e8f5e9',
    color: '#2e7d32',
    borderRadius: '6px',
    marginBottom: '20px',
    fontSize: '14px',
  },
  section: {
    marginBottom: '32px',
    padding: '20px',
    background: '#f8f9fa',
    borderRadius: '8px',
  },
  sectionTitle: {
    fontSize: '16px',
    fontWeight: 600,
    color: '#333',
    marginBottom: '8px',
  },
  sectionDesc: {
    fontSize: '14px',
    color: '#666',
    marginBottom: '16px',
  },
  fileUpload: {
    border: '2px dashed #ddd',
    borderRadius: '8px',
    padding: '40px 20px',
    textAlign: 'center',
    cursor: 'pointer',
    transition: 'all 0.2s',
  },
  fileUploadIcon: {
    fontSize: '48px',
    marginBottom: '16px',
  },
  fileUploadText: {
    fontSize: '16px',
    color: '#666',
    marginBottom: '8px',
  },
  fileUploadHint: {
    fontSize: '13px',
    color: '#999',
  },
  filePreview: {
    position: 'relative',
    marginBottom: '16px',
  },
  previewVideo: {
    width: '100%',
    maxHeight: '400px',
    borderRadius: '8px',
    background: '#000',
  },
  filePreviewInfo: {
    padding: '12px',
    background: '#fff',
    borderRadius: '6px',
    marginTop: '8px',
    fontSize: '14px',
    color: '#666',
  },
  filePreviewName: {
    fontWeight: 500,
    color: '#333',
    marginBottom: '4px',
  },
  fileRemove: {
    position: 'absolute',
    top: '8px',
    right: '8px',
    background: 'rgba(220, 38, 38, 0.9)',
    color: 'white',
    border: 'none',
    borderRadius: '50%',
    width: '32px',
    height: '32px',
    fontSize: '20px',
    cursor: 'pointer',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  },
  btn: {
    width: '100%',
    padding: '14px 24px',
    borderRadius: '6px',
    fontSize: '15px',
    fontWeight: 500,
    cursor: 'pointer',
    border: 'none',
    transition: 'all 0.2s',
  },
  btnPrimary: {
    background: '#007bff',
    color: 'white',
  },
  btnDisabled: {
    background: '#ccc',
    cursor: 'not-allowed',
  },
  btnSecondary: {
    width: '100%',
    padding: '12px 24px',
    background: '#f5f5f5',
    color: '#333',
    border: '1px solid #ddd',
    borderRadius: '6px',
    fontSize: '14px',
    fontWeight: 500,
    cursor: 'pointer',
  },
  error: {
    background: '#fee',
    color: '#c00',
    padding: '12px',
    borderRadius: '6px',
    marginBottom: '20px',
    fontSize: '14px',
  },
  status: {
    display: 'flex',
    alignItems: 'center',
    gap: '10px',
    padding: '12px',
    background: '#e7f3ff',
    color: '#0066cc',
    borderRadius: '6px',
    marginBottom: '20px',
    fontSize: '14px',
  },
  spinner: {
    display: 'inline-block',
    width: '16px',
    height: '16px',
    border: '2px solid rgba(0,123,255,0.3)',
    borderTopColor: '#007bff',
    borderRadius: '50%',
    animation: 'spin 1s linear infinite',
  },
  progressContainer: {
    position: 'relative',
    height: '24px',
    background: '#e0e0e0',
    borderRadius: '12px',
    marginBottom: '12px',
    overflow: 'hidden',
  },
  progressBar: {
    height: '100%',
    background: 'linear-gradient(90deg, #007bff, #0056b3)',
    borderRadius: '12px',
    transition: 'width 0.3s ease',
  },
  progressText: {
    position: 'absolute',
    top: '50%',
    left: '50%',
    transform: 'translate(-50%, -50%)',
    fontSize: '13px',
    fontWeight: '600',
    color: '#333',
  },
};

export default function UniqueizerPage() {
  return (
    <Suspense fallback={<div style={styles.page}><div style={styles.container}><div style={styles.emptyState}>Загрузка...</div></div></div>}>
      <UniqueizerContent />
    </Suspense>
  );
}
