import "../assets/styles/index.scss";
import { useAppLog, useWrapAsync } from "@paroicms/front-app-log";
import { showToast } from "@paroicms/internal-front-lib";
import { classNames } from "primereact/utils";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { FileDrop } from "./FileDrop";
import GalleryItem from "./GalleryItem/GalleryItem";
import ReorderMedias from "./ReorderMedias/ReorderMedias";
import UploadPlaceholder from "./UploadPlaceholder/UploadPlaceholder";
let uploadIdSeq = 0;
export function MediaGallery({ getMedias, deleteMedia, httpUploadMedia, className, reorderMedias, accept, acceptFilter, handle, direction = "row", onMediaAction, remainingMediaPlaces, updateMediaCount, isMobile, getMediaProperties, updateMediaAttachedData, contentLanguage, }) {
    const { t } = useTranslation();
    const appLog = useAppLog();
    const wrapAsync = useWrapAsync();
    const [medias, setMedias] = useState([]);
    const [uploadingFiles, setUploadingFiles] = useState([]);
    const [isDragging, setIsDragging] = useState(false);
    const setImageOnState = async () => {
        const medias = await getMedias(handle);
        setMedias(medias);
        updateMediaCount?.({ handle: handle, count: medias.length });
    };
    const handleDeleteMedia = async (mediaUid) => {
        await deleteMedia({ mediaUid, handle });
        await setImageOnState();
        showToast(t("TextDocumentEditScreen.mediaDeleted"), { severity: "info" });
    };
    const uploadSelectedFiles = (selectedFiles) => {
        const files = (acceptFilter ? selectedFiles.filter(acceptFilter) : selectedFiles).map((file) => ({
            uploadId: ++uploadIdSeq,
            file,
            handler: httpUploadMedia({ file, handle: handle }),
            progress: 0,
        }));
        for (const file of files) {
            const { handler } = file;
            handler.promise
                .catch(() => {
                showToast(t("TextDocumentEditScreen.uploadError", { fileName: file.file.name }), {
                    severity: "error",
                });
            })
                .then(() => onUploadEnd(file.uploadId))
                .catch((error) => appLog.error("[media-gallery]", error));
            handler.onProgress = (progress) => {
                file.progress = progress;
            };
        }
        setUploadingFiles([...uploadingFiles, ...files]);
    };
    const onUploadEnd = async (uploadId) => {
        await setImageOnState();
        setUploadingFiles((oldFiles) => oldFiles.filter((f) => f.uploadId !== uploadId));
    };
    const reorderMediasAndRefresh = async (payload) => {
        if (reorderMedias) {
            await reorderMedias({
                mediaUids: payload.map((item) => item.uid),
                handle,
            });
            await setImageOnState();
        }
    };
    const updateMediaCaption = async (mediaUid, caption) => {
        await updateMediaAttachedData(mediaUid, { caption });
        await setImageOnState();
    };
    useEffect(wrapAsync(setImageOnState), [handle]);
    function onDropFiles(files) {
        if (remainingMediaPlaces === 0) {
            showToast(t("frontMediaGallery.mediaLimitReached"), { severity: "warn" });
            return;
        }
        uploadSelectedFiles([...files]);
    }
    const galleryItems = (<>
      {medias.map((item) => (<GalleryItem isMobile={isMobile} key={item.uid} media={item} attachedData={item.attachedData} onDelete={() => handleDeleteMedia(item.uid)} onClick={onMediaAction ? () => onMediaAction(item) : undefined} getMediaProperties={getMediaProperties} updateCaption={updateMediaCaption} contentLanguage={contentLanguage}/>))}

      {uploadingFiles.map((item) => (<UploadPlaceholder key={item.uploadId} localMedia={item.file} handler={item.handler}/>))}
    </>);
    return (<FileDrop onDropFiles={onDropFiles} onDraggingChange={setIsDragging}>
      <div className={classNames("MediaGallery", direction, className)}>
        {medias.length > 1 && reorderMedias && (<ReorderMedias isMobile={isMobile} medias={medias} setOrdering={reorderMediasAndRefresh}/>)}
        <span className={classNames("MediaGallery-fileSelectorBtn", direction, {
            dragging: isDragging,
            mobile: !!isMobile,
        })}>
          {t("frontMediaGallery.chooseAFile")}
          <input className="MediaGallery-fileSelectorInput" type="file" name="files" accept={accept} multiple disabled={remainingMediaPlaces === 0} onChange={(ev) => ev.target.files && uploadSelectedFiles([...ev.target.files])}/>
        </span>
        {direction === "row" ? (galleryItems) : (<div className={classNames("Gallery", direction)}>{galleryItems}</div>)}
      </div>
    </FileDrop>);
}
