'use client'

import React, { useEffect, useState, useRef } from 'react'
import { SendIcon, 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 { sessionType } from '@/types/userType'
import { appointmentType } from '@/types/calendarTypes'

interface ChatProps {
  userId: string
  socketRef: React.MutableRefObject<any>
  roomId: string
  messagesFromDB: any
  showEmojis: boolean
  setShowEmojis: React.Dispatch<React.SetStateAction<boolean>>
  session: sessionType
  appointment: appointmentType
  expertInfo: any
  clientInfo: any
  /** true = peut écrire ; false = lecture seule */
  canSend?: boolean
  /** deadline (ms epoch) jusqu’à laquelle l’écriture reste active en post-appel */
  writeWindowUntil?: number | null
}

/**
 * Chat :
 * - affiche l’historique + écoute les nouveaux messages via socket
 * - envoi texte/fichier si `canSend === true`
 * - NE ferme PAS la socket au cleanup (uniquement .off)
 * - NE réémet PAS "join room" (fait par le parent)
 * - badge J+15 post-appel quand écriture autorisée
 */
const Chat: React.FC<ChatProps> = ({
  userId,
  socketRef,
  roomId,
  messagesFromDB,
  showEmojis,
  setShowEmojis,
  session,
  appointment,
  expertInfo,
  clientInfo,
  canSend = true,
  writeWindowUntil,            // ✅ on récupère bien la prop
}) => {
  const [message, setMessage] = useState('')
  const [messages, setMessages] = useState<any[]>([])
  const [fileToUpload, setFileToUpload] = useState<File | null>(null)
  const [uploadedFileName, setUploadedFileName] = useState('')
  const [selectedImage, setSelectedImage] = useState<string | null>(null)
  const fileInputRef = useRef<HTMLInputElement | null>(null)
  const messagesEndRef = useRef<HTMLDivElement | null>(null)
  const [writeMsLeft, setWriteMsLeft] = useState<number | null>(null)

  // compteur J+15 basé sur la deadline passée par le parent
  useEffect(() => {
    if (!writeWindowUntil || canSend !== true) {
      setWriteMsLeft(null)
      return
    }
    const update = () => {
      setWriteMsLeft(Math.max(0, writeWindowUntil - Date.now()))
    }
    update()
    const id = setInterval(update, 1000)
    return () => clearInterval(id)
  }, [writeWindowUntil, canSend])

  // hydrate l’historique
  useEffect(() => {
    setMessages(Array.isArray(messagesFromDB) ? messagesFromDB : [])
  }, [messagesFromDB])

  // écoute les nouveaux messages
  useEffect(() => {
    const sock = socketRef.current
    if (!sock) return
    const handleChatMessage = (data: any) => {
      setMessages((prev) => [...prev, data])
    }
    sock.on('chat message', handleChatMessage)
    return () => {
      sock.off('chat message', handleChatMessage)
    }
  }, [socketRef])

  // scroll en bas à chaque nouveau message
  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [messages])

const canActuallySend =
  canSend && (writeMsLeft === null || writeMsLeft > 0)

const triggerFileInput = () => fileInputRef.current?.click()

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (file) {
      setFileToUpload(file)
      setUploadedFileName(file.name)
    }
  }

  const addEmoji = (e: any) => setMessage((prev) => prev + e.native)

  const sendMessage = async () => {
    const sock = socketRef.current
    if (!sock || canActuallySend === false) return
    if (!message.trim() && !fileToUpload) return

    try {
      if (fileToUpload) {
        const formData = new FormData()
        formData.set('file', fileToUpload)
        const response = await fetch('/api/upload', { method: 'POST', body: formData })
        if (!response.ok) throw new Error('Upload failed')
        const json = await response.json()
        const fileUrl = json.path
        const fileName = json.fileName

        sock.emit('chat message', {
          userId,
          roomId,
          fileName,
          content: '',
          type: 'file',
          fileUrl,
          appointment,
        })
      } else {
        sock.emit('chat message', {
          userId,
          roomId,
          fileName: '',
          fileType: '',
          content: message.trim(),
          type: 'text',
          fileUrl: '',
          appointment,
        })
      }

      setMessage('')
      setFileToUpload(null)
      setUploadedFileName('')
      fileInputRef.current && (fileInputRef.current.value = '')
      setShowEmojis(false)
    } catch (err) {
      console.error('Erreur lors de l’envoi', err)
    }
  }

  // utilitaires (pour éventuels téléchargements base64) 
  const base64ToBlob = (base64: string, contentType: string) => {
    const byteCharacters = atob(base64)
    const byteArrays = []
    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)
      byteArrays.push(new Uint8Array(byteNumbers))
    }
    return new Blob(byteArrays, { type: contentType })
  }

  const getFileMimeType = (fileName: string) => {
    const ext = fileName.split('.').pop()?.toLowerCase()
    switch (ext) {
      case 'pdf':
        return 'application/pdf'
      case 'docx':
        return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
      case 'xlsx':
        return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      default:
        return 'application/octet-stream'
    }
  }

  const handleFileDownload = (base64Data: string, fileName: string) => {
    const mimeType = getFileMimeType(fileName)
    const blob = base64ToBlob(base64Data.split(',')[1], mimeType)
    const link = document.createElement('a')
    link.href = URL.createObjectURL(blob)
    link.download = fileName
    link.rel = 'noopener noreferrer'
    link.click()
  }

  // format badge
  const formatMs = (ms: number) => {
    const totalSec = Math.floor(ms / 1000)
    const days = Math.floor(totalSec / 86400)
    const hours = Math.floor((totalSec % 86400) / 3600)
    const minutes = Math.floor((totalSec % 3600) / 60)
    const seconds = totalSec % 60
    if (days > 0) return `${days}j ${hours}h ${minutes}m`
    if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`
    return `${minutes}m ${seconds}s`
  }

  const showWriteBadge =
    appointment?.status === 'completed' &&
    canSend === true &&
    typeof writeMsLeft === 'number' &&
    writeMsLeft > 0

  return (
    <div
      className={`flex flex-col justify-between h-full w-full rounded-2xl ${
        appointment.status === 'completed' ? 'py-4 px-4 max-w-[80%] m-auto' : ''
      }`}
    >
      {/* En-tête */}
      <div className="flex items-center px-3 py-2 bg-[#57a9e7] border-b-2 rounded-lg">
        <Image src={person} alt="" width={50} height={50} className="w-[50px]" />
        <p className="text-white font-semibold ml-3">
          {session?.user?.userId === appointment?.clientId
            ? `${expertInfo?.firstName} ${expertInfo.lastName}`
            : `${clientInfo?.firstName} ${clientInfo.lastName}`}
        </p>

        {/* Badge J+15 */}
        {showWriteBadge && (
          <span className="ml-auto inline-flex items-center gap-2 text-xs font-medium px-2 py-1 rounded-full bg-white/90 text-[#0f172a] shadow">
            <span className="inline-block w-2 h-2 rounded-full bg-green-500" />
            Écriture active — reste {formatMs(writeMsLeft!)}
          </span>
        )}
      </div>

      {/* Bandeau lecture seule */}
      {canSend === false && (
        <div className="text-center text-sm py-2 text-gray-600">
          Lecture seule (la rédaction sera réactivée pendant le prochain appel ou jusqu’à J+15 après le dernier appel).
        </div>
      )}

      {/* Liste des messages */}
      <ul
        className={
          appointment.status === 'completed'
            ? 'max-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') {
            const fileUrl = `/api/serveFiles?filename=${encodeURIComponent(msg.fileName)}`
            const isImage = /\.(jpg|jpeg|png|gif|bmp|svg)$/i.test(msg.fileName)
            return (
              <li
                key={`${index}-${msg.fileName || 'file'}`}
                className={`flex gap-3 px-2 mt-2 ${msg.userId !== userId ? 'justify-start' : 'justify-end'}`}
              >
                {msg.userId !== userId && (
                  <div className="rounded-full w-12 min-w-[2rem] min-h-[4rem]">
                    <Image src={person} alt="" width={48} height={48} />
                  </div>
                )}
                <div className="flex items-center">
                  {isImage ? (
                    <img
                      src={fileUrl}
                      className="max-w-[200px] rounded-lg cursor-pointer"
                      alt={msg.fileName}
                      onClick={() => setSelectedImage(fileUrl)}
                    />
                  ) : (
                    <a
                      href={fileUrl}
                      download={msg.fileName}
                      target="_blank"
                      rel="noopener noreferrer"
                      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`}
                    >
                      Télécharger {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.userId !== userId && (
                <div className="rounded-full w-12 min-w-[2rem] min-h-[4rem]">
                  <Image src={person} alt="" width={48} height={48} />
                </div>
              )}
              <div className="flex items-center">
                <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>
          )
        })}
        <div ref={messagesEndRef} />
      </ul>

      {/* Zone de saisie */}
      <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 items-end">
          <div
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault()
                if ((message.trim() || fileToUpload) && canActuallySend) sendMessage()
              }
            }}
            className="flex-1 flex flex-row-reverse"
          >
            {fileToUpload ? (
              <div className="flex-1 flex items-center">
                <div>
                  <input
                    type="file"
                    ref={fileInputRef}
                    onChange={handleFileChange}
                    className="hidden"
                    disabled={!canActuallySend}
                  />
                  <button className="file-upload-button" onClick={triggerFileInput} disabled={!canActuallySend}>
                    <PaperclipIcon className="w-5 h-5" />
                  </button>
                </div>
                <input
                  placeholder={`Fichier : ${uploadedFileName}`}
                  value={uploadedFileName}
                  className="flex-1 outline-none bg-gray-200 pl-4"
                  readOnly
                />
              </div>
            ) : (
              <>
                <input
                  value={message}
                  className="flex-1 outline-none bg-gray-200 pl-4"
                  onChange={(e) => setMessage(e.target.value)}
                  disabled={!canActuallySend}
                />
                <div className="flex items-center">
                  <input
                    type="file"
                    ref={fileInputRef}
                    onChange={handleFileChange}
                    className="hidden"
                    disabled={!canActuallySend}
                  />
                  <button className="text-left" onClick={() => setShowEmojis(!showEmojis)} disabled={!canActuallySend}>
                    🙂
                  </button>
                  {showEmojis && (
                    <div className="absolute bottom-[50px] right-2 z-50">
                      <Picker data={data} onEmojiSelect={addEmoji} />
                    </div>
                  )}
                  <button className="file-upload-button" onClick={triggerFileInput} disabled={!canActuallySend}>
                    <PaperclipIcon className="w-5 h-5" />
                  </button>
                </div>
              </>
            )}
          </div>
          <button onClick={sendMessage} disabled={!canActuallySend}>
            <SendIcon className="w-5 h-5" />
          </button>
        </div>
      </div>

      {/* Image agrandie */}
      {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="image" className="max-w-full max-h-full w-full" />
          </div>
        </div>
      )}
    </div>
  )
}

export default Chat
