import { useContext, useRef, useState } from 'react'
import CanvasContext from '../Context/canvasContext/CanvasContext'
import { Button } from '@/components/ui/button'
import { fabric } from 'fabric'
import { ImageIcon, Trash2 } from 'lucide-react'
import { Label } from '@/components/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import Resizer from "react-image-file-resizer"
import { Slider } from '@/components/ui/slider'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { useDropzone } from 'react-dropzone'
import ImageCustomization from './Customization/ImageCustomization'
import { Separator } from '../ui/separator'
import ActiveObjectContext from '../Context/activeObject/ObjectContext'

const UploadImage = () => {
    const { canvas } = useContext(CanvasContext);
    const [width, setWidth] = useState(1080);
    const [height, setHeight] = useState(1080);
    const [quality, setQuality] = useState(100);
    const [rotation, setRotation] = useState("0");
    const [format, setFormat] = useState('JPEG');
    const fileInputRef = useRef(null);

    const { activeObject, setActiveObject } = useContext(ActiveObjectContext);

    const [file, setFile] = useState(null);
    const [preview, setPreview] = useState(null);

    const { getRootProps, getInputProps, isDragActive } = useDropzone({
        accept: {
            'image/*': ['.jpeg', '.png', '.gif', '.jpg', '.webp', '.svg']
        },
        // maxSize: 5 * 1024 * 1024, // 5MB max file size
        multiple: false,
        onDrop: (acceptedFiles) => {
            if (!acceptedFiles.length) {
                console.error("No files were dropped.");
                return;
            }
            const selectedFile = acceptedFiles[0];
            // Create a preview URL
            const blobUrl = URL.createObjectURL(selectedFile);
            setFile(selectedFile);
            setPreview(blobUrl);

            if (selectedFile.type === "image/svg+xml") {
                addImageToCanvas(selectedFile);
                URL.revokeObjectURL(blobUrl);
            } else {
                const imgElement = new Image();
                imgElement.src = blobUrl;

                imgElement.onload = () => {
                    if (imgElement.width > 1080) {
                        handleResize(selectedFile, (compressedFile) => {
                            addImageToCanvas(compressedFile);
                        });
                    } else {
                        addImageToCanvas(selectedFile);
                    }
                    URL.revokeObjectURL(blobUrl); // Clean up
                };

                imgElement.onerror = () => {
                    console.error("Failed to load image.");
                    URL.revokeObjectURL(blobUrl); // Clean up
                };
            }
        }
    });

    const removeFile = () => {
        // Revoke the object URL to free up memory
        if (preview) {
            URL.revokeObjectURL(preview)
        }
        setFile(null)
        setPreview(null)
        if (fileInputRef.current) {
            fileInputRef.current.value = ""
        }
        if (activeObject?.type === "image") {
            canvas.remove(activeObject);
            setActiveObject(null);
            canvas.renderAll();
        }
    }

    const handleResize = (file, callback) => {
        Resizer.imageFileResizer(
            file,
            width,
            height,
            format,
            quality,
            parseInt(rotation),
            (resizedFile) => {
                callback(resizedFile)
            },
            'file',
        )
    }

    const addImageToCanvas = (file) => {
        const blobUrl = URL.createObjectURL(file)
        fabric.Image.fromURL(blobUrl, (img) => {
            img.set({
                left: canvas.width / 4,
                top: canvas.height / 4,
                scaleX: 0.5,
                scaleY: 0.5,
            })
            canvas.add(img)
            canvas.setActiveObject(img);
            // Update the active object state
            setActiveObject(img);
            canvas.renderAll();
            URL.revokeObjectURL(blobUrl);
        })
    }

    return (
        <Card className="w-full mx-auto">
            <CardHeader className="px-4 py-3">
                <CardTitle>Image Upload & Editing</CardTitle>
                <CardDescription>Upload, resize, and apply effects to your images</CardDescription>
            </CardHeader>
            <CardContent className="p-2">
                <Tabs defaultValue="upload">
                    <TabsList className="grid w-full grid-cols-2">
                        <TabsTrigger value="upload">Upload</TabsTrigger>
                        <TabsTrigger value="effects">Effects</TabsTrigger>
                    </TabsList>

                    {/* Uploads */}
                    <TabsContent value="upload">
                        <div className="space-y-4">
                            <div className="grid grid-cols-2 gap-4">
                                <div className="space-y-2">
                                    <Label>Width: {width}px</Label>
                                    <Slider
                                        value={[width]}
                                        max={2000}
                                        min={300}
                                        step={10}
                                        onValueChange={(value) => setWidth(value[0])}
                                    />
                                </div>
                                <div className="space-y-2">
                                    <Label>Height: {height}px</Label>
                                    <Slider
                                        value={[height]}
                                        max={2000}
                                        min={300}
                                        step={10}
                                        onValueChange={(value) => setHeight(value[0])}
                                    />
                                </div>
                            </div>
                            {format === "JPEG" && (
                                <div className="space-y-2">
                                    <Label>Quality: {quality}%</Label>
                                    <Slider
                                        value={[quality]}
                                        max={100}
                                        step={1}
                                        onValueChange={(value) => setQuality(value[0])}
                                    />
                                </div>
                            )}

                            <div className="grid grid-cols-2 gap-4">
                                <div className="space-y-2">
                                    <Label>Format</Label>
                                    <Select value={format} onValueChange={setFormat}>
                                        <SelectTrigger>
                                            <SelectValue />
                                        </SelectTrigger>
                                        <SelectContent>
                                            <SelectItem value="JPEG">JPEG</SelectItem>
                                            <SelectItem value="PNG">PNG</SelectItem>
                                            <SelectItem value="WEBP">WEBP</SelectItem>
                                        </SelectContent>
                                    </Select>
                                </div>
                                <div className="space-y-2">
                                    <Label>Rotation</Label>
                                    <Select value={rotation} onValueChange={setRotation}>
                                        <SelectTrigger>
                                            <SelectValue />
                                        </SelectTrigger>
                                        <SelectContent>
                                            <SelectItem value="0">0°</SelectItem>
                                            <SelectItem value="45">45°</SelectItem>
                                            <SelectItem value="90">90°</SelectItem>
                                            <SelectItem value="180">180°</SelectItem>
                                            <SelectItem value="270">270°</SelectItem>
                                        </SelectContent>
                                    </Select>
                                </div>
                            </div>

                            {/* upload image */}
                            {
                                !preview &&
                                <div className="max-w-md mx-auto p-4">
                                    <Card>
                                        <CardContent className="p-6 space-y-4">
                                            <div
                                                {...getRootProps()}
                                                className={`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors duration-300 ${isDragActive ? 'border-primary bg-primary/10' : 'border-gray-300 hover:border-primary'} ${preview ? 'hidden' : ''}`}
                                                ref={fileInputRef}
                                            >
                                                <input {...getInputProps()} />
                                                <div className="flex flex-col items-center justify-center space-y-4">
                                                    <ImageIcon
                                                        className={`h-12 w-12 ${isDragActive ? 'text-primary' : 'text-gray-400'}`}
                                                    />
                                                    <p className="text-sm text-gray-600">
                                                        {isDragActive
                                                            ? 'Drop file here'
                                                            : 'Drag \'n\' drop an image, or click to select a file'
                                                        }
                                                    </p>
                                                    <p className="text-xs text-gray-500">
                                                        (Max 5MB, image files only)
                                                    </p>
                                                </div>
                                            </div>
                                        </CardContent>
                                    </Card>
                                </div>
                            }

                            {/* preview image  */}
                            {preview && (
                                <Card className="overflow-y-scroll rounded-none">
                                    <CardContent className="mt-2 mb-2">
                                        <div className="w-fit aspect-square relative h-[100%]">
                                            {
                                                file?.type === "image/svg+xml" ? <object
                                                    data={preview}
                                                    type="image/svg+xml"
                                                    className="object-cover rounded-lg"
                                                    style={{ width: '100%', height: '100%' }}
                                                >
                                                    Your browser does not support SVG, no preview available for SVG.
                                                </object> :
                                                    <img
                                                        src={preview}
                                                        alt="Uploaded image"
                                                        className="object-cover rounded-lg overflow-hidden"
                                                    />
                                            }

                                            <Separator className="my-4" />
                                            <div className="grid grid-cols-1 gap-2 items-center pb-4">
                                                <p className="text-sm text-gray-600 truncate">{file?.name}</p>
                                                <Button
                                                    variant="destructive"
                                                    size="sm"
                                                    onClick={removeFile}
                                                >
                                                    <Trash2 className="mr-2 h-4 w-4" />
                                                    Remove
                                                </Button>
                                            </div>
                                        </div>
                                    </CardContent>
                                </Card>
                            )}
                        </div>
                    </TabsContent>

                    {/* Effects */}
                    <TabsContent value="effects">
                        <ImageCustomization />
                    </TabsContent>
                </Tabs>
            </CardContent>
        </Card>
    )
}
export default UploadImage


