﻿import React, { useState, ChangeEvent, useRef, useEffect } from "react";

/** Extensiones y tipos MIME aceptados (alineado con create/update en API). */
const ALLOWED_IMAGE_EXTENSIONS = new Set(["jpg", "jpeg", "png", "webp"]);
const ALLOWED_IMAGE_MIMES = new Set([
  "image/jpeg",
  "image/jpg",
  "image/png",
  "image/webp",
]);

function isAllowedImageFile(file: File): boolean {
  const ext = file.name.split(".").pop()?.toLowerCase() ?? "";
  if (ALLOWED_IMAGE_EXTENSIONS.has(ext)) {
    return true;
  }
  if (file.type && ALLOWED_IMAGE_MIMES.has(file.type.toLowerCase())) {
    return true;
  }
  return false;
}

export type ImageItem =
  | { type: "url"; src: string }
  | { type: "file"; src: string; file: File };

type InputImageProps = {
  register: any;
  initialImages?: string[];
  onImagesChange?: (currentImages: string[]) => void;
  onFilesChange?: (files: File[]) => void;
  /** Orden completo: primero existentes (url), luego nuevos (file), en el orden mostrado */
  onOrderedChange?: (items: ImageItem[]) => void;
};

export const InputImage: React.FC<InputImageProps> = ({
  register,
  initialImages,
  onImagesChange,
  onFilesChange,
  onOrderedChange,
}) => {
  const [items, setItems] = useState<ImageItem[]>([]);
  const inputRef = useRef<HTMLInputElement | null>(null);

  const { ref, ...registerProps } = register("imageUrl");

  useEffect(() => {
    if (initialImages && initialImages.length > 0) {
      setItems(initialImages.map((src) => ({ type: "url" as const, src })));
    } else {
      setItems([]);
    }
  }, [initialImages]);

  const syncToParent = (nextItems: ImageItem[]) => {
    const urls = nextItems.filter((i): i is ImageItem & { type: "url" } => i.type === "url").map((i) => i.src);
    const files = nextItems.filter((i): i is ImageItem & { type: "file" } => i.type === "file").map((i) => i.file);
    onImagesChange?.(urls);
    onFilesChange?.(files);
    onOrderedChange?.(nextItems);
  };

  const handleFileChange = (e: ChangeEvent<HTMLInputElement> | FileList) => {
    const incomingFiles = "target" in e ? e.target.files : e;
    if (!incomingFiles) return;

    const spaceAvailable = 4 - items.length;
    if (spaceAvailable <= 0) {
      alert("Ya has alcanzado el límite de 4 imágenes");
      return;
    }

    const fileArray = Array.from(incomingFiles)
      .filter((file) => {
        if (isAllowedImageFile(file)) {
          return true;
        }
        alert(
          `Formato no permitido: "${file.name}". Usa JPG, JPEG, PNG o WEBP.`
        );
        return false;
      })
      .slice(0, spaceAvailable);
    if (fileArray.length === 0) {
      if (inputRef.current) inputRef.current.value = "";
      return;
    }
    const newItems: ImageItem[] = fileArray.map((file) => ({
      type: "file",
      src: URL.createObjectURL(file),
      file,
    }));
    const nextItems = [...items, ...newItems];
    setItems(nextItems);
    syncToParent(nextItems);

    if (inputRef.current) inputRef.current.value = "";
  };

  const removeImage = (index: number) => {
    const item = items[index];
    if (item.type === "file" && item.src.startsWith("blob:")) {
      URL.revokeObjectURL(item.src);
    }
    const nextItems = items.filter((_, i) => i !== index);
    setItems(nextItems);
    syncToParent(nextItems);
  };

  const moveUp = (index: number) => {
    if (index <= 0) return;
    const next = [...items];
    [next[index - 1], next[index]] = [next[index], next[index - 1]];
    setItems(next);
    syncToParent(next);
  };

  const moveDown = (index: number) => {
    if (index >= items.length - 1) return;
    const next = [...items];
    [next[index], next[index + 1]] = [next[index + 1], next[index]];
    setItems(next);
    syncToParent(next);
  };

  return (
    <div className="form-group">
      <label style={{ display: "block", marginBottom: "8px", fontWeight: "bold" }}>
        Imágenes (mínimo 1, máximo 4) — puedes cambiar el orden con las flechas
      </label>

      <label
        htmlFor="file-upload"
        onDragOver={(e) => {
          e.preventDefault();
          e.currentTarget.style.borderColor = "#007bff";
        }}
        onDragLeave={(e) => {
          e.preventDefault();
          e.currentTarget.style.borderColor = "#ccc";
        }}
        onDrop={(e) => {
          e.preventDefault();
          const files = e.dataTransfer.files;
          if (files.length > 0) handleFileChange(files);
        }}
        style={{
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          justifyContent: "center",
          width: "100%",
          height: "180px",
          border: "2px dashed #ccc",
          borderRadius: "10px",
          cursor: "pointer",
          backgroundColor: "#f8f9fa",
          transition: "all 0.3s ease",
        }}
      >
        <div style={{ textAlign: "center", color: "#6c757d", pointerEvents: "none" }}>
          <i className="fas fa-images" style={{ fontSize: "40px", marginBottom: "10px" }} />
          <p style={{ margin: 0 }}>
            <strong>Arrastra</strong> o selecciona imágenes
          </p>
        </div>

        <input
          {...registerProps}
          id="file-upload"
          type="file"
          multiple
          accept=".jpg,.jpeg,.png,.webp,image/jpeg,image/png,image/webp"
          style={{ display: "none" }}
          ref={(e) => {
            ref(e);
            inputRef.current = e;
          }}
          onChange={(e) => {
            registerProps.onChange?.(e);
            handleFileChange(e);
          }}
        />
      </label>

      <p className="small text-muted mb-0 mt-2" style={{ lineHeight: 1.45 }}>
        Formatos: JPG, JPEG, PNG o WEBP. Medidas recomendadas: 800 x 800 px
        (proporción 1:1).
      </p>

      <div
        style={{
          display: "flex",
          gap: "12px",
          marginTop: "15px",
          flexWrap: "wrap",
          alignItems: "flex-start",
        }}
      >
        {items.map((item, index) => (
          <div
            key={item.type === "file" ? item.src : item.src}
            style={{
              width: "80px",
              position: "relative",
              display: "flex",
              flexDirection: "column",
              alignItems: "center",
            }}
          >
            <div style={{ display: "flex", alignItems: "center", gap: "4px", marginBottom: "4px" }}>
              <button
                type="button"
                onClick={() => moveUp(index)}
                disabled={index === 0}
                className="btn btn-sm btn-outline-secondary"
                title="Subir"
                style={{ padding: "2px 6px", minWidth: "28px" }}
              >
                <i className="fas fa-chevron-up" />
              </button>
              <span className="text-muted small">{index + 1}</span>
              <button
                type="button"
                onClick={() => moveDown(index)}
                disabled={index === items.length - 1}
                className="btn btn-sm btn-outline-secondary"
                title="Bajar"
                style={{ padding: "2px 6px", minWidth: "28px" }}
              >
                <i className="fas fa-chevron-down" />
              </button>
            </div>
            <div style={{ width: "65px", height: "65px", position: "relative" }}>
              <button
                type="button"
                onClick={() => removeImage(index)}
                style={{
                  position: "absolute",
                  top: "-5px",
                  right: "-5px",
                  backgroundColor: "#dc3545",
                  color: "white",
                  border: "none",
                  borderRadius: "50%",
                  width: "20px",
                  height: "20px",
                  fontSize: "12px",
                  cursor: "pointer",
                  zIndex: 10,
                }}
              >
                &times;
              </button>
              <img
                src={item.src}
                alt={`Preview ${index + 1}`}
                style={{
                  width: "100%",
                  height: "100%",
                  objectFit: "cover",
                  borderRadius: "6px",
                  border: "1px solid #ddd",
                }}
              />
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};
