// Rôle : fournit l'outil images avec import, collage, libellés et annotation rapide.
import { useState } from "react";
import { Icon } from "../../../components/Icon.jsx";
import { usePointerReorder } from "../../../hooks/usePointerReorder.js";

export function ImagesModule({ toolboxId, moduleId, context, editing }) {
  const data = context.getModuleData(toolboxId, moduleId, { images: [] });
  const textContent = context.moduleText?.images || {};
  const [dragOver, setDragOver] = useState(false);
  const pastePlaceholder = textContent.pastePlaceholder || "Coller une image ici";
  const {
    draggingId: draggingImageId,
    dropTarget,
    startDrag
  } = usePointerReorder({
    targetSelector: "[data-image-id]",
    getTargetId: (target) => target.dataset.imageId,
    canDropOn: (target) => target.dataset.imageModuleId === moduleId,
    getPlacement: (event, target) => {
      const rect = target.getBoundingClientRect();
      return event.clientX > rect.left + rect.width / 2 ? "after" : "before";
    },
    onMove: (draggingId, targetId, placement) => {
      const nextImages = data.images.filter((image) => image.id !== draggingId);
      const targetIndex = nextImages.findIndex((image) => image.id === targetId);
      if (targetIndex === -1) return;
      nextImages.splice(placement === "after" ? targetIndex + 1 : targetIndex, 0, data.images.find((image) => image.id === draggingId));
      context.setModuleData(toolboxId, moduleId, { images: nextImages.filter(Boolean) });
    }
  });

  async function addFiles(files) {
    if (await context.addImageFiles(toolboxId, moduleId, files)) {
      setDragOver(false);
    }
  }

  function updateImage(imageId, patch) {
    context.setModuleData(toolboxId, moduleId, {
      images: data.images.map((image) => image.id === imageId ? { ...image, ...patch } : image)
    });
  }

  return (
    <>
      {editing && (
        <div className="module-add-panel">
          <label
            className={`dropzone ${dragOver ? "is-drag-over" : ""}`}
            onDragOver={(event) => {
              event.preventDefault();
              event.dataTransfer.dropEffect = "copy";
              setDragOver(true);
            }}
            onDragLeave={() => setDragOver(false)}
            onDrop={(event) => {
              event.preventDefault();
              addFiles(event.dataTransfer.files);
            }}
          >
            <input type="file" accept="image/*" multiple hidden onChange={(event) => addFiles(event.target.files)} />
            {textContent.addImages || "Ajouter des images"}
          </label>
          <div
            className="paste-target"
            contentEditable
            suppressContentEditableWarning
            role="textbox"
            aria-label={textContent.pasteAriaLabel || "Coller une image depuis le presse-papiers"}
            onFocus={(event) => {
              if (event.currentTarget.textContent.trim() === pastePlaceholder) event.currentTarget.textContent = "";
            }}
            onBlur={(event) => {
              if (!event.currentTarget.textContent.trim()) event.currentTarget.textContent = pastePlaceholder;
            }}
            onPaste={(event) => {
              const files = [...(event.clipboardData?.items || [])]
                .filter((item) => item.type.startsWith("image/"))
                .map((item) => item.getAsFile())
                .filter(Boolean);
              if (!files.length) return;
              event.preventDefault();
              event.currentTarget.textContent = pastePlaceholder;
              addFiles(files);
            }}
          >
            {pastePlaceholder}
          </div>
        </div>
      )}
      <div className="images">
        {data.images.map((image) => {
          const isDragging = draggingImageId === image.id;
          const isDropTarget = dropTarget.id === image.id;
          const className = [
            isDragging ? "is-dragging" : "",
            isDropTarget ? "is-drop-target" : "",
            isDropTarget && dropTarget.placement === "after" ? "drop-after" : ""
          ].filter(Boolean).join(" ");

          return (
            <figure key={image.id} className={className} data-image-id={image.id} data-image-module-id={moduleId}>
              <button
                className="image-drag-handle"
                type="button"
                onPointerDown={(event) => startDrag(event, image.id)}
                aria-label={textContent.reorderAriaLabel || "Déplacer l'image"}
                title={textContent.reorderTitle || "Déplacer"}
              >
                <Icon name="drag" />
              </button>
              <button className="image-preview" onClick={() => context.setImage(image)} aria-label={textContent.previewAriaLabel || "Agrandir l'image"}>
                <img src={image.dataUrl} alt={textContent.imageAlt || "Image"} />
              </button>
              {editing ? (
                <input
                  className="image-label-input"
                  value={image.label || ""}
                  placeholder={textContent.labelPlaceholder || "Libellé de l'image"}
                  onChange={(event) => updateImage(image.id, { label: event.target.value })}
                  aria-label={textContent.labelAriaLabel || "Libellé de l'image"}
                />
              ) : image.label ? (
                <figcaption className="image-label">{image.label}</figcaption>
              ) : null}
              <div className="image-actions">
                <button
                  className="image-annotate-button"
                  type="button"
                  onClick={() => context.createImageAnnotationModule?.(image.dataUrl)}
                  aria-label={textContent.annotateAriaLabel || "Annoter l'image"}
                  title={textContent.annotateTitle || "Annoter"}
                >
                  <Icon name="map" />
                </button>
                <button className="image-delete-button danger" type="button" onClick={() => {
                  context.setModuleData(toolboxId, moduleId, { images: data.images.filter((item) => item.id !== image.id) });
                }} aria-label={textContent.deleteAriaLabel || "Supprimer l'image"} title={textContent.deleteTitle || "Supprimer"}>
                  <Icon name="trash" />
                </button>
              </div>
            </figure>
          );
        })}
      </div>
    </>
  );
}
