import { useEffect, useRef, useState } from 'react'
import { useWaste } from '../store'

const today = new Date()
today.setHours(0, 0, 0, 0)
const todayMs = today.getTime()

function formatTs(ts: number): string {
  const d = new Date(ts)
  const time = d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false })
  if (ts >= todayMs) return time
  return d.toLocaleDateString([], { month: 'short', day: 'numeric' }) + ' ' + time
}

const URL_RE = /https?:\/\/[^\s<>"']+/g
const IMAGE_EXT_RE = /\.(jpe?g|png|gif|webp|svg)(\?[^\s]*)?$/i

function renderText(text: string): React.ReactNode {
  const parts: React.ReactNode[] = []
  let last = 0
  let m: RegExpExecArray | null
  URL_RE.lastIndex = 0
  while ((m = URL_RE.exec(text)) !== null) {
    if (m.index > last) parts.push(text.slice(last, m.index))
    const url = m[0]
    const isImage = IMAGE_EXT_RE.test(url) || url.startsWith('blob:') || url.startsWith('data:image')
    parts.push(
      <a key={m.index} href={url} target="_blank" rel="noopener noreferrer" className="msg-link">
        {url}
      </a>
    )
    if (isImage) {
      parts.push(
        <img key={`img-${m.index}`} src={url} alt="" className="msg-image-preview" loading="lazy" />
      )
    }
    last = m.index + url.length
  }
  if (last < text.length) parts.push(text.slice(last))
  return parts.length > 1 ? <>{parts}</> : text
}

const EMOJI_SET = ['👍', '❤️', '😂', '😮', '😢', '🙏']

export function MessagePane({ onMenuClick }: { onMenuClick: () => void }) {
  const { messages, historyCutoff, activeRoom, activeNetworkId, localPeer, connectedPeers, knownPeers, reactions, sendReaction, send } = useWaste()
  const [draft, setDraft] = useState('')
  const [pickerMid, setPickerMid] = useState<string | null>(null)
  const bottomRef = useRef<HTMLDivElement>(null)
  const msgKey = activeNetworkId ? `${activeNetworkId}:${activeRoom}` : activeRoom
  const roomMessages = messages[msgKey] ?? []
  const cutoff = historyCutoff[msgKey] ?? 0

  const firstLiveIdx = cutoff > 0
    ? roomMessages.findIndex(m => m.ts > cutoff)
    : -1
  const dividerIdx = cutoff > 0
    ? (firstLiveIdx === -1 ? 0 : firstLiveIdx)
    : -1

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [roomMessages.length])

  // Close picker when clicking outside
  useEffect(() => {
    if (!pickerMid) return
    const handler = () => setPickerMid(null)
    document.addEventListener('click', handler)
    return () => document.removeEventListener('click', handler)
  }, [pickerMid])

  function submit(e: React.FormEvent) {
    e.preventDefault()
    const text = draft.trim()
    if (!text || !activeNetworkId) return

    if (activeRoom.startsWith('dm:')) {
      const toPeerID = activeRoom.slice(3)
      const peer = connectedPeers.find(p => p.id.startsWith(toPeerID) || p.id === toPeerID)
      if (peer) {
        send({ type: 'send_message', network_id: activeNetworkId, room: activeRoom, body: text, to: peer.id })
      }
    } else {
      send({ type: 'send_message', network_id: activeNetworkId, room: activeRoom, body: text })
    }
    setDraft('')
  }

  function aliasFor(fromId: string) {
    if (fromId === localPeer?.id) return localPeer.alias
    return connectedPeers.find(p => p.id === fromId)?.alias
      ?? knownPeers[fromId]
      ?? fromId.slice(0, 8)
  }

  function toggleReaction(mid: string, emoji: string, e: React.MouseEvent) {
    e.stopPropagation()
    if (!activeNetworkId || !mid) return
    sendReaction(activeNetworkId, mid, emoji)
    setPickerMid(null)
  }

  function openPicker(mid: string, e: React.MouseEvent) {
    e.stopPropagation()
    setPickerMid(prev => prev === mid ? null : mid)
  }

  const roomLabel = activeRoom.startsWith('dm:')
    ? `@ ${activeRoom.slice(3, 11)}…`
    : `# ${activeRoom}`

  return (
    <main className="message-pane">
      <div className="message-pane-header">
        <button className="menu-btn-mobile" onClick={onMenuClick} aria-label="Menu">☰</button>
        {roomLabel}
      </div>

      <div className="messages">
        {dividerIdx === 0 && (
          <div className="history-divider"><span>earlier messages</span></div>
        )}
        {roomMessages.map((msg, i) => {
          const mine = msg.from === localPeer?.id
          const alias = aliasFor(String(msg.from))
          const ts = formatTs(msg.ts)
          const mid = msg.mid ?? ''
          const msgReactions = mid ? reactions[mid] : undefined
          const hasReactions = msgReactions && Object.keys(msgReactions).length > 0
          return (
            <div key={mid || i} className="message-wrapper">
              {i === dividerIdx && dividerIdx > 0 && (
                <div className="history-divider"><span>earlier messages</span></div>
              )}
              <div className={`message ${mine ? 'mine' : ''}`}>
                <span className="message-ts">{ts}</span>
                <span className="message-alias">{alias}</span>
                <span className="message-text">
                  {renderText(msg.text)}
                </span>
                {mid && (
                  <button
                    className="reaction-add"
                    onClick={e => openPicker(mid, e)}
                    title="React"
                  >+</button>
                )}
              </div>
              {pickerMid === mid && (
                <div className="reaction-picker" onClick={e => e.stopPropagation()}>
                  {EMOJI_SET.map(emoji => (
                    <button key={emoji} className="reaction-picker-btn" onClick={e => toggleReaction(mid, emoji, e)}>
                      {emoji}
                    </button>
                  ))}
                </div>
              )}
              {hasReactions && (
                <div className="reaction-bar">
                  {Object.entries(msgReactions!).map(([emoji, fromIds]) => {
                    const iMine = fromIds.includes(localPeer?.id ?? '')
                    return (
                      <button
                        key={emoji}
                        className={`reaction-chip ${iMine ? 'mine' : ''}`}
                        onClick={e => toggleReaction(mid, emoji, e)}
                        title={fromIds.map(aliasFor).join(', ')}
                      >
                        {emoji} {fromIds.length}
                      </button>
                    )
                  })}
                </div>
              )}
            </div>
          )
        })}
        <div ref={bottomRef} />
      </div>

      <form className="compose" onSubmit={submit}>
        <input
          value={draft}
          onChange={e => setDraft(e.target.value)}
          placeholder={`Message ${roomLabel}`}
          autoComplete="off"
        />
        <button type="submit" disabled={!draft.trim()}>Send</button>
      </form>
    </main>
  )
}
