"use client";

import { useState, useRef, ChangeEvent, useEffect } from "react";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import { Upload, Download, Image as ImageIcon, X, Trash2 } from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";

export function ImageConverter() {
  const [images, setImages] = useState<File[]>([]);
  const [previewUrls, setPreviewUrls] = useState<string[]>([]);
  const [selectedImageIndex, setSelectedImageIndex] = useState<number | null>(
    null
  );
  const [width, setWidth] = useState<number | string>("");
  const [height, setHeight] = useState<number | string>("");
  const [format, setFormat] = useState<"png" | "jpeg" | "webp">("png");
  const [isConverting, setIsConverting] = useState(false);
  const [isDraggingOver, setIsDraggingOver] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    // Clean up object URLs on component unmount
    return () => {
      previewUrls.forEach((url) => URL.revokeObjectURL(url));
    };
  }, [previewUrls]);

  useEffect(() => {
    if (selectedImageIndex !== null && previewUrls[selectedImageIndex]) {
      const img = new Image();
      img.onload = () => {
        setWidth(img.width);
        setHeight(img.height);
      };
      img.src = previewUrls[selectedImageIndex];
    } else {
      setWidth("");
      setHeight("");
    }
  }, [selectedImageIndex, previewUrls]);

  const handleFiles = (files: FileList | null) => {
    if (!files || files.length === 0) return;

    const imageFiles = Array.from(files).filter((file) =>
      file.type.startsWith("image/")
    );

    if (imageFiles.length === 0) {
      toast.error("No valid image files found.");
      return;
    }

    const newImages = [...images, ...imageFiles];
    const newPreviewUrls = [
      ...previewUrls,
      ...imageFiles.map((file) => URL.createObjectURL(file)),
    ];

    setImages(newImages);
    setPreviewUrls(newPreviewUrls);

    if (selectedImageIndex === null) {
      setSelectedImageIndex(images.length);
    }
    toast.success(`${imageFiles.length} image(s) added.`);
  };

  const handleImageChange = (e: ChangeEvent<HTMLInputElement>) => {
    handleFiles(e.target.files);
    if (e.target) e.target.value = "";
  };

  const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setIsDraggingOver(true);
  };

  const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setIsDraggingOver(false);
  };

  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setIsDraggingOver(false);
    handleFiles(e.dataTransfer.files);
  };

  const handleRemoveImage = (indexToRemove: number) => {
    URL.revokeObjectURL(previewUrls[indexToRemove]);
    const newImages = images.filter((_, i) => i !== indexToRemove);
    const newPreviewUrls = previewUrls.filter((_, i) => i !== indexToRemove);

    setImages(newImages);
    setPreviewUrls(newPreviewUrls);

    if (selectedImageIndex === indexToRemove) {
      setSelectedImageIndex(newImages.length > 0 ? Math.max(0, indexToRemove - 1) : null);
    } else if (selectedImageIndex !== null && selectedImageIndex > indexToRemove) {
      setSelectedImageIndex(selectedImageIndex - 1);
    }
  };

  const handleClearAll = () => {
    previewUrls.forEach((url) => URL.revokeObjectURL(url));
    setImages([]);
    setPreviewUrls([]);
    setSelectedImageIndex(null);
    toast.info("All images cleared.");
  };

  const handleConvertAndDownload = () => {
    if (selectedImageIndex === null || !width || !height) {
      toast.error("Please select an image and set dimensions.");
      return;
    }

    setIsConverting(true);
    const image = images[selectedImageIndex];
    const previewUrl = previewUrls[selectedImageIndex];
    const img = new Image();
    img.crossOrigin = "anonymous";
    img.src = previewUrl;

    img.onload = () => {
      const canvas = document.createElement("canvas");
      canvas.width = Number(width);
      canvas.height = Number(height);
      const ctx = canvas.getContext("2d");

      if (ctx) {
        ctx.drawImage(img, 0, 0, Number(width), Number(height));
        const dataUrl = canvas.toDataURL(`image/${format}`);
        const link = document.createElement("a");
        link.href = dataUrl;
        const originalName = image.name.substring(0, image.name.lastIndexOf('.'));
        link.download = `${originalName}_${width}x${height}.${format}`;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        toast.success(`Exported ${image.name} successfully!`);
      } else {
        toast.error("Could not process the image.");
      }
      setIsConverting(false);
    };
    img.onerror = () => {
      toast.error("Failed to load image for conversion.");
      setIsConverting(false);
    };
  };

  const hasImages = images.length > 0;
  const isImageSelected = selectedImageIndex !== null;

  return (
    <div className="grid grid-cols-1 lg:grid-cols-2 gap-8 w-full">
      <div className="flex flex-col gap-8">
        <Card>
          <CardHeader>
            <CardTitle>Image Settings</CardTitle>
            <CardDescription>
              Adjust resolution and format for the selected image.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-6">
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="width">Width (px)</Label>
                <Input id="width" type="number" placeholder="e.g., 1920" value={width} onChange={(e) => setWidth(e.target.value)} disabled={!isImageSelected} />
              </div>
              <div className="space-y-2">
                <Label htmlFor="height">Height (px)</Label>
                <Input id="height" type="number" placeholder="e.g., 1080" value={height} onChange={(e) => setHeight(e.target.value)} disabled={!isImageSelected} />
              </div>
            </div>
            <div className="space-y-2">
              <Label htmlFor="format">Format</Label>
              <Select value={format} onValueChange={(value: "png" | "jpeg" | "webp") => setFormat(value)} disabled={!isImageSelected}>
                <SelectTrigger id="format"><SelectValue placeholder="Select format" /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="png">PNG</SelectItem>
                  <SelectItem value="jpeg">JPEG</SelectItem>
                  <SelectItem value="webp">WEBP</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </CardContent>
          <CardFooter className="flex justify-between">
            <Button variant="outline" onClick={() => fileInputRef.current?.click()}><Upload className="mr-2 h-4 w-4" />Upload Images</Button>
            <Button onClick={handleConvertAndDownload} disabled={!isImageSelected || isConverting}><Download className="mr-2 h-4 w-4" />{isConverting ? "Converting..." : "Convert & Download"}</Button>
          </CardFooter>
        </Card>

        {hasImages && (
          <Card>
            <CardHeader>
              <div className="flex justify-between items-center">
                <CardTitle>Uploaded Images</CardTitle>
                <Button variant="ghost" size="sm" onClick={handleClearAll}><Trash2 className="mr-2 h-4 w-4" />Clear All</Button>
              </div>
            </CardHeader>
            <CardContent>
              <ScrollArea className="w-full whitespace-nowrap">
                <div className="flex space-x-4 pb-4">
                  {previewUrls.map((url, index) => (
                    <div key={url} className="relative shrink-0">
                      <button onClick={() => setSelectedImageIndex(index)} className={cn("w-24 h-24 rounded-md overflow-hidden border-2 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", selectedImageIndex === index ? "border-primary" : "border-transparent")}>
                        <img src={url} alt={`Preview ${index + 1}`} className="w-full h-full object-cover" />
                      </button>
                      <Button variant="destructive" size="icon" className="absolute -top-2 -right-2 h-6 w-6 rounded-full" onClick={() => handleRemoveImage(index)}><X className="h-4 w-4" /></Button>
                    </div>
                  ))}
                </div>
                <ScrollBar orientation="horizontal" />
              </ScrollArea>
            </CardContent>
          </Card>
        )}
      </div>

      <div className={cn("w-full aspect-video rounded-md border flex items-center justify-center bg-gray-100 dark:bg-gray-800 relative transition-colors", isDraggingOver && "border-primary bg-primary/10")} onDragOver={handleDragOver} onDragLeave={handleDragLeave} onDrop={handleDrop}>
        {isImageSelected && previewUrls[selectedImageIndex] ? (
          <img src={previewUrls[selectedImageIndex]} alt="Selected image preview" className="max-w-full max-h-full object-contain" />
        ) : (
          <div className="w-full h-full border-2 border-dashed rounded-md flex flex-col items-center justify-center text-gray-500 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800/50" onClick={() => fileInputRef.current?.click()}>
            <ImageIcon className="w-12 h-12 mb-2" />
            <span>Click or drag & drop images here</span>
          </div>
        )}
        <Input type="file" ref={fileInputRef} onChange={handleImageChange} className="hidden" accept="image/*" multiple />
      </div>
    </div>
  );
}