import { FaRegTrashAlt } from "react-icons/fa";
import { BiEdit } from "react-icons/bi";
import {useSelector} from'react-redux'
import { useEffect, useRef, useState } from 'react'
import {getDownloadURL, getStorage, ref, uploadBytesResumable} from 'firebase/storage'
import { app } from '../firebase';
import {updateUserStart, updateUserSuccess, updateUserFailure, deleteUserFailure, deleteUserStart, deleteUserSuccess, logoutUserStart} from '../redux/user/userSlice.js'
import { useDispatch } from 'react-redux';
import {Link} from 'react-router-dom'

export const Profile = () => {
  const fileRef = useRef(null);
  const {currentUser, loading, error} = useSelector((state) => state.user);
  const [file, setFile] = useState(undefined);
  const [filePercentage, setFilePercentage] = useState(0);
  const [fileUploadError, setFileUploadError] = useState(false)
  const [formData, setFormData] = useState({})
  const [updateSuccess, setUpdateSuccess] = useState(false);
  const [userListings, setUserListings] = useState([]);
  const [userListingsError, setUserListingsError] = useState(false);
  const dispatch = useDispatch();


  useEffect (() => {
    if(file){
      handleFileUpload(file);
    }
  }, [file]);

  const handleFileUpload = (file) =>{
    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;
        setFilePercentage(Math.round(progress));
      },
    (error) => {
      setFileUploadError(true);
    },
    () => {
      getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => setFormData({...formData, avatar: downloadURL}));
    }
    )
  };
  const handleChange = (e) => {
    setFormData({...formData, [e.target.id]: e.target.value})
  }
  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      dispatch(updateUserStart());
      const res = await fetch(`/server/user/update/${currentUser._id}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(formData)
      });
      const data = await res.json();
      if(data.success === false){
        dispatch(updateUserFailure(data.message));
        return;
      }
      dispatch(updateUserSuccess(data));
      setUpdateSuccess(true);

    } catch (error) {
      dispatch(updateUserFailure(error.message));
    }
  };
  //delete user functionality 
  const handleDeleteUser = async () => {
    try {
      dispatch(deleteUserStart());
      const res = await fetch(`/server/user/delete/${currentUser._id}`, {
        method: 'DELETE',
      });
      const data = await res.json();
      if(data.success === false){
        dispatch(deleteUserFailure(data.message));
        return;
      }
      dispatch(deleteUserSuccess(data));

    } catch (error) {
      dispatch(deleteUserFailure(error.message))
    }
  };
  //logout functionality
  const handleLogout = async () => {
    try {
      dispatch(logoutUserStart());
      const res = await fetch('/server/auth/logout');
      const data = await res.json();
      if(data.success === false){
        dispatch(deleteUserFailure(data.message))
        return;
      }
      dispatch(deleteUserSuccess(data))

    } catch (error) {
      dispatch(deleteUserFailure(error.message))
    }
  };
  //show user listing functionality
  const handleUserListings = async () => {
    try {
      setUserListingsError(false);
      const res = await fetch(`/server/user/listings/${currentUser._id}`)
      const data = await res.json();
      if(data.success === false){
        setUserListingsError(true);
        return;
      }
      setUserListings(data)

    } catch (error) {
      setUserListingsError(true);
    }
  };
  //delete user listing functionality
  const handleListingDelete = async (listingId) => {
    try {
      const res = await fetch(`/server/listing/delete/${listingId}`, {
        method: 'DELETE'
      });
      const data = await res.json();
      if(data.success === false){
        return;
      }
      setUserListings((prev) =>
        prev.filter((listing) => listing._id !== listingId)
      )

    } catch (error) {
      console.log(error.message)
    }
  };


  return (
    <div className='max-w-sm p-3 mx-auto'>
      <h1 className="text-2xl uppercase text-center text-blue-900 font-serif my-10 tracking-wide">Profile</h1>
      <form onSubmit={handleSubmit} className='flex flex-col gap-4'> 
      <input onChange={(e) => setFile(e.target.files[0])} type="file" ref={fileRef} hidden accept='image/*'/>
        <img onClick={() => fileRef.current.click()} src={formData?.avatar || currentUser.avatar} alt="" className='rounded-full h-24 w-24 object-cover self-center mt-2 cursor-pointer bg-blue-100'/>
        <p className='text-sm self-center'>
          {
            fileUploadError ? (<span className='text-red-700'>Error image upload (image must be less than 2 mb) </span>) :
            filePercentage > 0 && filePercentage < 100 ? (<span className='text-blue-900'>{`Uploading ${filePercentage}%`}</span>) :
            filePercentage === 100 ? (<span className='text-green-900'>Image successfully uploaded</span>) : ("")
          }
        </p>
        <input type="text" placeholder='Username' id='username' defaultValue={currentUser.username} onChange={handleChange} className='border p-2 rounded-md text-sm'/>
        <input type="email" placeholder='Email' id='email' defaultValue={currentUser.email} onChange={handleChange} className='border p-2 rounded-md text-sm'/>
        <input type="password" placeholder='Password' id='password' onChange={handleChange} className='border p-2 rounded-md text-sm'/>
        <button disabled={loading} className='bg-blue-950 text-white text-sm p-2 rounded-md uppercase hover:opacity-90 disabled:opacity-80'>{loading ? 'Loading...' : 'Update'}</button>
        <Link to='/createListing' className='bg-green-800 text-white text-sm p-2 text-center rounded-md uppercase hover:opacity-90'>Create Listing</Link>
      </form>
      <div className='flex justify-between mt-4'>
        <span onClick={handleDeleteUser} className='text-red-700 cursor-pointer'>Delete Account</span>
        <span onClick={handleLogout} className='text-red-700 cursor-pointer'>Log Out</span>
      </div>
      <p className='text-red-700 mt-4'>{error ? error : ''}</p>
      <p className='text-green-900 mt-4'>{updateSuccess ? 'User profile is updated successfully' : ''}</p>
          {/*===== Show user listing =====*/}
      <button onClick={handleUserListings} className='text-blue-900 w-full'>View listings</button>
      <p className='text-red-700 text-sm'>{userListingsError ? 'Error showing listing' : ''}</p>
      {userListings && userListings.length > 0 && 
      <div className="flex flex-col gap-4"> 
      <h1 className="text-center mt-12 text-md uppercase text-blue-800 font-semibold">Your listings</h1>
      {userListings.map((listing) => (
        <div key={listing._id} className="flex justify-between items-center border rounded-md p-2 gap-2">
          <Link to={`/listing/${listing._id}`}>
            <img src={listing.imageUrls[0]} alt="" className='h-14 w-14 object-contain'/>
          </Link>
          <Link to={`/listing/${listing._id}`} className='text-blue-900 font-semibold  hover:underline truncate flex-1' >
            <p>{listing.name}</p>
          </Link>
          <div className="flex gap-4">
            <button onClick={() => handleListingDelete(listing._id)} className='text-red-700'><FaRegTrashAlt/></button>
            <Link to={`/updateListing/${listing._id}`}><button className='text-green-700'><BiEdit/></button></Link>
          </div>
        </div>
      ))}
      </div>}
    </div>
  );
}
