import { type FC, useState } from "react";
import { Trash } from "iconsax-react";
import UploadBoxDraggble from "@/components/UploadBoxDraggble";
import { useEditorStore } from "@/pages/editor/store/editorStore";
import { useSingleUpload } from "@/pages/uploader/hooks/useUploaderData";
import { createScopedId } from "@/pages/editor/store/editorStore.helpers";
import { GALLERY_DRAG_MIME } from "@/pages/editor/types/GalleryTypes";

const ImageGallery: FC = () => {
    const { gallery, addGalleryItem, removeGalleryItem } = useEditorStore();
    const { mutateAsync: uploadFile } = useSingleUpload();
    const [isUploading, setIsUploading] = useState(false);
    const [uploadProgress, setUploadProgress] = useState(0);

    const handleFileChange = async (files: File[]) => {
        if (files.length === 0) return;

        setIsUploading(true);
        setUploadProgress(0);
        try {
            for (let i = 0; i < files.length; i++) {
                const file = files[i];
                const result = await uploadFile({
                    file,
                    onProgress: (fileProgress) => {
                        const overall = Math.round(((i + fileProgress / 100) / files.length) * 100);
                        setUploadProgress(overall);
                    },
                });
                const imageUrl = result?.data?.url;
                if (!imageUrl) continue;

                const dimensions = await loadImageDimensions(imageUrl);
                addGalleryItem({
                    id: createScopedId("gallery"),
                    url: imageUrl,
                    width: dimensions.width,
                    height: dimensions.height,
                });
            }
        } catch {
            // TODO: show error toast
        } finally {
            setIsUploading(false);
            setUploadProgress(0);
        }
    };

    const handleDragStart = (e: React.DragEvent<HTMLImageElement>, url: string) => {
        e.dataTransfer.setData(GALLERY_DRAG_MIME, url);
        e.dataTransfer.effectAllowed = "copy";
    };

    return (
        <div className="space-y-3">
            <div className="text-base font-bold">گالری</div>
            <p className="text-sm text-gray-600">
                تصویر را آپلود کنید، سپس از گالری بکشید و روی صفحه رها کنید
            </p>

            <UploadBoxDraggble
                label="تصویر مورد نظر را آپلود کنید"
                onChange={handleFileChange}
                isMultiple={true}
                hidePreview
                isLoading={isUploading}
                uploadProgress={isUploading ? uploadProgress : undefined}
            />

            {gallery.length === 0 && !isUploading && (
                <p className="text-sm text-gray-500">گالری خالی است</p>
            )}

            {gallery.length > 0 && (
                <div className="grid grid-cols-3 gap-2 max-h-[320px] overflow-y-auto">
                    {gallery.map((item) => (
                        <div
                            key={item.id}
                            className="group relative flex aspect-square items-center justify-center rounded-lg border border-gray-200 bg-gray-50 p-1 hover:border-blue-300 hover:bg-blue-50 transition-colors"
                        >
                            <img
                                src={item.url}
                                alt=""
                                draggable
                                onDragStart={(e) => handleDragStart(e, item.url)}
                                className="max-h-full max-w-full object-contain cursor-grab active:cursor-grabbing"
                            />
                            <button
                                type="button"
                                onClick={() => removeGalleryItem(item.id)}
                                className="absolute -left-1 -top-1 hidden size-5 items-center justify-center rounded-full bg-white shadow group-hover:flex"
                                title="حذف از گالری"
                            >
                                <Trash size={12} color="#ef4444" variant="Bold" />
                            </button>
                        </div>
                    ))}
                </div>
            )}
        </div>
    );
};

const loadImageDimensions = (url: string): Promise<{ width: number; height: number }> =>
    new Promise((resolve) => {
        const img = new Image();
        img.onload = () => {
            resolve({ width: img.naturalWidth, height: img.naturalHeight });
        };
        img.onerror = () => {
            resolve({ width: 100, height: 100 });
        };
        img.src = url;
    });

export default ImageGallery;
