import React, { useRef, useEffect, useState } from 'react';
import Image from 'next/image';
import { useDrag, useDrop } from 'react-dnd';
import { coloredToast } from '@/lib/toast';

interface CustomWindow extends Window {
    cloudinary: any;
}

declare let window: CustomWindow;

interface ImageFormProps {
    images: string[];
    setImages: React.Dispatch<React.SetStateAction<string[]>>;
}

const ML_WAIT_TIMEOUT_MS = 8000;
const ML_POLL_INTERVAL_MS = 100;

const ImageForm: React.FC<ImageFormProps> = ({ images, setImages }) => {
    const totalImages = 6;

    const [isUploading, setIsUploading] = useState(false);
    const [itemUploadId, setItemUploadId] = useState(-1);
    const itemUploadIdRef = useRef(itemUploadId);
    const mlRef = useRef<any>(null);
    const waitTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
    const handlersRef = useRef({
        show: () => { },
        hide: () => { },
        insert: (_res: any) => { },
    });

    const [ml, setMl] = useState<any>(null);

    const config = {
        cloud_name: 'aurumlab',
        api_key: '637983323526145',
        folder: { path: 'aurumlab/product/images' },
    };

    const clearWaitTimer = () => {
        if (waitTimerRef.current) {
            clearInterval(waitTimerRef.current);
            waitTimerRef.current = null;
        }
    };

    const resetUploadState = () => {
        setIsUploading(false);
        itemUploadIdRef.current = -1;
        setItemUploadId(-1);
    };

    const ensureMediaLibrary = () => {
        if (mlRef.current) return mlRef.current;
        if (typeof window.cloudinary === 'undefined') return null;

        const mlInstance = window.cloudinary.createMediaLibrary(config, {
            insertHandler: (res: any) => handlersRef.current.insert(res),
            showHandler: () => handlersRef.current.show(),
            hideHandler: () => handlersRef.current.hide(),
        });

        mlRef.current = mlInstance;
        setMl(mlInstance);
        return mlInstance;
    };

    const openMediaLibrary = () => {
        const instance = ensureMediaLibrary();
        if (!instance) return false;
        clearWaitTimer();
        instance.show();
        return true;
    };

    const handleUploadClick = (id: number) => {
        itemUploadIdRef.current = id;
        setItemUploadId(id);
        setIsUploading(true);

        if (openMediaLibrary()) return;

        clearWaitTimer();
        const startedAt = Date.now();
        waitTimerRef.current = setInterval(() => {
            if (openMediaLibrary()) return;
            if (Date.now() - startedAt >= ML_WAIT_TIMEOUT_MS) {
                clearWaitTimer();
                resetUploadState();
                coloredToast('danger', 'Cloudinary Media Library gagal dimuat. Coba refresh halaman.');
            }
        }, ML_POLL_INTERVAL_MS);
    };

    useEffect(() => {
        ensureMediaLibrary();
        return () => clearWaitTimer();
    }, []);

    useEffect(() => {
        if (ml && itemUploadIdRef.current !== -1 && isUploading) {
            ml.show();
        }
    }, [ml]);

    handlersRef.current.show = () => {
        setIsUploading(true);
    };

    handlersRef.current.insert = (res: any) => {
        let imageUrl = res.assets[0].url.toString().replace('http://', 'https://');
        imageUrl = imageUrl.replace('/upload/', '/upload/f_auto/q_90/');

        if (imageUrl) {
            setImages((prevImages) => {
                const updatedItems = prevImages.slice();
                updatedItems[itemUploadIdRef.current] = imageUrl;

                return updatedItems;
            });
            clearWaitTimer();
            resetUploadState();
        }
    };

    handlersRef.current.hide = () => {
        clearWaitTimer();
        resetUploadState();
    };

    const removeImage = (id: number) => {
        const updatedItems = [...images];
        updatedItems[id] = '';
        setImages(updatedItems);
    };

    const handleDrop = (index: number) => (item: any) => {
        const dragIndex = item.index;
        const dragUrl = images[dragIndex];
        const hoverIndex = index;
        const updatedItems = [...images];
        updatedItems[dragIndex] = updatedItems[hoverIndex];
        updatedItems[hoverIndex] = dragUrl;
        setImages(updatedItems);
    };

    const dropRef = (index: number) =>
        useDrop({
            accept: 'IMAGE',
            drop: handleDrop(index),
        });

    return (
        <>
            <div className="text-lg">Product Images : </div>
            <div className="mt-4 flex justify-between">
                {Array.from({ length: totalImages }, (_, index) => {
                    const [collectedProps, drop] = dropRef(index);
                    const [{ isDragging }, drag] = useDrag({
                        type: 'IMAGE',
                        item: { index },
                        collect: (monitor) => ({
                            isDragging: monitor.isDragging(),
                        }),
                    });
                    return (
                        <div key={index} ref={drop as any}>
                            <div ref={drag as any}>
                                {/* <input type="file" style={{ display: 'none' }} accept="image/*" id={`fileInput_${index}`} onChange={(e) => handleUpload(e, index)} /> */}
                                {itemUploadId !== index && !images[index] && (
                                    <button onClick={() => handleUploadClick(index)} className="mt-5" id={index.toString()}>
                                        <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 24 24" fill="none">
                                            <path
                                                d="M2 12.5001L3.75159 10.9675C4.66286 10.1702 6.03628 10.2159 6.89249 11.0721L11.1822 15.3618C11.8694 16.0491 12.9512 16.1428 13.7464 15.5839L14.0446 15.3744C15.1888 14.5702 16.7369 14.6634 17.7765 15.599L21 18.5001"
                                                stroke="currentColor"
                                                strokeWidth="1.5"
                                                strokeLinecap="round"
                                            />
                                            <path d="M15 5.5H18.5M18.5 5.5H22M18.5 5.5V9M18.5 5.5V2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
                                            <path
                                                d="M22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12C2 10.8717 2 9.87835 2.02008 9M12 2C7.28595 2 4.92893 2 3.46447 3.46447C3.03965 3.88929 2.73806 4.38921 2.52396 5"
                                                stroke="currentColor"
                                                strokeWidth="1.5"
                                                strokeLinecap="round"
                                            />
                                        </svg>
                                    </button>
                                )}
                                {itemUploadId === index && isUploading && (
                                    <div className="relative mt-5 flex justify-center">
                                        <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 24 24" fill="none">
                                            <path
                                                d="M2 12.5001L3.75159 10.9675C4.66286 10.1702 6.03628 10.2159 6.89249 11.0721L11.1822 15.3618C11.8694 16.0491 12.9512 16.1428 13.7464 15.5839L14.0446 15.3744C15.1888 14.5702 16.7369 14.6634 17.7765 15.599L21 18.5001"
                                                stroke="currentColor"
                                                strokeWidth="1.5"
                                                strokeLinecap="round"
                                            />
                                            <path d="M15 5.5H18.5M18.5 5.5H22M18.5 5.5V9M18.5 5.5V2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
                                            <path
                                                d="M22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12C2 10.8717 2 9.87835 2.02008 9M12 2C7.28595 2 4.92893 2 3.46447 3.46447C3.03965 3.88929 2.73806 4.38921 2.52396 5"
                                                stroke="currentColor"
                                                strokeWidth="1.5"
                                                strokeLinecap="round"
                                            />
                                        </svg>
                                        <span className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform">
                                            <span className="m-auto inline-block h-4 w-4 animate-spin rounded-full border-[3px] border-transparent border-l-primary align-middle"></span>
                                        </span>
                                    </div>
                                )}

                                {!isUploading && images[index] && (
                                    <div className="mt-5">
                                        <Image src={images[index]} alt="Thumbnail" width={50} height={50} />
                                        <div onClick={() => handleUploadClick(index)} className="mt-2 cursor-pointer hover:underline">
                                            change
                                        </div>
                                        <div onClick={() => removeImage(index)} className="mb-2 cursor-pointer hover:underline">
                                            remove
                                        </div>
                                    </div>
                                )}
                                {isUploading && itemUploadId !== index && images[index] && (
                                    <div className="mt-5">
                                        <Image src={images[index]} alt="Thumbnail" width={50} height={50} />
                                        <div onClick={() => handleUploadClick(index)} className="mt-2 cursor-pointer hover:underline">
                                            change
                                        </div>
                                        <div onClick={() => removeImage(index)} className="mb-2 cursor-pointer hover:underline">
                                            remove
                                        </div>
                                    </div>
                                )}
                            </div>
                        </div>
                    );
                })}
            </div>
        </>
    );
};

export default ImageForm;
