import React, { useEffect, useRef, useState } from "react";
import "./Product_details_swiper.css";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faChevronLeft,
  faChevronRight,
  faHeart as solidHeart,
} from "@fortawesome/free-solid-svg-icons";
import Best_seller_heart from "../../common-components/product_card/Best_seller_heart/Best_seller_heart";
import "react-medium-image-zoom/dist/styles.css";

function Product_details_swiper({ product, activeMetal }) {
  const [activeImage, setActiveImage] = useState("");

  const colourImages =
    activeMetal?.Product_Images?.length > 0
      ? activeMetal.Product_Images
      : product?.Product_Images || [];

  useEffect(() => {
    if (colourImages.length > 0) {
      setActiveImage(colourImages[0].image);
    } else if (product?.image) {
      setActiveImage(product.image);
    }
  }, [activeMetal, product]);

  class Zoomable {
    constructor(element, config) {
      this.element = element;
      this.config = this._mergeConfig(config);

      const { initialZoom, minZoom, maxZoom } = this.config;

      this.zoomed = false;
      this.initialZoom = Math.max(Math.min(initialZoom, maxZoom), minZoom);
      this.zoom = this.initialZoom;

      this.img = element.querySelector(".zoomable__img");
      this.img.draggable = false;
      this.element.style.setProperty("--zoom", this.initialZoom);

      this._addEventListeners();
    }

    static get Default() {
      return Default;
    }

    _addEventListeners() {
      this.element.addEventListener("mouseenter", () =>
        this._handleMouseover(),
      );
      this.element.addEventListener("mousemove", (evt) =>
        this._handleMousemove(evt),
      );
      this.element.addEventListener("mouseleave", () => this._handleMouseout());
      this.element.addEventListener("wheel", (evt) => this._handleWheel(evt));
    }

    _handleMouseover() {
      if (this.zoomed) {
        return;
      }

      this.element.classList.add("zoomable--zoomed");
      this.zoomed = true;
    }

    _handleMousemove(evt) {
      if (!this.zoomed) {
        return;
      }

      const elPos = this.element.getBoundingClientRect();
      const percentageX = `${
        ((evt.clientX - elPos.left) * 100) / elPos.width
      }%`;
      const percentageY = `${
        ((evt.clientY - elPos.top) * 100) / elPos.height
      }%`;

      this.element.style.setProperty("--zoom-pos-x", percentageX);
      this.element.style.setProperty("--zoom-pos-y", percentageY);
    }

    _handleMouseout() {
      if (!this.zoomed) {
        return;
      }

      this.element.style.setProperty("--zoom", this.initialZoom);
      this.element.classList.remove("zoomable--zoomed");
      this.zoomed = false;
    }

    _handleWheel(evt) {
      if (!this.zoomed) {
        return;
      }

      evt.preventDefault();

      const newZoom = this.zoom + evt.deltaY * (this.config.zoomSpeed * -1);
      const { minZoom, maxZoom } = this.config;

      this.zoom = Math.max(Math.min(newZoom, maxZoom), minZoom);
      this.element.style.setProperty("--zoom", this.zoom);
    }

    _mergeConfig(config) {
      return {
        ...this.constructor.Default,
        ...(typeof config === "object" ? config : {}),
      };
    }
  }

  const Default = {
    initialZoom: 3,
    minZoom: 1.25,
    maxZoom: 4,
    zoomSpeed: 0.01,
  };

  const zoomableRef = useRef(null);

  useEffect(() => {
    const element = zoomableRef.current;
    if (!element) return;

    const zoomable = new Zoomable(element);

    return () => {
      element.removeEventListener("mouseenter", zoomable._handleMouseover);
      element.removeEventListener("mousemove", zoomable._handleMousemove);
      element.removeEventListener("mouseleave", zoomable._handleMouseout);
      element.removeEventListener("wheel", zoomable._handleWheel);
    };
  }, []);


  const handlePreviousImage = () => {
    if (!colourImages.length) return;

    const currentIndex = colourImages.findIndex(
      (item) => item.image === activeImage,
    );

    const previousIndex =
      currentIndex <= 0 ? colourImages.length - 1 : currentIndex - 1;

    setActiveImage(colourImages[previousIndex].image);
  };

  const handleNextImage = () => {
    if (!colourImages.length) return;

    const currentIndex = colourImages.findIndex(
      (item) => item.image === activeImage,
    );

    const nextIndex =
      currentIndex === colourImages.length - 1 ? 0 : currentIndex + 1;

    setActiveImage(colourImages[nextIndex].image);
  };

  return (
    <>
      <section className="Product_details_swiper">
        <div className="main_img_holder">
          <div className="img_holder" ref={zoomableRef}>
            <img
              className="Product_img zoomable__img"
              src={process.env.NEXT_PUBLIC_IMG_URL + activeImage}
              alt=""
            />
          </div>

          <button
            type="button"
            className="product_main_prev"
            onClick={handlePreviousImage}
          >
            <FontAwesomeIcon icon={faChevronLeft} />
          </button>

          <button
            type="button"
            className="product_main_next"
            onClick={handleNextImage}
          >
            <FontAwesomeIcon icon={faChevronRight} />
          </button>

          <div className="wishlist_div wishlist_swiper_div">
            <Best_seller_heart product={product} />
          </div>
        </div>

        <div className="swiper_holder">
          <Swiper
            slidesPerView={5}
            spaceBetween={10}
            className="Product_details_Swiper_holder"
          >
            {colourImages.map((val) => (
              <SwiperSlide
                key={val.id}
                onClick={() => setActiveImage(val.image)}
              >
                <div
                  className={`img_holder ${
                    activeImage === val.image ? "active_thumb" : ""
                  }`}
                >
                  <img
                    className="Product_img"
                    src={process.env.NEXT_PUBLIC_IMG_URL + val?.image}
                  />
                </div>
              </SwiperSlide>
            ))}
          </Swiper>
        </div>
      </section>
    </>
  );
}

export default Product_details_swiper;
