import { useEffect, useState, useRef } from 'react';
import Image from 'next/image';
import NumberFormatter from '@/lib/ribuan';
import { Checkbox } from '@mui/material';
import FormControlLabel from '@mui/material/FormControlLabel';
import { coloredToast } from '@/lib/toast';

const ML_WAIT_TIMEOUT_MS = 8000;
const ML_POLL_INTERVAL_MS = 100;

interface Attributes {
    id: string;
    value: any;
    name: string;
    type: string;
}

interface ProductItem {
    id: number;
    sku_variation: string;
    reg_price: number;
    sale_price: number;
    qty: number;
    gold_weight: number;
    image: string;
    attributes: any;
    is_default_image?: boolean;
}

interface Product {
    product_sku: string;
    product_qty: number;
    product_gold_weight: number;
    product_reg_price: number;
    product_sale_price: number;
}

interface ItemVariantFormProps {
    product: Product;
    items: ProductItem[];
    selectedOption: Attributes[];
    setItems: React.Dispatch<React.SetStateAction<ProductItem[]>>;
    
}

interface CustomWindow extends Window {
    cloudinary: any;
}

declare let window: CustomWindow;

const ItemVariant: React.FC<ItemVariantFormProps> = ({ items, setItems, selectedOption, product }) => {
    const addItem = () => {
        let maxId = 0;
        maxId = items?.length ? items.reduce((max: number, character: any) => (character.id > max ? character.id : max), items[0].id) : 0;

        setItems([
            ...items,
            {
                id: maxId + 1,
                sku_variation: product.product_sku || '',
                reg_price: product.product_reg_price || 0,
                sale_price: product.product_sale_price || 0,
                qty: 0,
                gold_weight: 0,
                image: '',
                attributes: [],
                is_default_image: false,
            },
        ]);
    };

    const removeItem = (item: any = null) => {
        setItems(items.filter((d: any) => d.id !== item.id));
    };

    const handleChange = (form: string, value: string, id: number) => {
        const updatedItems = items.map((item) => {
            if (item.id === id) {
                return {
                    ...item,
                    [form]: String(value),
                };
            }
            return item;
        });
        setItems(updatedItems);
    };

    const handleAttributeSelected = (attrid: string, name: string, type: string, value: string, id: number) => {
        const updatedItems = items.map((item) => {
            if (item.id === id) {
                let attributes = item.attributes || []; // Initialize with existing attributes if they exist
                const existingAttributeIndex = attributes.findIndex((attr: any) => attr.name === name);

                if (existingAttributeIndex !== -1) {
                    // Update the existing attribute if it exists
                    attributes[existingAttributeIndex] = {
                        ...attributes[existingAttributeIndex],
                        id: attrid,
                        name,
                        type,
                        value: value !== '' ? JSON.parse(value) : value,
                    };
                } else {
                    // Push a new attribute if it doesn't exist with the same name
                    attributes.push({
                        id: attrid,
                        name,
                        type,
                        value: value !== '' ? JSON.parse(value) : value,
                    });
                }

                return {
                    ...item,
                    attributes,
                };
            }

            return item;
        });

        setItems(updatedItems);
    };

    const handleImageVariationDefault = (id: number) => {
        const currentDefault = items.find((i) => i.is_default_image);
        const isClickingCurrentDefault = currentDefault?.id === id;
        const updatedItems = items.map((item) => ({
            ...item,
            is_default_image: isClickingCurrentDefault ? false : item.id === id,
        }));
        setItems(updatedItems);
    };

    const handleChangeSelectedOption = () => {
        if (items.length > 0) {
            // selectedItems is null
            if (selectedOption && selectedOption.length <= 0) {
                const updatedItems = items.map((item) => {
                    return {
                        ...item,
                        attributes: [], // Clear attributes
                    };
                });
                setItems(updatedItems);
            } else {
                // If selected options exist, adjust attributes for each item
                const updatedItems = items.map((item) => {
                    let attributes = [...item.attributes];

                    // Filter out attributes that don't exist in selectedOption
                    attributes = attributes.filter((attr) => {
                        return selectedOption.some((option) => option.id === attr.id);
                    });

                    // Add any missing attributes with default values
                    selectedOption.forEach((option) => {
                        const findAttribute = attributes.find((attr) => attr.id === option.id);
                        if (!findAttribute) {
                            attributes.push({
                                id: option.id,
                                name: option.name,
                                type: option.type,
                                value: '', // You can set a default value here if needed
                            });
                        }
                    });

                    return {
                        ...item,
                        attributes,
                    };
                });

                setItems(updatedItems);
            }
        }
    };

    useEffect(() => {
        handleChangeSelectedOption();
    }, [selectedOption]);

    const handleChangeNumber = (form: string, value: string, id: number) => {
        const updatedItems = items.map((item) => {
            if (item.id === id) {
                return {
                    ...item,
                    [form]: Number(value),
                };
            }
            return item;
        });
        setItems(updatedItems);
    };

    const [selectedImage, setSelectedImage] = useState<File | null>(null);
    const [isUploading, setIsUploading] = useState(false);
    const [itemUploadId, setItemUploadId] = useState(0);
    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 = 0;
        setItemUploadId(0);
    };

    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 !== 0 && isUploading) {
            ml.show();
        }
    }, [ml]);

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

    handlersRef.current.insert = (res: any) => {
        const imageUrl = res.assets[0].url.toString();

        if (imageUrl) {
            setItems((prevImages) => {
                const updatedItems = prevImages.map((item) => {
                    if (item.id === itemUploadIdRef.current) {
                        return {
                            ...item,

                            image: imageUrl,
                        };
                    }
                    return item;
                });

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

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

    // const handleUploadClick = (id: number) => {
    //     const fileInput = document.getElementById(`fileInputVar_${id}`); // Locate the input element by id
    //     if (fileInput) {
    //         fileInput.click(); // Trigger the click event for the input element
    //     }
    // };
    // const handleUpload = (e: any, id: number) => {
    //     const file = e.target.files?.[0];
    //     if (file) {
    //         setSelectedImage(file);
    //         setIsUploading(true);
    //         setItemUploadId(id);
    //         // Upload the selected image to Cloudinary
    //         uploadImageToCloudinary(file, id);
    //     }
    // };

    // // Function to upload image to Cloudinary
    // const uploadImageToCloudinary = async (file: File, id: number) => {
    //     try {
    //         const folder = 'aurumlab/product/images';
    //         const api_url = process.env.API_URL;
    //         const signResponse = await fetch(`${api_url}api/sign-cloudinary?folder=${folder}`, {
    //             credentials: 'include',
    //         });
    //         const signData = await signResponse.json();

    //         const cloudinary_url = process.env.NEXT_PUBLIC_CLOUDINARY_URL;
    //         const cloudinary_cloud_name = process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME;
    //         const cloudinaryUploadUrl = `${cloudinary_url}${cloudinary_cloud_name}/image/upload`;
    //         const formData = new FormData();
    //         formData.append('file', file);
    //         formData.append('api_key', signData.apikey);
    //         formData.append('timestamp', signData.timestamp);
    //         formData.append('signature', signData.signature);
    //         formData.append('folder', folder);

    //         // Send a POST request to Cloudinary to upload the image
    //         const response = await fetch(cloudinaryUploadUrl, {
    //             method: 'POST',
    //             body: formData,
    //         });

    //         if (response.ok) {
    //             const data = await response.json();
    //             const imageUrl = data.secure_url; // Get the secure URL of the uploaded image

    //             // Update the articleThumbnail state with the Cloudinary URL
    //             const updatedItems = items.map((item) => {
    //                 if (item.id === id) {
    //                     return {
    //                         ...item,

    //                         image: imageUrl,
    //                     };
    //                 }
    //                 return item;
    //             });
    //             setItems(updatedItems);
    //             setIsUploading(false);
    //             setItemUploadId(0);
    //         } else {
    //             console.error('Failed to upload image to Cloudinary');
    //         }
    //     } catch (error) {
    //         console.error('Error uploading image to Cloudinary:', error);
    //     }
    // };

    return (
        <div className="mb-2 w-full">
            <table className="min-w-full">
                <thead>
                    <tr>
                        <th>Image</th>
                        <th>Detail Variation</th>
                        <th></th>
                    </tr>
                </thead>

                <tbody>
                    {items.length <= 0 && (
                        <tr>
                            <td colSpan={3} className="!text-center font-semibold">
                                No Product Items Available
                            </td>
                        </tr>
                    )}
                    {items.map((item: any) => (
                        <tr className="align-top" key={item.id}>
                            <td>
                                {/* <input
                                    type="file"
                                    style={{ display: 'none' }}
                                    accept="image/*"
                                    id={`fileInputVar_${item.id}`} // Set the id attribute
                                    onChange={(e) => handleUpload(e, item.id)}
                                /> */}
                                {itemUploadId !== item.id && !item.image && (
                                    <button onClick={() => handleUploadClick(item.id)} className="mt-5" id={item.id}>
                                        <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 === item.id && 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 && item.image && (
                                    <div className="mt-5">
                                        <Image src={item.image} alt="Thumbnail" width={50} height={50} />
                                        <div onClick={() => handleUploadClick(item.id)} className="my-2 cursor-pointer hover:underline">
                                            change
                                        </div>
                                    </div>
                                )}
                                {isUploading && itemUploadId !== item.id && item.image && (
                                    <div className="mt-5">
                                        <Image src={item.image} alt="Thumbnail" width={50} height={50} />
                                        <div onClick={() => handleUploadClick(item.id)} className="my-2 cursor-pointer hover:underline">
                                            change
                                        </div>
                                    </div>
                                )}
                            </td>
                            <td>
                                <div className="flex flex-wrap justify-between">
                                    <div className="w-full  px-2 lg:w-1/2">
                                        <div className="mt-4 flex items-center">
                                            <label htmlFor={`product_sku_${item.id}`} className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">
                                                SKU Variation
                                            </label>
                                            <input
                                                type="text"
                                                placeholder="SKU variation"
                                                id={`product_sku_${item.id}`}
                                                className="form-input w-2/3 uppercase lg:w-[160px]"
                                                value={item.sku_variation}
                                                onChange={(e) => handleChange('sku_variation', e.target.value, item.id)} // Tambahkan event handler onChange di sini
                                            />
                                        </div>
                                        <div className="mt-4 flex items-center">
                                            <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">Quantity</label>
                                            <input
                                                type="number"
                                                className="form-input w-2/3 lg:w-[160px]"
                                                placeholder="Stok"
                                                value={item.qty}
                                                onChange={(e) => handleChangeNumber('qty', e.target.value, item.id)}
                                            />
                                        </div>
                                        <div className="mt-4 flex items-center">
                                            <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">Gold Weight</label>
                                            <input
                                                type="number"
                                                className="form-input w-2/3 lg:w-[160px]"
                                                placeholder="gold weight"
                                                value={item.gold_weight}
                                                onChange={(e) => handleChangeNumber('gold_weight', e.target.value, item.id)}
                                            />
                                        </div>
                                        <div className="mt-4 flex items-center">
                                            <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">Regular Price</label>
                                            <NumberFormatter
                                                className="form-input w-2/3 lg:w-[160px]"
                                                placeholder="Regular"
                                                value={item.reg_price}
                                                onChange={(value) => handleChangeNumber('reg_price', value.toString(), item.id)}
                                            />
                                        </div>
                                        <div className="mt-4 flex items-center">
                                            <label className="mb-0 flex-1 ltr:mr-2 rtl:ml-2">Sale Price</label>
                                            <NumberFormatter
                                                className="form-input w-2/3 lg:w-[160px]"
                                                placeholder="Sale"
                                                value={item.sale_price}
                                                onChange={(value) => handleChangeNumber('sale_price', value.toString(), item.id)}
                                            />
                                        </div>
                                    </div>
                                    <div className=" w-full px-2 lg:w-1/2">
                                        {(!selectedOption || selectedOption.length <= 0) && <div className="mt-4 flex items-center">no selected attribute</div>}
                                        {selectedOption &&
                                            selectedOption.map((optionField: any, index: number) => {
                                                const findValue = item.attributes.find((attr: any) => attr.id === optionField.id);
                                                const defaultValue = findValue ? findValue.value : '';

                                                return (
                                                    <div key={`${index}__${item.id}`} className="mt-4 flex items-center">
                                                        <label className="mb-0 flex-1 capitalize ltr:mr-2 rtl:ml-2">{optionField.name}</label>
                                                        <select
                                                            className="form-select w-2/3 lg:w-[160px]"
                                                            value={JSON.stringify(defaultValue)}
                                                            onChange={(e) => handleAttributeSelected(optionField.id, optionField.name, optionField.type, e.target.value, item.id)}
                                                        >
                                                            <option value="">select {optionField.name}</option>
                                                            {optionField.value.length > 0 &&
                                                                optionField.value.map((value: any, idx: number) => (
                                                                    <option value={JSON.stringify(value)} key={idx}>
                                                                        {optionField.type === 'color' || optionField.type === 'image' ? value.label : value}
                                                                    </option>
                                                                ))}
                                                        </select>
                                                    </div>
                                                );
                                            })}
                                        {selectedOption && selectedOption.length > 0 && selectedOption[0]?.type === 'color' && (
                                            <div className="mt-4 flex items-center variation-item-default-checkbox">
                                               <FormControlLabel
                                                    control={
                                                        <Checkbox
                                                            checked={item.is_default_image === true}
                                                            onChange={() => handleImageVariationDefault(item.id)}
                                                            sx={{
                                                                '&.Mui-checked': {
                                                                    color: '#3b5bdb',
                                                                },
                                                                '& .MuiSvgIcon-root': { fontSize: 18 }
                                                            }}
                                                        />
                                                    }
                                                    label="Default Image"
                                                    sx={{
                                                        '& .MuiFormControlLabel-label': { fontSize: 16 }
                                                    }}
                                                />
                                            </div>
                                        )}
                                    </div>
                                </div>
                            </td>

                            <td>
                                <button type="button" onClick={() => removeItem(item)}>
                                    <svg
                                        xmlns="http://www.w3.org/2000/svg"
                                        width="20"
                                        height="20"
                                        viewBox="0 0 24 24"
                                        fill="none"
                                        stroke="currentColor"
                                        strokeWidth="1.5"
                                        strokeLinecap="round"
                                        strokeLinejoin="round"
                                    >
                                        <line x1="18" y1="6" x2="6" y2="18"></line>
                                        <line x1="6" y1="6" x2="18" y2="18"></line>
                                    </svg>
                                </button>
                            </td>
                        </tr>
                    ))}
                </tbody>
            </table>
            <button type="button" className="btn btn-outline-primary btn-sm" onClick={addItem}>
                Add Item
            </button>
        </div>
    );
};

export default ItemVariant;
