'use client'

import { useEffect, useState, useRef } from 'react'
import { SendIcon, UploadIcon, PaperclipIcon } from 'lucide-react'
import Image from 'next/image'

import Picker from '@emoji-mart/react'
import data from '@emoji-mart/data'

import person from '@/assets/ExpertElipse.svg'
import axios from 'axios'
import { sessionType } from '@/types/userType'
import { appointmentType } from '@/types/calendarTypes'

interface ChatProps {
  userId: string
  roomId: string
  session: sessionType
  messagesFromDB: any // Consider using a more specific type if possible
  socketRef: React.MutableRefObject<any> // Use a more specific type instead of `any` if the structure of the socket reference is known
  showEmojis: Boolean
  appointment: appointmentType
  expertInfo: any
  clientInfo: any
  setShowEmojis: React.Dispatch<React.SetStateAction<boolean>>
}

let socket: any

const Chat: React.FC<ChatProps> = ({
  userId,
  socketRef,
  roomId,
  messagesFromDB,
  showEmojis,
  setShowEmojis,
  session,
  appointment,
  expertInfo,
  clientInfo,
}) => {
  console.log('from chat', {
    messagesFromDB,
  })

  const [message, setMessage] = useState('')
  const [messages, setMessages] = useState([
    {
      userId: null,
      fileName: '',
      content: null || '',
      type: null,
      fileType: '',
      fileUrl: '',
    },
  ])

  const [uploadedFileName, setUploadedFileName] = useState('')
  const [fileToUpload, setFileToUpload] = useState(null)

  const [selectedImage, setSelectedImage] = useState(null)

  const handleImageClick = (imageSrc: any) => {
    setSelectedImage(imageSrc)
  }
  // Ref for the hidden file input
  const fileInputRef = useRef<any>(null)
  const messagesEndRef = useRef<HTMLDivElement>(null)

  // Function to trigger the hidden file input click
  const triggerFileInputClick = () => {
    if (fileInputRef.current) {
      fileInputRef.current.click()
    }
  }

  useEffect(() => {
    console.log(typeof messagesFromDB)
    setMessages((prevMessages) => [...prevMessages, ...messagesFromDB])
  }, [])

  const scrollToBottom = () => {
    if (messagesEndRef.current) {
      console.log('scroll')
      messagesEndRef.current.scrollIntoView({ behavior: 'smooth' })
    }
  }

  useEffect(() => {
    socket = socketRef.current

    console.log({ socket })

    // socket.emit('join', { userId: 'user123' });

    socket.on('chat message', (data: any) => {
      console.log('Receiving', data)
      const { content, type, userId, roomId, fileName, fileType } = data

      setMessages((prevMessages: any) => {
        console.log({ prevMessages })

        return [...prevMessages, { content, userId, fileName, fileType, type }]
      })
    })

    return () => {
      socket.off('chat message')
      socket.close()
    }
  }, [socketRef])

  const addEmoji = (e: any) => {
    let emoji = e.native
    setMessage(message + emoji)
  }

  const sendMessage = async () => {
    if (socket) {
      if (fileToUpload) {
        const data = new FormData()

        data.set('file', fileToUpload)

        try {
          let fileUrl

          fetch('/api/upload', {
            method: 'POST',
            body: data, // This is your request payload, for example, a FormData object
          })
            .then((response) => {
              if (!response.ok) {
                throw new Error('Network response was not ok')
              }
              console.log({ response })
              return response.json() // Parses the response body as JSON
            })
            .then((data) => {
              console.log(data)
              fileUrl = data.path // 'data' contains the parsed JSON object from the server response
              const fileName = data.fileName

              // Send the message with the file URL or identifier
              socket.emit('chat message', {
                userId,
                roomId,
                fileName,
                content: '', // Optional: Include a message with the file
                type: 'file',
                fileUrl, // The URL or identifier of the uploaded file
                appointment,
              })
            })
            .catch((error) => {
              console.error('Error:', error)
            })

          console.log(6)
        } catch (error) {
          console.error('Error uploading file:', error)
        }
      } else if (message) {
        // Send a text message if there's no file to upload
        socket.emit('chat message', {
          content: message,
          type: 'text',
          userId,
          roomId,
          fileName: '',
          fileType: '',
          fileUrl: '',
          appointment,
        })
      }

      // Reset state after sending
      setMessage('')
      setUploadedFileName('')
      setFileToUpload(null)
    }
  }

  const handleFileChange = (event: any) => {
    const file = event.target.files[0]
    console.log({ file })
    if (file) {
      setUploadedFileName(file.name) // Update the state with the file name

      // const reader = new FileReader();
      // reader.onloadend = () => {

      //     setFileToUpload({ data: reader.result, name: file.name, type: file.type }); // Store the file data for lat
      // };
      // reader.readAsDataURL(file);
      setFileToUpload(file)
    }
  }

  const base64ToBlob = (base64: any, contentType: any) => {
    const byteCharacters = atob(base64)
    const byteArrays: any = []

    for (let offset = 0; offset < byteCharacters.length; offset += 512) {
      const slice = byteCharacters.slice(offset, offset + 512)
      const byteNumbers = new Array(slice.length)

      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i)
      }

      const byteArray = new Uint8Array(byteNumbers)
      byteArrays.push(byteArray)
    }

    return new Blob(byteArrays, { type: contentType })
  }

  const getFileMimeType = (fileName: any) => {
    const extension = fileName.split('.').pop().toLowerCase()
    switch (extension) {
      case 'pdf':
        return 'application/pdf'
      case 'docx':
        return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
      case 'xlsx':
        return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      // Add more cases for other file types as needed
      default:
        return 'application/octet-stream' // Generic binary stream for unknown types
    }
  }

  const handleFileDownload = (base64Data: any, fileName: any) => {
    const mimeType = getFileMimeType(fileName)
    const link = document.createElement('a')
    const blob = base64ToBlob(base64Data.split(',')[1], mimeType) // Use dynamic MIME type
    link.href = URL.createObjectURL(blob)
    link.download = fileName
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }

  useEffect(() => {
    scrollToBottom()
  }, [messages])

  return (
    <div
      className={`flex flex-col justify-between h-full w-full lg-auto rounded-2xl border-blue-600  gap-4  ${
        appointment.status === 'completed' && ' py-4 px-4 max-w-[80%] m-auto '
      } `}
    >
      <div className="flex justify-start px-3 py-2 bg-[#57a9e7] border-b-2 rounded-lg cursor-pointer ">
        <Image
          src={person}
          alt=""
          width={100}
          height={100}
          className="w-[50px]"
        />

        <p className="text-white font-semibold flex flex-col justify-center ml-3 ">
          {' '}
          {session?.user?.userId === appointment?.clientId
            ? expertInfo?.firstName + ' ' + expertInfo.lastName
            : clientInfo?.firstName + ' ' + clientInfo.lastName}{' '}
        </p>
      </div>
      <ul
        className={
          appointment.status === 'completed'
            ? 'max-h-[70vh] min-h-[70vh]  h-full overflow-y-auto custom-scrollbar border-l border-solid '
            : `   max-h-full h-full overflow-y-auto custom-scrollbar`
        }
      >
        {messages.map((msg, index) => {
          if (msg.type === 'file') {
            // Construct the URL for the file download
            const fileUrl = `/api/serveFiles?filename=${encodeURIComponent(
              msg.fileName
            )}`

            const isImage = /\.(jpg|jpeg|png|gif|bmp|svg)$/i.test(msg.fileName)

            return (
              <li
                key={index}
                className={`flex gap-3 px-2 mt-2 ${
                  msg.userId !== userId ? 'justify-start' : 'justify-end'
                }`}
              >
                {/* Other message content */}
                {msg?.fileName && msg?.userId !== userId && (
                  <div className="rounded-full w-12 min-w-[2rem]  min-h-[4rem] ">
                    <Image src={person} alt="" width={100} height={100} />
                  </div>
                )}
                <div className="flex items-center ">
                  {isImage ? (
                    <img
                      src={fileUrl}
                      className="max-w-[200px] rounded-lg cursor-pointer"
                      alt={msg?.fileName}
                      onClick={() => handleImageClick(fileUrl)}
                    />
                  ) : (
                    <a
                      href={fileUrl}
                      download={msg.fileName}
                      target="_blank"
                      className={`max-w-[200px] px-3 py-1  ${
                        msg?.userId !== userId ? 'bg-blue-200' : 'bg-green-300'
                      } text-blue-600 hover:text-blue-800 rounded-lg`}
                    >
                      Download {msg.fileName}
                    </a>
                  )}
                </div>
              </li>
            )
          }

          return (
            <li
              key={index}
              className={`flex gap-3  px-2 mt-2 ${
                msg?.userId !== userId ? 'justify-start' : 'justify-end'
              }`}
            >
              {msg?.content && msg?.userId !== userId && (
                <div className="rounded-full w-12 min-w-[2rem]  min-h-[4rem] ">
                  <Image src={person} alt="" width={100} height={100} />
                </div>
              )}
              <div className="flex items-center ">
                {msg?.type === 'text' && (
                  <p
                    className={`max-w-[200px] px-3 py-1 ${
                      msg?.userId !== userId ? 'bg-blue-200' : 'bg-green-300'
                    }  rounded-lg`}
                  >
                    {msg?.content}
                  </p>
                )}
              </div>
            </li>
          )
        })}
      </ul>
      <div className="flex flex-col w-full  ">
        <div className="flex w-full bg-gray-200 border border-blue-200 rounded-md px-2 py-2  focus:border-3 focus:border-blue-600  items-end">
          <div
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault() // Prevent the default Enter key action
                if (message || uploadedFileName) {
                  sendMessage() // Call the appropriate function
                }
              }
            }}
            className="flex-1 flex flex-row-reverse "
          >
            {uploadedFileName ? (
              <div className="flex-1 flex gap- items-center">
                <div>
                  {/* Hidden file input */}
                  <input
                    type="file"
                    ref={fileInputRef}
                    onChange={handleFileChange}
                    className="hidden "
                  />
                  {/* Custom button that triggers file input */}
                  <button
                    className="file-upload-button"
                    onClick={triggerFileInputClick}
                  >
                    <PaperclipIcon className="w-5 h-5" />
                  </button>
                </div>

                {/* Invisible input to capture Enter key presses */}
                <input
                  placeholder={`Uploaded :  ${uploadedFileName} `}
                  value={uploadedFileName}
                  className="flex-1 outline-none bg-gray-200 w-full  pl-4 "
                  // onChange={(e) => setMessage(e.target.value)}
                  // tabIndex={-1} // Make the input not focusable

                  readOnly
                />
              </div>
            ) : (
              <>
                <input
                  value={message}
                  className="flex-1 outline-none bg-gray-200 w-full pl-4"
                  onChange={(e) => setMessage(e.target.value)}
                />
                <div className="flex items-center">
                  {/* Hidden file input */}
                  <input
                    type="file"
                    ref={fileInputRef}
                    onChange={handleFileChange}
                    className="hidden "
                  />
                  <button
                    className="text-left"
                    onClick={() => setShowEmojis(!showEmojis)}
                  >
                    😀
                  </button>
                  {showEmojis && (
                    <div className="absolute bottom-[50px] righ-[20px]">
                      <Picker data={data} onEmojiSelect={addEmoji} />
                    </div>
                  )}
                  {/* Custom button that triggers file input */}
                  <button
                    className="file-upload-button"
                    onClick={triggerFileInputClick}
                  >
                    <PaperclipIcon className="w-5 h-5" />
                  </button>
                  {/* {uploadedFileName && (
                        <span className="uploaded-file-name">
                            Uploaded: {uploadedFileName}
                        </span>
                    )} */}
                </div>
              </>
            )}
            <div ref={messagesEndRef} className="hidden" />
          </div>

          <button onClick={() => sendMessage()}>
            <SendIcon className="w-5 h-5" />
          </button>
        </div>
      </div>
      {/* Modal for displaying the enlarged image */}
      {selectedImage && (
        <div
          className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50    "
          onClick={() => setSelectedImage(null)}
        >
          <div
            className="bg-white p-4 rounded-lg w-2/3 lg:w-1/3 cursor-pointer "
            onClick={(e) => e.stopPropagation()}
          >
            <img
              src={selectedImage}
              alt="Enlarged"
              className="max-w-full max-h-full w-full "
            />
          </div>
        </div>
      )}
    </div>
  )
}

export default Chat
