import { useEffect, useLayoutEffect, useRef, useState, useCallback } from 'react'
import { MessageBubble } from './MessageBubble'
import type { ChatMessage } from '../../types/protocol'
import { Sparkles, ArrowDown, ArrowUp } from 'lucide-react'

interface MessageListProps {
  messages: ChatMessage[]
  onNavigateToSubAgent?: (taskId: string, description: string) => void
  showThinking?: boolean
}

export function MessageList({ messages, onNavigateToSubAgent, showThinking = true }: MessageListProps) {
  const bottomRef = useRef<HTMLDivElement>(null)
  const containerRef = useRef<HTMLDivElement>(null)
  const isAtBottomRef = useRef(true)
  const prevShowBottomRef = useRef(false)
  const prevShowTopRef = useRef(false)

  const [showScrollToBottom, setShowScrollToBottom] = useState(false)
  const [showScrollToTop, setShowScrollToTop] = useState(false)
  const [hasNewMessage, setHasNewMessage] = useState(false)

  // ---- scroll helpers ----

  const scrollToBottom = useCallback((behavior: ScrollBehavior = 'smooth') => {
    isAtBottomRef.current = true
    setShowScrollToBottom(false)
    setHasNewMessage(false)
    bottomRef.current?.scrollIntoView({ behavior })
  }, [])

  const scrollToTop = useCallback(() => {
    containerRef.current?.scrollTo({ top: 0, behavior: 'smooth' })
  }, [])

  // ---- scroll event: track whether user is at bottom ----

  const handleScroll = useCallback(() => {
    const el = containerRef.current
    if (!el) return

    const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight
    const nearBottom = distanceFromBottom < 120

    isAtBottomRef.current = nearBottom

    const shouldShowTop = el.scrollTop > el.clientHeight * 0.8
    if (shouldShowTop !== prevShowTopRef.current) {
      prevShowTopRef.current = shouldShowTop
      setShowScrollToTop(shouldShowTop)
    }

    const shouldShowBottom = !nearBottom
    if (shouldShowBottom !== prevShowBottomRef.current) {
      prevShowBottomRef.current = shouldShowBottom
      setShowScrollToBottom(shouldShowBottom)
    }

    if (nearBottom && hasNewMessage) {
      setHasNewMessage(false)
    }
  }, [hasNewMessage])

  // ---- auto-scroll: useLayoutEffect runs before browser processes scroll events ----

  useLayoutEffect(() => {
    if (messages.length === 0) {
      isAtBottomRef.current = true
      return
    }

    const lastMessage = messages[messages.length - 1]

    if (lastMessage.role === 'user' || isAtBottomRef.current) {
      bottomRef.current?.scrollIntoView({ behavior: 'instant' })
    } else {
      setHasNewMessage(true)
    }
  }, [messages])

  // ---- mount: always scroll to bottom if messages already loaded ----

  useEffect(() => {
    if (messages.length > 0) {
      scrollToBottom('instant')
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  // ---- empty state ----

  if (messages.length === 0) {
    return (
      <div className="flex h-full items-center justify-center">
        <div className="text-center animate-fade-in">
          <div className="mb-6 inline-flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-[var(--accent-cyan)]/20 to-[var(--accent-blue)]/20 shadow-2xl shadow-[var(--accent-cyan)]/20">
            <Sparkles className="h-10 w-10 text-[var(--accent-cyan)]" />
          </div>
          <h2 className="mb-2 text-2xl font-bold text-[var(--text-primary)]">开始新的对话</h2>
          <p className="text-[var(--text-muted)]">在下方输入消息开始与 AI 助手聊天</p>
          <div className="mt-8 flex items-center justify-center gap-4 text-sm text-[var(--text-muted)]">
            <span className="px-3 py-1 rounded-full bg-[var(--bg-hover)] border border-[var(--border-color)]">/new 创建话题</span>
            <span className="px-3 py-1 rounded-full bg-[var(--bg-hover)] border border-[var(--border-color)]">/list 查看列表</span>
          </div>
        </div>
      </div>
    )
  }

  // ---- main render ----

  return (
    <div className="relative h-full">
      <div
        ref={containerRef}
        onScroll={handleScroll}
        className="h-full overflow-y-auto p-6 space-y-6"
      >
        {messages.map((message) => (
          <MessageBubble key={message.id} message={message} onNavigateToSubAgent={onNavigateToSubAgent} showThinking={showThinking} />
        ))}
        <div ref={bottomRef} />
      </div>

      {/* 浮动按钮 */}
      <div className="absolute right-4 bottom-4 z-10 flex flex-col items-center gap-2 pointer-events-none">
        {showScrollToTop && (
          <button
            onClick={scrollToTop}
            className="pointer-events-auto group relative flex items-center justify-center
                       w-9 h-9 rounded-full
                       bg-[var(--bg-tertiary)]/80 backdrop-blur-md
                       border border-[var(--border-color)]
                       text-[var(--text-muted)] hover:text-[var(--accent-cyan)]
                       hover:border-[var(--accent-cyan)]/30
                       hover:shadow-[0_0_20px_var(--shadow-glow-sm)]
                       transition-all duration-300 ease-out
                       animate-fade-in"
            aria-label="回到顶部"
          >
            <ArrowUp className="h-4 w-4 transition-transform duration-300 group-hover:-translate-y-0.5" />
          </button>
        )}

        {showScrollToBottom && (
          <button
            onClick={() => scrollToBottom('smooth')}
            className="pointer-events-auto group relative flex items-center justify-center
                       w-9 h-9 rounded-full
                       bg-[var(--bg-tertiary)]/80 backdrop-blur-md
                       border border-[var(--border-color)]
                       text-[var(--text-muted)] hover:text-[var(--accent-cyan)]
                       hover:border-[var(--accent-cyan)]/30
                       hover:shadow-[0_0_20px_var(--shadow-glow-sm)]
                       transition-all duration-300 ease-out
                       animate-fade-in"
            aria-label="回到底部"
          >
            <ArrowDown className={`h-4 w-4 transition-transform duration-300 group-hover:translate-y-0.5 ${hasNewMessage ? 'animate-bounce' : ''}`} />

            {hasNewMessage && (
              <span className="absolute -top-0.5 -right-0.5 flex h-2.5 w-2.5">
                <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-[var(--accent-cyan)]/60"></span>
                <span className="relative inline-flex h-2.5 w-2.5 rounded-full bg-[var(--accent-cyan)]"></span>
              </span>
            )}
          </button>
        )}
      </div>
    </div>
  )
}
