import { useContext, useRef, useState } from "react";
import CanvasContext from "./Context/canvasContext/CanvasContext";
import { Card, CardTitle } from "./ui/card";
import { Button } from "./ui/button";
import { Trash2, UploadIcon, X } from "lucide-react";
import { Separator } from "./ui/separator";
import ColorComponent from "./ColorComponent";
import { Label } from "./ui/label";
import { Input } from "./ui/input";
import { Slider } from "./ui/slider";
import { fabric } from "fabric";
import OpenContext from "./Context/openContext/OpenContext";
import { ScrollArea } from "./ui/scroll-area";
import RndComponent from "./Layouts/RndComponent";

const CanvasSetting = () => {
  const { canvas, canvasHeight, canvasWidth, screenWidth } =
    useContext(CanvasContext);
  const { setOpenSetting } = useContext(OpenContext);
  const bgImgRef = useRef(null);

  const [canvasSettings, setCanvasSettings] = useState({
    width: canvas?.width,
    height: canvas?.height,
    perPixelTargetFind: true, // Enable per-pixel detection globally
    targetFindTolerance: 4, // Adjust for leniency in pixel-perfect detection
  });

  const handleChange = (key, value) => {
    setCanvasSettings((prevSettings) => ({
      ...prevSettings,
      [key]: value,
    }));

    // Update canvas dimensions
    if (key === "width") {
      canvas.setWidth(value); // Update canvas width
    } else if (key === "height") {
      canvas.setHeight(value); // Update canvas height
    }

    // Adjust the background image to fit the updated canvas
    const bgImage = canvas.backgroundImage;
    if (bgImage) {
      const canvasWidth = canvas.width;
      const canvasHeight = canvas.height;

      // Calculate scaling factors for width and height
      const scaleX = canvasWidth / bgImage.width;
      const scaleY = canvasHeight / bgImage.height;

      // Choose the larger scale to cover the entire canvas
      const scale = Math.max(scaleX, scaleY);

      // Apply the scale and center the image
      bgImage.scaleX = scale;
      bgImage.scaleY = scale;
      bgImage.left = 0; // Align left
      bgImage.top = 0; // Align top

      // Mark the background image as needing an update
      canvas.setBackgroundImage(bgImage, canvas.renderAll.bind(canvas));
    } else {
      canvas.renderAll(); // Render if no background image
    }
  };

  const setBackgroundImage = (e) => {
    const file = e.target.files[0];
    if (file) {
      const blobUrl = URL.createObjectURL(file);

      // Create an image element
      const imgElement = new Image();
      imgElement.src = blobUrl;

      imgElement.onload = () => {
        // Create a fabric.Image instance
        const img = new fabric.Image(imgElement, {
          scaleX: canvas.width / imgElement.width,
          scaleY: canvas.height / imgElement.height,
        });

        // Set the background image on the canvas
        canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));

        // Revoke the object URL to free memory
        URL.revokeObjectURL(blobUrl);
      };

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

  const setBackgroundOverlayImage = (e) => {
    const file = e.target.files[0];
    if (file) {
      const blobUrl = URL.createObjectURL(file);

      // Create an image element
      const imgElement = new Image();
      imgElement.src = blobUrl;

      imgElement.onload = () => {
        const img = new fabric.Image(imgElement, {
          scaleX: canvas.width / imgElement.width,
          scaleY: canvas.height / imgElement.height,
        });

        // Use setOverlayImage method to add the image as an overlay
        canvas.setOverlayImage(img, () => {
          canvas.renderAll();
        });

        // Revoke the object URL after image is loaded and set
        URL.revokeObjectURL(blobUrl);
      };
    }
  };

  const adjustBackgroundOpacity = (value) => {
    if (canvas) {
      if (canvas.backgroundImage) {
        // Update the opacity of the background image if it exists
        canvas.backgroundImage.set("opacity", value);
      } else if (canvas.overlayImage) {
        // Update the opacity of the overlay image if it exists
        canvas.overlayImage.set("opacity", value);
      } else {
        console.error("No background or overlay image found on the canvas.");
        return;
      }

      // Re-render the canvas to apply changes
      canvas.renderAll();
    } else {
      console.error("Canvas is not initialized.");
    }
  };

  const removeBackgroundImage = () => {
    if (canvas) {
      canvas.backgroundImage = null;
      canvas.renderAll();
    }
    if (bgImgRef.current) {
      bgImgRef.current.value = "";
    }
  };

  const removeBackgroundOverlayImage = () => {
    if (canvas) {
      canvas.overlayImage = null;
      canvas.renderAll();
    }
  };

  const rndValue = {
    valueX: 0,
    valueY: 20,
    width: 250,
    height: 0,
    minWidth: 250,
    maxWidth: 300,
    minHeight: 0,
    maxHeight: 400,
    bound: "parent",
  };
  const content = () => {
    return (
      <Card className="xl:p-0 lg:p-0 md:p-0 p-2 border-none shadow-none">
        <CardTitle className="flex items-center flex-wrap justify-between gap-1 xl:hidden lg:hidden md:hidden">
          Canvas Setting{" "}
          <Button
            className="rnd-escape"
            variant="secondary"
            onClick={() => setOpenSetting(false)}
          >
            <X />
          </Button>{" "}
        </CardTitle>
        <Separator className="mt-4 block xl:hidden lg:hidden md:hidden" />
        <ScrollArea className="h-[400px] xl:h-fit lg:h-fit md:h-fit">
          <div className="rnd-escape">
            <ColorComponent />

            <Separator className="mt-2" />

            <div className="flex flex-col my-2 gap-2 rnd-escape">
              <div>
                <Label>Background:</Label>
                <div className="flex items-center w-fit gap-2 flex-wrap relative">
                  <Button className="top-0 absolute flex items-center w-[30px]">
                    <UploadIcon className="cursor-pointer" />
                    <Input
                      ref={bgImgRef}
                      className="absolute top-0 opacity-0"
                      type="file"
                      accept="image/*"
                      onChange={setBackgroundImage}
                    />
                  </Button>

                  <Button
                    variant="secondary"
                    className="ml-[35px]"
                    onClick={removeBackgroundImage}
                  >
                    <Trash2 />
                  </Button>
                </div>
              </div>

              <div>
                <Label>Background Overlay:</Label>
                <div className="flex items-center w-fit gap-2 flex-wrap relative">
                  <Button className="top-0 absolute flex items-center w-[30px]">
                    <UploadIcon className="cursor-pointer" />
                    <Input
                      className="absolute top-0 opacity-0"
                      type="file"
                      accept="image/*"
                      onChange={setBackgroundOverlayImage}
                    />
                  </Button>

                  <Button
                    variant="secondary"
                    className="ml-[35px]"
                    onClick={removeBackgroundOverlayImage}
                  >
                    <Trash2 />
                  </Button>
                </div>
              </div>

              {/* opacity */}
              <div className="flex flex-col gap-2 rnd-escape mt-2">
                <Label>Background Opacity:</Label>
                <Slider
                  defaultValue={[1.0]} // Default value, you can set it to 0.0 or another value
                  min={0.0}
                  max={1.0}
                  step={0.01} // Step size for fine control
                  onValueChange={(value) => {
                    const newOpacity = value[0]; // Extract slider value
                    adjustBackgroundOpacity(newOpacity); // Adjust Fabric.js background opacity
                  }}
                />
              </div>
            </div>

            <Separator className="mt-4" />

            {/* canvas size customization (width/height) */}
            <div className="flex gap-2 my-2">
              <div className="flex flex-col gap-2">
                <Label>Width:</Label>
                <Input
                  min={300}
                  type="number"
                  value={canvasSettings.width}
                  onChange={(e) => {
                    if (canvasWidth > parseInt(e.target.value)) {
                      handleChange("width", parseInt(e.target.value, 10));
                    }
                  }}
                />
              </div>

              <div className="flex flex-col gap-2">
                <Label>Height:</Label>
                <Input
                  min={300}
                  type="number"
                  value={canvasSettings.height}
                  onChange={(e) => {
                    if (canvasHeight > parseInt(e.target.value)) {
                      handleChange("height", parseInt(e.target.value, 10));
                    }
                  }}
                />
              </div>
            </div>
          </div>
        </ScrollArea>
      </Card>
    );
  };

  return screenWidth <= 768 ? (
    <RndComponent value={rndValue}>{content()}</RndComponent>
  ) : (
    <div>{content()}</div>
  );
};

export default CanvasSetting;
