import { useEffect, useState } from "react"
import {getDownloadURL, getStorage, ref, uploadBytesResumable} from 'firebase/storage'
import {app} from '../firebase'
import {useSelector} from 'react-redux'
import {useNavigate, useParams} from 'react-router-dom' 


const UpdateListing = () => {
    const {currentUser} = useSelector((state) => state.user)
    const navigate =useNavigate();
    const params = useParams();
    const [files, setFiles] = useState([]);
    const [formData, setFormData] = useState({
        imageUrls: [],
        name: '',
        description: '',
        address: '',
        type: 'rent',
        bed: 1,
        bath: 1,
        currentPrice: 100,
        discountPrice: 0,
        offer: false,
        parking: false,
        furnished: false,
    });
    const [imageUploadError, setImageUploadError] = useState(false);
    const [upload, setUpload] = useState(false);
    const [error, setError] = useState(false);
    const [loading, setLoading] = useState(false);
    useEffect(() => {
       const fetchListing = async() => {
        const listingId = params.listingId;
        const res = await fetch(`/server/listing/get/${listingId}`);
        const data = await res.json();
        if(data.success === false){
            setError(data.message);
            return;
        }
        setFormData(data);
       };
       fetchListing(); 
    }, []);

    const handleImageSubmit = (e) => {
        if(files.length > 0 && files.length + formData.imageUrls.length < 11){
            setUpload(true);
            setImageUploadError(false);

            const promises = [];
            for(let i = 0; i < files.length; i++){
                promises.push(storeImage(files[i]));
            }
            Promise.all(promises).then((urls) => {
                setFormData({...formData, imageUrls: formData.imageUrls.concat(urls), 
                });
                setImageUploadError(false);
                setUpload(false);
            }).catch((error) => {
                setImageUploadError('Image upload failed (2mb max per image)');
                setUpload(false);
            });
        }else{
            setImageUploadError('You can upload maximum 10 images');
            setUpload(false);
        }
    };
    const storeImage = async(file) => {
        return new Promise((resolve, reject) => {
            const storage = getStorage(app);
            const fileName = new Date().getTime() + file.name
            const storageRef = ref(storage, fileName);
            const uploadTask = uploadBytesResumable(storageRef, file);
            uploadTask.on(
                "state_changed",(snapshot) => {
                    const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
                    console.log(`Upload is ${progress}% done`)
                },
                (error) => {
                    reject(error);
                },
                () => {
                    getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
                        resolve(downloadURL)
                    });
                }
            );
        });
    };
    const handleDeleteImage = (index) => {
        setFormData({...formData, imageUrls: formData.imageUrls.filter((_, i) => i !== index),
        });
    };
    const handleChange = (e) => {
        if (e.target.id === 'sale' || e.target.id === 'rent') {
            setFormData({...formData, type: e.target.id, });
        }
        if(e.target.id === 'parking' || e.target.id === 'furnished' || e.target.id === 'offer'){
            setFormData({...formData, [e.target.id]: e.target.checked, });
        }
        if(e.target.type === 'number' || e.target.type === 'text' || e.target.type === 'textarea'){
            setFormData({...formData, [e.target.id]: e.target.value, });
        }
    };
    const handleSubmit = async (e) => {
        e.preventDefault();
        try {
            if(formData.imageUrls.length < 1) 
                return setError('You need to upload at least one image');
            if (+formData.currentPrice < +formData.discountPrice)
                return setError('Discount must be lower than your current price');

            setLoading(true);
            setError(false);
            const res = await fetch(`/server/listing/update/${params.listingId}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({...formData, userRef: currentUser._id,}),
            });
            const data = await res.json();
            setLoading(false);
            if(data.success === false){
                setError(data.message)
            }
            navigate(`/listing/${data._id}`)
        } catch (error) {
           setError(error.message);
           setLoading(false); 
           
        }
    }

  return (
    <div className="p-3 max-w-4xl mx-auto">
        <h1 className="text-2xl uppercase text-center text-blue-900 font-serif my-10 tracking-wide">Update a listing</h1>
        <form onSubmit={handleSubmit} className="flex flex-col sm:flex-row gap-4"> 
            <div className="flex flex-col flex-1 gap-4">
                <input type="text" placeholder="Title" onChange={handleChange} value={formData.name} id="name" className='border p-2 rounded-md text-sm ' maxLength='62' minLength='10' required/>
                <textarea type="text" placeholder="Description" onChange={handleChange} value={formData.description} id="description" className='border p-2 rounded-md text-sm resize-none' required/>
                <input type="text" placeholder="Address" onChange={handleChange} value={formData.address} id="address" className='border p-2 rounded-md text-sm ' required/>
                <div className="flex gap-4 flex-wrap text-sm">
                    <div className="flex gap-2">
                        <input type="checkbox" onChange={handleChange} checked={formData.type === "sale"} id="sale" className="w-4"/>
                        <span>Sell</span>
                    </div>
                    <div className="flex gap-2">
                        <input type="checkbox" onChange={handleChange} checked={formData.type === "rent"} id="rent" className="w-4"/>
                        <span>Rent</span>
                    </div>
                    <div className="flex gap-2">
                        <input type="checkbox" onChange={handleChange} checked={formData.parking} id="parking" className="w-4"/>
                        <span>Garage</span>
                    </div>
                    <div className="flex gap-2">
                        <input type="checkbox" onChange={handleChange} checked={formData.furnished} id="furnished" className="w-4"/>
                        <span>Furnished</span>
                    </div>
                    <div className="flex gap-2">
                        <input type="checkbox" onChange={handleChange} checked={formData.offer} id="offer" className="w-4"/>
                        <span>Offer</span>
                    </div>
                </div>
                <div className=" flex flex-wrap gap-6 text-sm">
                    <div className="flex gap-2 items-center">
                        <input type='number' onChange={handleChange} value={formData.bed} id="bed" min='1' required className="p-2 border border-gray-500 rounded-lg w-20"/>
                        <p>Beds</p>
                    </div>
                    <div className="flex gap-2 items-center">
                        <input type='number' onChange={handleChange} value={formData.bath} id="bath" min='1' required className="p-2 border border-gray-500 rounded-lg w-20"/>
                        <p>Baths</p>
                    </div>
                    <div className="flex gap-2 items-center">
                        <input type='number' onChange={handleChange} value={formData.currentPrice} id="currentPrice" min='100' max='10000000' required className="p-2 border border-gray-500 rounded-lg [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"/>
                        <div className="flex flex-col items-center">
                           <p>Current price</p>
                           <span className="text-xs">($ per mounth)</span> 
                        </div>
                    </div>
                    {formData.offer && (
                        <div className="flex gap-2 items-center">
                            <input type='number' onChange={handleChange} value={formData.discountPrice} id="discountPrice" min='0' max='10000000' required className="p-2 border border-gray-500 rounded-lg [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"/>
                            <div className="flex flex-col items-center">
                            <p>Discounted price</p> 
                            <span className="text-xs">($ per mounth)</span>
                            </div>
                        </div>
                    )}
                </div>
            </div>
            <div className="flex flex-col flex-1 gap-4">
                <p className="font-semibold">Images: <span className="font-normal text-gray-500 ml-2">You can upload maximum 10 images</span></p>
                <div className="flex gap-4">
                    <input type="file" multiple accept="image/*" onChange={(e) => setFiles(e.target.files)} id="images" className="p-2 border border-gray-300 rounded w-full"/>
                    <button disabled={loading} type='button' onClick={handleImageSubmit} className="p-2 text-grenn-900 text-xs tracking-wider border border-blue-800 rounded uppercase hover:bg-blue-100 hover:border-blue-300 disabled:opacity-80">{upload ? 'Uploading...' : 'Upload'}</button>
                </div>
                <p className="text-red-700 text-sm self-center">{imageUploadError && imageUploadError}</p>
                {
                    formData.imageUrls.length > 0 && formData.imageUrls.map((url, index) => (
                        <div key={url} className="flex justify-between p-2 border items-center">
                            <img src={url} alt="" className="w-14 h-14 rounded-md object-contain"/>
                            <button type="button" onClick={() => handleDeleteImage (index)} className="p-2 text-red-700 text-xs rounded-lg uppercase hover:opacity-80">Delete</button>
                        </div>
                    ))
                }
                <button disabled={loading || upload} className="p-2 bg-blue-950 text-white text-sm font-semibold rounded-md uppercase hover:opacity-95 disabled:bg-opacity-80">{loading ? 'Updating...' : 'Update listing'}</button>
                { error && <p className="text-red-700 text-sm">{error}</p>}
            </div>  
        </form>
    </div>
  )
}

export default UpdateListing