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, subagentType?: string) => void
  showThinking?: boolean
  /** 视图标识，用于保存/恢复滚动位置。不同视图间切换时保持各自的滚动位置。 */
  viewKey?: string
}

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

  // Per-view scroll position memory
  const scrollPositionsRef = useRef<Map<string, number>>(new Map())

  const [showScrollToBottom, setShowScrollToBottom] = useState(false)
  const [newMessageCount, setNewMessageCount] = useState(0)

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

  const scrollToBottom = useCallback((behavior: ScrollBehavior = 'smooth') => {
    isAtBottomRef.current = true
    setShowScrollToBottom(false)
    setNewMessageCount(0)
    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

    // Save scroll position for current view
    const key = viewKeyRef.current
    if (key) {
      scrollPositionsRef.current.set(key, el.scrollTop)
    }

    isAtBottomRef.current = nearBottom

    // 回到底部：距底部 > 200px 时显示（同时显示回到顶部）
    const shouldShowBottom = distanceFromBottom > 200
    if (shouldShowBottom !== prevShowBottomRef.current) {
      prevShowBottomRef.current = shouldShowBottom
      setShowScrollToBottom(shouldShowBottom)
    }

    // 滚回底部时清除新消息计数
    if (nearBottom) {
      setNewMessageCount(0)
    }
  }, [])

  // ---- auto-scroll: handle view switches and message updates ----

  useLayoutEffect(() => {
    const prevKey = prevViewKeyRef.current
    const viewChanged = prevKey !== viewKey
    prevViewKeyRef.current = viewKey

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

    if (viewChanged) {
      // View switched (e.g. breadcrumb navigation): restore saved scroll position
      const key = viewKey ?? ''
      const savedPos = scrollPositionsRef.current.get(key)
      if (savedPos !== undefined && containerRef.current) {
        containerRef.current.scrollTop = savedPos
        const el = containerRef.current
        const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight
        isAtBottomRef.current = distanceFromBottom < 120
        return
      }
      // First time viewing this view: scroll to bottom
      isAtBottomRef.current = true
      bottomRef.current?.scrollIntoView({ behavior: 'instant' })
      return
    }

    // Same view, messages changed: normal auto-scroll logic
    const lastMessage = messages[messages.length - 1]

    if (lastMessage.role === 'user' || isAtBottomRef.current) {
      bottomRef.current?.scrollIntoView({ behavior: 'instant' })
    } else {
      setNewMessageCount((prev) => prev + 1)
    }
  }, [messages, viewKey])

  // ---- 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>

      {/* 浮动导航按钮 — 底部居中并排 */}
      {showScrollToBottom && (
        <div className="absolute bottom-4 left-1/2 -translate-x-1/2 z-10 flex items-center gap-2">
          {/* 回到顶部 */}
          <button
            onClick={scrollToTop}
            className="flex items-center gap-1.5 px-3 py-2 rounded-full
                       bg-[var(--bg-tertiary)]/90 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" />
            <span className="text-sm text-[var(--text-secondary)]">顶部</span>
          </button>

          {/* 回到底部 */}
          <button
            onClick={() => scrollToBottom('smooth')}
            className="flex items-center gap-2 px-4 py-2 rounded-full
                       bg-[var(--bg-tertiary)]/90 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 ${newMessageCount > 0 ? 'animate-bounce' : ''}`} />
            {newMessageCount > 0 ? (
              <span className="text-sm font-medium text-[var(--text-primary)]">
                {newMessageCount} 条新消息
              </span>
            ) : (
              <span className="text-sm text-[var(--text-secondary)]">回到最新</span>
            )}
            {newMessageCount > 0 && (
              <span className="relative flex h-2 w-2">
                <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-[var(--accent-cyan)]/60" />
                <span className="relative inline-flex h-2 w-2 rounded-full bg-[var(--accent-cyan)]" />
              </span>
            )}
          </button>
        </div>
      )}
    </div>
  )
}
