import React, { useState, useCallback, useEffect } from 'react';
import {
  Box,
  Button,
  VStack,
  Text,
  useToast,
  Progress,
  SimpleGrid,
  Image,
  IconButton,
  HStack,
  Alert,
  AlertIcon,
  Spinner,
  Center
} from '@chakra-ui/react';
import { DeleteIcon } from '@chakra-ui/icons';

// Process single image
export const processImage = async (image, onProgress) => {
  try {
    // Initial stage
    if (onProgress) onProgress({ current: 0, stage: 'Loading image...' });

    // Create a promise to load the image
    const loadImage = () => new Promise((resolve, reject) => {
      const img = new window.Image();
      img.onload = () => resolve(img);
      img.onerror = reject;
      img.src = image.url;
    });

    // Load the image
    const img = await loadImage();
    if (onProgress) onProgress({ current: 20, stage: 'Analyzing image...' });

    // Create canvas with white background
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Set canvas size to Kaufland's recommended minimum size
    const targetSize = 2048;
    const padding = 200;

    // Calculate dimensions to maintain aspect ratio
    let canvasWidth, canvasHeight, targetWidth, targetHeight;
    const originalAspectRatio = img.width / img.height;

    if (originalAspectRatio > 1) {
      targetWidth = Math.max(targetSize, img.width);
      targetHeight = targetWidth / originalAspectRatio;
    } else {
      targetHeight = Math.max(targetSize, img.height);
      targetWidth = targetHeight * originalAspectRatio;
    }

    // Set canvas size based on target dimensions plus padding
    canvasWidth = Math.ceil(targetWidth + (padding * 2));
    canvasHeight = Math.ceil(targetHeight + (padding * 2));

    // Ensure minimum size requirement is met
    canvasWidth = Math.max(canvasWidth, targetSize);
    canvasHeight = Math.max(canvasHeight, targetSize);

    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    if (onProgress) onProgress({ current: 40, stage: 'Preparing canvas...' });

    // Fill with white background
    ctx.fillStyle = '#FFFFFF';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    if (onProgress) onProgress({ current: 60, stage: 'Adding white background...' });

    // Calculate position to center the image
    const x = (canvasWidth - targetWidth) / 2;
    const y = (canvasHeight - targetHeight) / 2;

    // Draw image in center
    ctx.drawImage(img, x, y, targetWidth, targetHeight);

    if (onProgress) onProgress({ current: 80, stage: 'Optimizing quality...' });

    // Progressive quality reduction function
    const getProcessedBlob = async (startQuality = 0.9) => {
      let quality = startQuality;
      const maxSize = 2 * 1024 * 1024; // 2MB target size

      while (quality >= 0.3) {
        try {
          const blob = await new Promise((resolve) => {
            canvas.toBlob((b) => resolve(b), 'image/jpeg', quality);
          });

          if (blob.size <= maxSize) {
            if (onProgress) {
              onProgress({
                current: 90,
                stage: 'Finalizing image...',
                imageSize: blob.size
              });
            }
            return blob;
          }

          if (onProgress) {
            onProgress({
              current: 85,
              stage: `Compressing (quality: ${Math.round(quality * 100)}%)...`,
              imageSize: blob.size
            });
          }

          quality -= 0.1;
        } catch (err) {
          throw new Error('Failed to compress image');
        }
      }

      throw new Error('Could not compress image to target size while maintaining acceptable quality');
    };

    try {
      const processedBlob = await getProcessedBlob();

      if (onProgress) onProgress({ current: 100, stage: 'Complete', imageSize: processedBlob.size });

      return {
        id: image.id,
        name: `processed-${image.id}`,
        originalUrl: image.url,
        processedUrl: URL.createObjectURL(processedBlob),
        processedBlob,
        quality: processedBlob.size <= 2 * 1024 * 1024 ? 'good' : 'reduced'
      };
    } catch (compressionError) {
      throw new Error('Failed to process image: ' + compressionError.message);
    }
  } catch (error) {
    throw error;
  }
};

// Process multiple images
export const processImages = async (images, { onProgress } = {}) => {
  const processed = [];
  const totalImages = images.length;

  try {
    for (let i = 0; i < images.length; i++) {
      const image = images[i];

      // Calculate overall progress
      const updateProgress = (progressData) => {
        const overallProgress = ((i + (progressData.current / 100)) / totalImages) * 100;
        if (onProgress) {
          onProgress({
            total: Math.round(overallProgress),
            current: Math.round(progressData.current),
            currentImage: i + 1,
            totalImages,
            stage: progressData.stage,
            imageSize: progressData.imageSize
          });
        }
      };

      const result = await processImage(image, updateProgress);

      if (result) {
        processed.push(result);
      }

      // Small delay between images
      await new Promise(resolve => setTimeout(resolve, 100));
    }

    return processed;
  } catch (error) {
    throw error;
  }
};

