import { useContext, useEffect, useState } from "react";
import CanvasContext from "./Context/canvasContext/CanvasContext";
import { Card, CardTitle } from "./ui/card";
import { Button } from "./ui/button";
import { Trash2, UploadIcon } 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 { ScrollArea } from "./ui/scroll-area";
import { useNavigate, useParams } from "react-router-dom";
import { useToast } from "../hooks/use-toast";
import { useMutation } from "@tanstack/react-query";
import { deleteImage, uploadImage } from "../api/uploadApi";
import { createProject } from "../api/projectApi";
import SaveCanvas from "./SaveCanvas";

const CanvasSetting = () => {
  const { canvas } = useContext(CanvasContext);
  const params = useParams();
  const { id } = params;
  const { toast } = useToast();
  const navigate = useNavigate();
  const [bgImage, setBgImage] = useState(null);
  const [bgOverLayImage, setBgOverLayImage] = useState(null);

  // create empty project if no id is provided
  useEffect(() => {
    const createEmptyProject = async () => {
      try {
        const response = await createProject();
        if (response?.status === 200) {
          toast({
            title: response?.status,
            description: response?.message
          })
        }
        if (response?.data?.id) {
          navigate(`/${response.data.id}`);
        }
      } catch (error) {
        console.error("Project creation failed:", error);
      }
    };
    if (!id) {
      createEmptyProject();
    }
  }, [id, navigate, toast]);

  // upload bg-image handler
  const { mutate: uploadBackgroundImage } = useMutation({
    mutationFn: async ({ file, id }) => {
      return await uploadImage({ file, id });
    },
    onSuccess: (data) => {
      if (data?.status === 200) {
        toast({
          title: data?.status,
          description: data?.message
        });
        setBgImage(data?.data[0]?.url);

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

        // Set the crossOrigin attribute BEFORE setting the src
        imgElement.crossOrigin = "anonymous"; // This ensures CORS headers are sent
        imgElement.src = data?.data[0]?.url;

        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));
        };

        imgElement.onerror = (error) => {
          console.error('Failed to load image:', error);
          toast({
            variant: "destructive",
            title: "Image Load Error",
            description: "Failed to load the image. Please try again."
          })
        };
      }
      else {
        toast({
          variant: "destructive",
          title: data?.status,
          description: data?.message
        });
      }
    }
  })

  // handle bg-image remove
  const { mutate: removeBackgroundMutate } = useMutation({
    mutationFn: async (url) => {
      return await deleteImage(url);
    },
    onSuccess: (data) => {
      if (data?.status === 200) {
        toast({
          title: data?.status,
          description: data?.message
        })
        canvas.backgroundImage = null;
        canvas.renderAll();
        setBgImage(null);
      }
      else {
        toast({
          variant: "destructive",
          title: data?.status,
          description: data?.message
        })
      }
    }
  });

  // upload bg-overLayImage handler
  const { mutate: uploadOverlayImage } = useMutation({
    mutationFn: async ({ file, id }) => {
      return await uploadImage({ file, id });
    },
    onSuccess: (data) => {
      if (data?.status === 200) {
        toast({
          title: data?.status,
          description: data?.message
        });
        setBgOverLayImage(data?.data[0]?.url);
        // Create an image element
        const imgElement = new Image();

        // Set the crossOrigin attribute BEFORE setting the src
        imgElement.crossOrigin = "anonymous"; // This ensures CORS headers are sent
        imgElement.src = data?.data[0]?.url;

        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.setOverlayImage(img, canvas.renderAll.bind(canvas));
        };

        imgElement.onerror = (error) => {
          console.error('Failed to load image:', error);
          toast({
            variant: "destructive",
            title: "Image Load Error",
            description: "Failed to load the image. Please try again."
          })
        };

      }
      else {
        toast({
          variant: "destructive",
          title: data?.status,
          description: data?.message
        });
      }
    }
  })

  // handle bg-overLayImage remove
  const { mutate: removeOverLayMutate } = useMutation({
    mutationFn: async (url) => {
      return await deleteImage(url);
    },
    onSuccess: (data) => {
      if (data?.status === 200) {
        toast({
          title: data?.status,
          description: data?.message
        })
        canvas.overlayImage = null;
        canvas.renderAll();
        setBgOverLayImage(null);
      }
      else {
        toast({
          variant: "destructive",
          title: data?.status,
          description: data?.message
        })
      }
    }
  });

  const setBackgroundImage = (e) => {
    const file = e.target.files[0];
    if (file) {
      uploadBackgroundImage({ file, id })
    }
    else {
      toast({
        variant: "destructive",
        title: "Error",
        description: "Please select a file",
      })
    }
  };

  const setBackgroundOverlayImage = (e) => {
    const file = e.target.files[0];
    if (file) {
      uploadOverlayImage({ file, id })
    }
    else {
      toast({
        variant: "destructive",
        title: "Error",
        description: "Please select a file",
      })
    }
  };

  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) {
      const bgUrl = canvas.backgroundImage?.getSrc();
      console.log("background image from remove", bgUrl)
      if (bgUrl) {
        removeBackgroundMutate(bgUrl)
      }
      else {
        toast({
          variant: "destructive",
          title: "Error",
          description: "No background image found",
        })
      }
    }
  };

  const removeBackgroundOverlayImage = () => {
    if (canvas) {
      const overLayUrl = canvas.overlayImage?.getSrc();
      console.log("overlay image from remove", overLayUrl);
      if (overLayUrl) {
        removeOverLayMutate(overLayUrl);
      }
      else {
        toast({
          variant: "destructive",
          title: "Error",
          description: "No overlay image found",
        })
      }
    }
  };

  useEffect(() => {
    if (canvas) {
      const bgUrl = canvas.backgroundImage?.getSrc();
      setBgImage(bgUrl);
      const overLayUrl = canvas.overlayImage?.getSrc();
      setBgOverLayImage(overLayUrl);
    }
  }, [canvas, setBgImage, setBgOverLayImage])

  return (
    <div>
      <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
        </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>
                {
                  bgImage && <img src={bgImage} alt="canvas_bg_image" className="rounded-md mb-2" />
                }
                <div className="flex items-center w-fit gap-2 flex-wrap relative">
                  {
                    !bgImage &&
                    <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={setBackgroundImage}
                      />
                    </Button>
                  }

                  {
                    bgImage &&
                    <Button
                      variant="secondary"
                      onClick={removeBackgroundImage}
                    >
                      <Trash2 />
                    </Button>
                  }
                </div>

              </div>

              {
                bgImage ? <Separator className="mt-4" /> : <Separator className="mt-12" />
              }

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

                  {
                    bgOverLayImage &&
                    <Button
                      variant="secondary"
                      onClick={removeBackgroundOverlayImage}
                    >
                      <Trash2 />
                    </Button>
                  }
                </div>

              </div>
              {
                bgOverLayImage ? <Separator className="mt-4" /> : <Separator className="mt-12" />
              }

              {/* 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" />

            {/* Save canvas Component */}
            {
              id &&
              <SaveCanvas />
            }

          </div>
        </ScrollArea>
      </Card>
    </div>
  );
};

export default CanvasSetting;
