import { useState, useCallback, useRef } from "react";

/**
 * Koenig expects `fileUploader.useFileUpload(type)` — a React hook it
 * calls internally for each card type ("image", "audio", "file", etc.).
 *
 * `makeFileUploader(csrfToken, uploadUrls)` returns the object Koenig wants:
 *   { useFileUpload: (type) => { upload, progress, isLoading, errors, filesNumber } }
 *
 * `uploadUrls` is an object: { image, media, file }
 * For backwards compat, a plain string is treated as the image URL.
 */

const URL_KEY_MAP = {
  image:          { urlKey: "image", responseKey: "images" },
  audio:          { urlKey: "media", responseKey: "media" },
  video:          { urlKey: "media", responseKey: "media" },
  mediaThumbnail: { urlKey: "image", responseKey: "images" },
  file:           { urlKey: "file",  responseKey: "files" },
};

export default function makeFileUploader(csrfToken, uploadUrls) {
  // Normalise: string → object with all keys pointing to same URL
  const urls =
    typeof uploadUrls === "string"
      ? { image: uploadUrls, media: uploadUrls, file: uploadUrls }
      : uploadUrls || {};

  return {
    fileTypes: {
      image: { mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'] },
      audio: { mimeTypes: ['audio/mpeg', 'audio/ogg', 'audio/wav', 'audio/mp4', 'audio/aac'] },
      video: { mimeTypes: ['video/mp4', 'video/webm', 'video/ogg'] },
      mediaThumbnail: { mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] },
      file: { mimeTypes: [] },
    },
    useFileUpload(type) {
      const mapping = URL_KEY_MAP[type] || URL_KEY_MAP.image;
      const [progress, setProgress] = useState(0);
      const [isLoading, setIsLoading] = useState(false);
      const [errors, setErrors] = useState([]);
      const [filesNumber, setFilesNumber] = useState(0);
      const csrfRef = useRef(csrfToken);
      const urlRef = useRef(urls[mapping.urlKey] || urls.image || "/editor-api/images/upload/");
      const responseKeyRef = useRef(mapping.responseKey);

      const upload = useCallback(async (files) => {
        const fileList = Array.from(files);
        setFilesNumber(fileList.length);
        setIsLoading(true);
        setErrors([]);
        setProgress(0);

        const results = [];
        for (let i = 0; i < fileList.length; i++) {
          const file = fileList[i];
          const formData = new FormData();
          formData.append("file", file);

          try {
            const resp = await fetch(urlRef.current, {
              method: "POST",
              body: formData,
              headers: {
                "X-CSRFToken": csrfRef.current || "",
              },
            });
            if (!resp.ok) {
              const err = await resp.json().catch(() => ({}));
              const msg =
                err.errors?.[0]?.message || `Upload failed (${resp.status})`;
              setErrors((prev) => [
                ...prev,
                { message: msg, fileName: file.name },
              ]);
              continue;
            }
            const data = await resp.json();
            const fileUrl = data[responseKeyRef.current]?.[0]?.url;
            if (fileUrl) {
              results.push({ url: fileUrl, fileName: file.name });
            }
          } catch (e) {
            setErrors((prev) => [
              ...prev,
              { message: e.message, fileName: file.name },
            ]);
          }
          setProgress(Math.round(((i + 1) / fileList.length) * 100));
        }

        setIsLoading(false);
        return results;
      }, []);

      return { upload, progress, isLoading, errors, filesNumber };
    },
  };
}
