import { useState, useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
import {
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Button,
  Box,
  Typography,
  LinearProgress,
  List,
  ListItem,
  ListItemText,
  IconButton,
  Alert,
} from '@mui/material';
import {
  CloudUpload as UploadIcon,
  Close as CloseIcon,
  CheckCircle as SuccessIcon,
  Error as ErrorIcon,
} from '@mui/icons-material';
import api from '../services/api';

interface UploadFile {
  file: File;
  progress: number;
  status: 'pending' | 'uploading' | 'success' | 'error';
  error?: string;
  assetId?: string;
}

interface UploadDialogProps {
  open: boolean;
  onClose: () => void;
  onComplete?: () => void;
}

export default function UploadDialog({ open, onClose, onComplete }: UploadDialogProps) {
  const [files, setFiles] = useState<UploadFile[]>([]);
  const [uploading, setUploading] = useState(false);

  const onDrop = useCallback((acceptedFiles: File[]) => {
    const newFiles: UploadFile[] = acceptedFiles.map((file) => ({
      file,
      progress: 0,
      status: 'pending',
    }));
    setFiles((prev) => [...prev, ...newFiles]);
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    accept: {
      'image/*': ['.jpg', '.jpeg', '.png', '.gif', '.webp'],
      'video/*': ['.mp4', '.mov', '.avi', '.mkv', '.webm'],
    },
  });

  const updateFileProgress = (index: number, progress: number, status: UploadFile['status'], error?: string, assetId?: string) => {
    setFiles((prev) =>
      prev.map((f, i) =>
        i === index ? { ...f, progress, status, error, assetId } : f
      )
    );
  };

  const uploadFile = async (file: File, index: number) => {
    try {
      updateFileProgress(index, 0, 'uploading');

      // Step 1: Create upload
      const uploadData = await api.createUpload({
        original_filename: file.name,
        content_type: file.type,
        size_bytes: file.size,
      });

      updateFileProgress(index, 33, 'uploading', undefined, uploadData.asset_id);

      // Step 2: Upload file to backend
      await api.uploadFileToBackend(uploadData.asset_id, file);

      updateFileProgress(index, 66, 'uploading', undefined, uploadData.asset_id);

      // Step 3: Finalize upload
      await api.finalizeUpload(uploadData.asset_id);

      updateFileProgress(index, 100, 'success', undefined, uploadData.asset_id);
    } catch (error: any) {
      console.error('Upload failed:', error);
      updateFileProgress(
        index,
        0,
        'error',
        error.response?.data?.detail || 'Ошибка загрузки'
      );
    }
  };

  const handleUpload = async () => {
    setUploading(true);

    // Upload files in parallel (max 3 at a time)
    const batchSize = 3;
    for (let i = 0; i < files.length; i += batchSize) {
      const batch = files.slice(i, i + batchSize);
      await Promise.all(
        batch.map((file, batchIndex) => {
          const fileIndex = i + batchIndex;
          if (files[fileIndex].status === 'pending') {
            return uploadFile(files[fileIndex].file, fileIndex);
          }
          return Promise.resolve();
        })
      );
    }

    setUploading(false);
    if (onComplete) {
      onComplete();
    }
  };

  const handleClose = () => {
    if (!uploading) {
      setFiles([]);
      onClose();
    }
  };

  const canUpload = files.length > 0 && files.some((f) => f.status === 'pending');
  const allComplete = files.length > 0 && files.every((f) => f.status === 'success' || f.status === 'error');

  return (
    <Dialog open={open} onClose={handleClose} maxWidth="md" fullWidth>
      <DialogTitle>
        Загрузка файлов
        <IconButton
          onClick={handleClose}
          disabled={uploading}
          sx={{ position: 'absolute', right: 8, top: 8 }}
        >
          <CloseIcon />
        </IconButton>
      </DialogTitle>

      <DialogContent>
        {files.length === 0 && (
          <Box
            {...getRootProps()}
            sx={{
              border: '2px dashed',
              borderColor: isDragActive ? 'primary.main' : 'grey.400',
              borderRadius: 2,
              p: 4,
              textAlign: 'center',
              cursor: 'pointer',
              bgcolor: isDragActive ? 'action.hover' : 'transparent',
              transition: 'all 0.3s',
              '&:hover': {
                bgcolor: 'action.hover',
                borderColor: 'primary.main',
              },
            }}
          >
            <input {...getInputProps()} />
            <UploadIcon sx={{ fontSize: 64, color: 'primary.main', mb: 2 }} />
            <Typography variant="h6" gutterBottom>
              {isDragActive
                ? 'Отпустите файлы для загрузки'
                : 'Перетащите файлы сюда'}
            </Typography>
            <Typography variant="body2" color="text.secondary">
              или нажмите для выбора файлов
            </Typography>
            <Typography variant="caption" color="text.secondary" display="block" sx={{ mt: 2 }}>
              Поддерживаются фото (JPG, PNG, GIF, WebP) и видео (MP4, MOV, AVI, MKV, WebM)
            </Typography>
          </Box>
        )}

        {files.length > 0 && (
          <List sx={{ maxHeight: 400, overflow: 'auto' }}>
            {files.map((uploadFile, index) => (
              <ListItem key={index} sx={{ flexDirection: 'column', alignItems: 'stretch' }}>
                <Box sx={{ display: 'flex', alignItems: 'center', width: '100%', mb: 1 }}>
                  <ListItemText
                    primary={uploadFile.file.name}
                    secondary={`${(uploadFile.file.size / 1024 / 1024).toFixed(2)} MB`}
                  />
                  {uploadFile.status === 'success' && (
                    <SuccessIcon color="success" />
                  )}
                  {uploadFile.status === 'error' && (
                    <ErrorIcon color="error" />
                  )}
                </Box>

                {uploadFile.status === 'uploading' && (
                  <LinearProgress
                    variant="determinate"
                    value={uploadFile.progress}
                    sx={{ mb: 1 }}
                  />
                )}

                {uploadFile.error && (
                  <Alert severity="error" sx={{ mt: 1 }}>
                    {uploadFile.error}
                  </Alert>
                )}
              </ListItem>
            ))}
          </List>
        )}

        {files.length > 0 && !allComplete && (
          <Box
            {...getRootProps()}
            sx={{
              mt: 2,
              p: 2,
              border: '1px dashed',
              borderColor: 'grey.400',
              borderRadius: 1,
              textAlign: 'center',
              cursor: 'pointer',
              '&:hover': { bgcolor: 'action.hover' },
            }}
          >
            <input {...getInputProps()} />
            <Typography variant="body2" color="text.secondary">
              Добавить еще файлы
            </Typography>
          </Box>
        )}
      </DialogContent>

      <DialogActions>
        <Button onClick={handleClose} disabled={uploading}>
          {allComplete ? 'Закрыть' : 'Отмена'}
        </Button>
        {canUpload && (
          <Button
            onClick={handleUpload}
            variant="contained"
            disabled={uploading}
          >
            Загрузить ({files.filter((f) => f.status === 'pending').length})
          </Button>
        )}
      </DialogActions>
    </Dialog>
  );
}