const ImageProcessorComponent = ({ onImagesProcessed, isProcessing, setIsProcessing }) => {
  const [selectedFiles, setSelectedFiles] = useState([]);
  const [processedImages, setProcessedImages] = useState([]);
  const [progress, setProgress] = useState(0);
  const [currentFileIndex, setCurrentFileIndex] = useState(0);
  const [currentFileProgress, setCurrentFileProgress] = useState(0);
  const [error, setError] = useState(null);
  const [processingStatus, setProcessingStatus] = useState('');
  const toast = useToast();

  // Regular status updates
  useEffect(() => {
    let statusInterval;
    if (isProcessing) {
      statusInterval = setInterval(() => {
        setProcessingStatus(prev => {
          const dots = prev.match(/\./g)?.length || 0;
          return `Processing${'.'.repeat((dots + 1) % 4)}`;
        });
      }, 500);
    }
    return () => {
      if (statusInterval) clearInterval(statusInterval);
    };
  }, [isProcessing]);

  const handleFileSelect = (event) => {
    const files = Array.from(event.target.files);
    const validFiles = files.filter(file => {
      const isValid = file.type.startsWith('image/');
      if (!isValid) {
        toast({
          title: 'Invalid file type',
          description: `${file.name} is not an image file`,
          status: 'error',
          duration: 3000,
        });
      }
      return isValid;
    });
    setSelectedFiles(prevFiles => [...prevFiles, ...validFiles]);
    setError(null);
  };

  const processAllImages = async () => {
    if (selectedFiles.length === 0) {
      toast({
        title: 'No images selected',
        description: 'Please select images to process',
        status: 'warning',
        duration: 3000,
      });
      return;
    }

    setIsProcessing(true);
    setProgress(0);
    setCurrentFileProgress(0);
    setError(null);
    setCurrentFileIndex(0);
    setProcessingStatus('Starting...');

    try {
      const processed = await processImages(selectedFiles, {
        onProgress: ({ total, current, currentImage, totalImages }) => {
          setProgress(total);
          setCurrentFileProgress(current);
          setCurrentFileIndex(currentImage - 1);
          setProcessingStatus(`Processing image ${currentImage} of ${totalImages}`);
        }
      });

      setProcessedImages(processed);

      if (processed.length > 0) {
        onImagesProcessed(processed);
        toast({
          title: 'Processing Complete',
          description: `Successfully processed ${processed.length} images`,
          status: 'success',
          duration: 3000,
        });
      }
    } catch (error) {
      console.error('Processing error:', error);
      setError(error.message || 'Failed to process images');
      toast({
        title: 'Processing Error',
        description: error.message || 'Failed to process images',
        status: 'error',
        duration: 5000,
      });
    } finally {
      setIsProcessing(false);
      setCurrentFileIndex(0);
      setCurrentFileProgress(0);
      setProcessingStatus('');
    }
  };

  const removeImage = (index) => {
    setSelectedFiles(prevFiles => prevFiles.filter((_, i) => i !== index));
    if (error) setError(null);
  };

  return (
    <VStack spacing={4} width="100%">
      {error && (
        <Alert status="error">
          <AlertIcon />
          {error}
        </Alert>
      )}

      <Box width="100%">
        <input
          type="file"
          accept="image/*"
          multiple
          onChange={handleFileSelect}
          style={{ display: 'none' }}
          id="image-upload"
          disabled={isProcessing}
        />
        <label htmlFor="image-upload">
          <Button
            as="span"
            colorScheme="blue"
            width="100%"
            isDisabled={isProcessing}
          >
            Select Images
          </Button>
        </label>
      </Box>

      {selectedFiles.length > 0 && (
        <SimpleGrid columns={3} spacing={4} width="100%">
          {selectedFiles.map((file, index) => (
            <Box key={index} position="relative">
              <Image
                src={URL.createObjectURL(file)}
                alt={file.name}
                borderRadius="md"
                objectFit="cover"
                width="100%"
                height="150px"
              />
              <IconButton
                icon={<DeleteIcon />}
                size="sm"
                colorScheme="red"
                position="absolute"
                top={2}
                right={2}
                onClick={() => removeImage(index)}
                isDisabled={isProcessing}
              />
              {isProcessing && currentFileIndex === index && (
                <Box
                  position="absolute"
                  top={0}
                  left={0}
                  right={0}
                  bottom={0}
                  bg="blackAlpha.600"
                  borderRadius="md"
                  display="flex"
                  alignItems="center"
                  justifyContent="center"
                  flexDirection="column"
                >
                  <Spinner color="white" mb={2} />
                  <Text color="white" fontSize="sm" fontWeight="bold">
                    {currentFileProgress}%
                  </Text>
                </Box>
              )}
              {isProcessing && currentFileIndex > index && (
                <Box
                  position="absolute"
                  top={0}
                  left={0}
                  right={0}
                  bottom={0}
                  bg="blackAlpha.600"
                  borderRadius="md"
                  display="flex"
                  alignItems="center"
                  justifyContent="center"
                >
                  <Text color="white" fontSize="sm" fontWeight="bold">
                    ✓ Done
                  </Text>
                </Box>
              )}
            </Box>
          ))}
        </SimpleGrid>
      )}

      {isProcessing && (
        <Box width="100%" p={4} borderWidth="1px" borderRadius="md" bg="white">
          <VStack spacing={3}>
            <Text fontWeight="bold">{processingStatus}</Text>
            <Progress
              value={progress}
              size="sm"
              colorScheme="blue"
              width="100%"
              isAnimated
              hasStripe
            />
            <HStack justify="space-between" width="100%">
              <Text>Overall Progress: {progress}%</Text>
              <Text>
                Image {currentFileIndex + 1} of {selectedFiles.length}
              </Text>
            </HStack>
            <Text fontSize="sm" color="gray.600">
              Current image: {currentFileProgress}% complete
            </Text>
          </VStack>
        </Box>
      )}

      {selectedFiles.length > 0 && !isProcessing && (
        <Button
          colorScheme="green"
          onClick={processAllImages}
          width="100%"
          isDisabled={isProcessing}
          loadingText={processingStatus}
        >
          Process {selectedFiles.length} Images
        </Button>
      )}
    </VStack>
  );
};

export { ImageProcessorComponent as default };