import axios from "axios";
import { Result } from "antd";
import * as markerjs2 from "markerjs2";
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import { handleUpload } from "../documents-local-upload/documents-local-upload.utility";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";

const mapStateToProps = createStructuredSelector({
  currentUser: selectCurrentUser,
  bodyshop: selectBodyshop
});
const mapDispatchToProps = () => ({});

export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
  const imgRef = useRef(null);
  const [loading, setLoading] = useState(false);
  const [uploaded, setuploaded] = useState(false);
  const [loadedImageUrl, setLoadedImageUrl] = useState(null);
  const [imageLoaded, setImageLoaded] = useState(false);
  const [imageLoading, setImageLoading] = useState(true);
  const markerArea = useRef(null);
  const { t } = useTranslation();
  const notification = useNotification();
  const [uploading, setUploading] = useState(false);

  const triggerUpload = useCallback(
    async (dataUrl) => {
      if (uploading) return;
      setUploading(true);
      const blob = await b64toBlob(dataUrl);
      const nameWithoutExt = filename.split(".").slice(0, -1).join(".").trim();
      const parts = nameWithoutExt.split("-");
      const baseParts = [];
      for (let i = 0; i < parts.length; i++) {
        if (/^\d+$/.test(parts[i])) {
          break;
        }
        baseParts.push(parts[i]);
      }
      const adjustedBase = baseParts.length > 0 ? baseParts.join("-") : "edited";
      const adjustedFilename = `${adjustedBase}.jpg`;
      const file = new File([blob], adjustedFilename, { type: "image/jpeg" });

      handleUpload({
        ev: {
          file: file,
          filename: adjustedFilename,
          onSuccess: () => {
            setUploading(false);
            setLoading(false);
            setuploaded(true);
          },
          onError: () => {
            setUploading(false);
            setLoading(false);
          }
        },
        context: {
          jobid: jobid,
          callback: () => {} // Optional callback
        },
        notification
      });
    },
    [filename, jobid, notification, uploading]
  );

  useEffect(() => {
    if (imgRef.current !== null && imageLoaded && !markerArea.current) {
      // create a marker.js MarkerArea
      markerArea.current = new markerjs2.MarkerArea(imgRef.current);

      // attach an event handler to assign annotated image back to our image element
      markerArea.current.addEventListener("close", () => {
        // NO OP
      });

      markerArea.current.addEventListener("render", (event) => {
        const dataUrl = event.dataUrl;
        imgRef.current.src = dataUrl;
        markerArea.current.close();
        triggerUpload(dataUrl);
      });
      // launch marker.js

      markerArea.current.renderAtNaturalSize = true;
      markerArea.current.renderImageType = "image/jpeg";
      markerArea.current.renderImageQuality = 1;
      //markerArea.current.settings.displayMode = "inline";
      markerArea.current.show();
    }
  }, [triggerUpload, imageLoaded]);

  useEffect(() => {
    // Load the image from imageUrl
    let isCancelled = false;

    const loadImage = async () => {
      if (!imageUrl) return;

      setImageLoaded(false);
      setImageLoading(true);

      try {
        const response = await axios.get(imageUrl, { responseType: "blob" });

        if (isCancelled) return;

        const blobUrl = URL.createObjectURL(response.data);
        setLoadedImageUrl((prevUrl) => {
          if (prevUrl) URL.revokeObjectURL(prevUrl);
          return blobUrl;
        });
      } catch (error) {
        console.error("Failed to fetch image blob", error);
      } finally {
        if (!isCancelled) {
          setImageLoading(false);
        }
      }
    };

    loadImage();

    return () => {
      isCancelled = true;
    };
  }, [imageUrl]);

  async function b64toBlob(url) {
    const res = await fetch(url);
    return await res.blob();
  }

  return (
    <div>
      {!loading && !uploaded && loadedImageUrl && (
        <img
          ref={imgRef}
          src={loadedImageUrl}
          alt="sample"
          onLoad={() => setImageLoaded(true)}
          onError={(error) => {
            console.error("Failed to load image", error);
          }}
          style={{ maxWidth: "90vw", maxHeight: "90vh" }}
        />
      )}
      {(loading || imageLoading || !imageLoaded) && !uploaded && (
        <LoadingSpinner message={t("documents.labels.uploading")} />
      )}
      {uploaded && <Result status="success" title={t("documents.successes.edituploaded")} />}
    </div>
  );
}

export default connect(mapStateToProps, mapDispatchToProps)(DocumentEditorLocalComponent);
