import ActiveObjectContext from "@/components/Context/activeObject/ObjectContext";
import CanvasContext from "@/components/Context/canvasContext/CanvasContext";
import { useContext, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { fabric } from "fabric";
import Resizer from "react-image-file-resizer";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Slider } from "@/components/ui/slider";
import {
  HardDriveUpload,
  ImagePlus,
  Upload,
  Crop,
  RotateCw,
  FileType,
  ChevronUp,
  ChevronDown,
} from "lucide-react";
import { Card, CardContent } from "@/components/ui/card";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import CollapsibleComponent from "./CollapsibleComponent";
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { useToast } from "@/hooks/use-toast";
import { useMutation } from "@tanstack/react-query";
import useProject from "@/hooks/useProject";
import { uploadImage } from "@/api/uploadApi";

const features = [
  {
    icon: Upload,
    title: "Auto-Resize",
    description: "Images larger than 1080px are automatically resized",
  },
  {
    icon: Crop,
    title: "Custom Dimensions",
    description: "Set your preferred resize dimensions",
  },
  {
    icon: RotateCw,
    title: "Quality & Rotation",
    description: "Adjust image quality and rotation as needed",
  },
  {
    icon: FileType,
    title: "Format Conversion",
    description: "Convert between various image formats",
  },
];

const AddImageIntoShape = () => {
  const { canvas } = useContext(CanvasContext);
  const { activeObject, setActiveObject } = useContext(ActiveObjectContext);
  const [errorMessage, setErrorMessage] = useState("");
  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 [isOpen, setIsOpen] = useState(false);

  const { toast } = useToast();

  const { id, projectData, projectUpdate } = useProject();

  // Upload image handler
  const { mutate: uploadMutate } = useMutation({
    mutationFn: async ({ file, id }) => await uploadImage({ file, id }),
    onSuccess: (data) => {
      if (data?.status === 200) {
        toast({ title: data?.status, description: data?.message });
        handleImageInsert(data?.data[0]?.url);
      } else {
        toast({ variant: "destructive", title: data?.status, description: data?.message });
      }
    },
  });


  const handleResize = (file, callback) => {
    Resizer.imageFileResizer(
      file,
      width,
      height,
      format,
      quality,
      parseInt(rotation),
      (resizedFile) => {
        callback(resizedFile); // Pass the resized file to the callback
      },
      "file" // Output type
    );
  };

  const fileHandler = (e) => {
    if (!activeObject) {
      toast({ variant: "destructive", title: "No active object selected!" });
      return;
    }
    const file = e.target.files[0];
    if (!file && activeObject) {
      setErrorMessage("No file selected.");
      return;
    }

    // Check if the file is an SVG (skip compression)
    if (file.type === "image/svg+xml") {
      toast({ variant: "destructive", title: "SVG files are not supported!" });
      clearFileInput();
      return;
    }

    // Handle raster images (JPEG, PNG, etc.)
    const imgElement = new Image();
    const blobUrl = URL.createObjectURL(file);
    imgElement.src = blobUrl;

    imgElement.onload = () => {
      if (imgElement.width > 1080) {
        handleResize(file, (compressedFile) => {
          uploadMutate({ file: compressedFile, id }); // Fixed key name
          clearFileInput();
        });
      } else {
        uploadMutate({ file, id }); // Direct upload if width is small
        clearFileInput();
      }
      URL.revokeObjectURL(blobUrl); // Clean up
    };

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

  const clearFileInput = () => {
    if (fileInputRef.current) {
      fileInputRef.current.value = "";
    }
  };

  // const handleImageInsert = (img) => {
  //   if (!activeObject) {
  //     setErrorMessage("No active object selected!");
  //     return;
  //   }
  //   // Ensure absolute positioning for the clipPath
  //   activeObject.set({
  //     isClipPath: true, // Custom property
  //     absolutePositioned: true,
  //   });

  //   // Calculate scale factors based on clip object size
  //   let scaleX = activeObject.width / img.width;
  //   let scaleY = activeObject.height / img.height;
  //   if (activeObject?.width < 100) {
  //     scaleX = 0.2;
  //   }

  //   if (activeObject.height < 100) {
  //     scaleY = 0.2;
  //   }

  //   // Create a fabric image object with scaling and clipPath
  //   const fabricImage = new fabric.Image.fromURL(img, {
  //     scaleX: scaleX,
  //     scaleY: scaleY,
  //     left: activeObject.left,
  //     top: activeObject.top,
  //     clipPath: activeObject, // Apply clipPath to the image
  //     originX: activeObject.originX, // Match origin point
  //     originY: activeObject.originY, // Match origin point
  //   }, { crossOrigin: "anonymous" });

  //   // Adjust position based on the clipPath's transformations
  //   fabricImage.set({
  //     left: activeObject.left,
  //     top: activeObject.top,
  //     angle: activeObject.angle, // Match rotation if any
  //   });

  //   canvas.add(fabricImage);
  //   canvas.setActiveObject(fabricImage);
  //   setActiveObject(fabricImage);
  //   canvas.renderAll();
  //   // Update the active object state
  //   projectUpdate({ id, updateData: { ...projectData?.data, object: canvas.toJSON(['id', 'selectable']), preview_url: "" } });
  // };


  const handleImageInsert = (imgUrl) => {

    console.log(imgUrl);

    // Ensure absolute positioning for the clipPath
    activeObject.set({
      isClipPath: true, // Custom property
      absolutePositioned: true,
    });

    // Load the image asynchronously
    fabric.Image.fromURL(
      imgUrl,
      (img) => {
        // Ensure the image is fully loaded before applying transformations
        let scaleX = activeObject.width / img.width;
        let scaleY = activeObject.height / img.height;

        // Prevent the image from being too small
        if (activeObject.width < 100) scaleX = 0.2;
        if (activeObject.height < 100) scaleY = 0.2;

        // Set image properties
        img.set({
          scaleX: scaleX,
          scaleY: scaleY,
          left: activeObject.left,
          top: activeObject.top,
          clipPath: activeObject, // Apply clipPath to the image
          originX: activeObject.originX, // Match origin point
          originY: activeObject.originY, // Match origin point
          crossOrigin: "anonymous", // Ensure CORS handling
        });

        // Add image to canvas
        canvas.add(img);
        canvas.setActiveObject(img);
        setActiveObject(img);
        canvas.renderAll();

        // Update project data
        projectUpdate({
          id,
          updateData: {
            ...projectData?.data,
            object: canvas.toJSON(["id", "selectable"]),
            preview_url: "",
          },
        });
      },
      { crossOrigin: "anonymous" }
    );
  };

  const content = () => {
    return (
      <div>
        <Card className="my-2">
          <CardContent className="p-0">
            <Alert>
              <AlertTitle className="text-lg font-semibold flex items-center gap-1 flex-wrap">
                Image Insertion <ImagePlus className="h-5 w-5" />
              </AlertTitle>
              <AlertDescription className="mt-1">
                <p className="mb-1">
                  Insert and customize images within shapes. Adjust image
                  position and clipping after insertion.
                </p>
                <Collapsible open={isOpen} onOpenChange={setIsOpen}>
                  <CollapsibleTrigger asChild>
                    <Button
                      variant="outline"
                      className="w-full justify-between mt-2"
                    >
                      <span>Key Features</span>
                      {isOpen ? (
                        <ChevronUp className="h-4 w-4" />
                      ) : (
                        <ChevronDown className="h-4 w-4" />
                      )}
                    </Button>
                  </CollapsibleTrigger>
                  <CollapsibleContent>
                    <div className="grid grid-cols-1 gap-2 mt-2">
                      {features.map((feature, index) => (
                        <div
                          key={index}
                          className="flex items-start p-4 bg-white rounded-lg shadow-sm"
                        >
                          <feature.icon className="h-6 w-6 mr-3 flex-shrink-0 text-primary" />
                          <div>
                            <h3 className="font-semibold mb-1">
                              {feature.title}
                            </h3>
                            <p className="text-sm text-gray-600">
                              {feature.description}
                            </p>
                          </div>
                        </div>
                      ))}
                    </div>
                  </CollapsibleContent>
                </Collapsible>
              </AlertDescription>
            </Alert>
          </CardContent>
        </Card>

        {errorMessage && (
          <p className="text-red-600 text-sm mt-2">{errorMessage}</p>
        )}
        <div className="flex flex-col w-[100%]">
          <div className="space-y-1">
            {/* Width Slider */}
            <div className="space-y-1">
              <Label className="text-xs">Width: {width}px</Label>
              <Slider
                min={300}
                value={[width]}
                max={2000}
                step={10}
                onValueChange={(value) => setWidth(value[0])}
              />
            </div>

            {/* Height Slider */}
            <div className="space-y-1">
              <Label className="text-xs">Height: {height}px</Label>
              <Slider
                min={300}
                value={[height]}
                max={2000}
                step={10}
                onValueChange={(value) => setHeight(value[0])}
              />
            </div>

            {/* Quality Slider */}
            {format === "JPEG" && (
              <div className="space-y-1">
                <Label className="text-xs">Quality: {quality}%</Label>
                <Slider
                  value={[quality]}
                  max={100}
                  step={1}
                  onValueChange={(value) => setQuality(value[0])}
                />
              </div>
            )}

            <div className="grid grid-cols-2 gap-1 items-center">
              {/* Rotation */}
              <div>
                <Label className="text-xs">Rotation: {rotation}°</Label>

                <Select
                  value={rotation}
                  onValueChange={(value) => setRotation(value)}
                >
                  <SelectTrigger className="w-full">
                    <SelectValue placeholder="Select rotation in degree" />
                  </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>

              {/* Format Dropdown */}
              <div>
                <Label className="text-xs">Format</Label>
                <Select
                  value={format}
                  onValueChange={(value) => setFormat(value)}
                >
                  <SelectTrigger className="w-full">
                    <SelectValue placeholder="Select format" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="JPEG">JPEG</SelectItem>
                    <SelectItem value="PNG">PNG</SelectItem>
                    <SelectItem value="WEBP">WEBP</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            </div>
          </div>

          <Button className="w-fit h-fit flex flex-wrap gap-1 relative py-4 my-4 mx-auto">
            <HardDriveUpload className="cursor-pointer" />
            Upload Image
            <Input
              className="cursor-pointer bg-white text-black absolute top-0 opacity-0"
              type="file"
              accept="image/*"
              ref={fileInputRef}
              onChange={fileHandler}
            />
          </Button>
        </div>
      </div>
    );
  };

  return (
    <Card className="flex flex-col shadow-none border-0">
      <CollapsibleComponent text={"Insert Image"}>
        {content()}
      </CollapsibleComponent>
    </Card>
  );
};

export default AddImageIntoShape;
