'use client'

import { useCallback, useEffect, useMemo, useState } from 'react'
import { useChat } from '@/hooks/useChat'
import { useRelay, useRelaySession } from '@/hooks/useRelay'
import {
  createChatSession,
  loadChatSessionState,
  saveChatSessionState,
  type ChatSessionMeta,
} from '@/lib/chatSessions'
import type { ChatMessage, SessionEventMessage } from '@/lib/protocol'
import { ConnectionStatus } from './ConnectionStatus'
import { MessageList } from './MessageList'
import { ChatInput } from './ChatInput'
import { ChatToolbar } from './ChatToolbar'
import { SystemStatusPanel } from './SystemStatusPanel'

interface ChatContainerProps {
  lobsterId: string
  lobsterName: string
  isOnline: boolean
  userName?: string
}

export function ChatContainer({
  lobsterId,
  lobsterName,
  isOnline,
  userName,
}: ChatContainerProps) {
  const { publishAvatarEvent } = useRelay()
  const [sessions, setSessions] = useState<ChatSessionMeta[]>([])
  const [activeSessionId, setActiveSessionId] = useState('')
  const [showStatusPanel, setShowStatusPanel] = useState(false)
  const [queueStatus, setQueueStatus] = useState<SessionEventMessage['payload'] | null>(null)
  const [pendingDispatchCount, setPendingDispatchCount] = useState(0)
  const sessionId = activeSessionId

  useEffect(() => {
    const stored = loadChatSessionState(lobsterId)
    if (stored) {
      setSessions(stored.sessions)
      setActiveSessionId(stored.activeSessionId)
      return
    }

    const initialSession = createChatSession(lobsterId, 1)
    setSessions([initialSession])
    setActiveSessionId(initialSession.id)
  }, [lobsterId])

  useEffect(() => {
    if (!activeSessionId || sessions.length === 0) return
    saveChatSessionState(lobsterId, {
      sessions,
      activeSessionId,
    })
  }, [lobsterId, sessions, activeSessionId])

  const {
    messages,
    aiTyping,
    setAiTyping,
    addMessage,
    addMessages,
    createUserMessage,
    clearAllMessages,
  } = useChat(sessionId)

  const touchSession = useCallback((targetSessionId: string) => {
    setSessions(prev =>
      prev.map(session =>
        session.id === targetSessionId
          ? { ...session, updatedAt: Date.now() }
          : session,
      ),
    )
  }, [])

  const createNextSession = useCallback(() => {
    const nextSession = createChatSession(lobsterId, sessions.length + 1)
    setSessions(prev => [nextSession, ...prev])
    setActiveSessionId(nextSession.id)
    setShowStatusPanel(false)
    return nextSession
  }, [lobsterId, sessions.length])

  const onMessage = useCallback(
    (msg: ChatMessage) => {
      addMessage(msg)
      setAiTyping(false)
      setPendingDispatchCount(prev => Math.max(0, prev - 1))
      touchSession(msg.sessionId)
    },
    [addMessage, setAiTyping, touchSession],
  )

  const onTyping = useCallback(
    (isTyping: boolean) => {
      setAiTyping(isTyping)
    },
    [setAiTyping],
  )

  const onHistoryResponse = useCallback(
    (msgs: ChatMessage[]) => {
      addMessages(msgs)
    },
    [addMessages],
  )

  const onSessionEvent = useCallback((msg: SessionEventMessage) => {
    if (msg.payload.event !== 'queue_status') return
    if (msg.payload.state === 'idle') {
      setQueueStatus(null)
      setPendingDispatchCount(0)
      return
    }
    setQueueStatus(msg.payload)
  }, [])

  const optimisticQueueStatus = useMemo<SessionEventMessage['payload'] | null>(() => {
    if (pendingDispatchCount <= 0) return null
    if (pendingDispatchCount === 1) {
      return {
        event: 'queue_status',
        state: 'processing',
        depth: 0,
      }
    }
    return {
      event: 'queue_status',
      state: 'enqueued',
      depth: pendingDispatchCount - 1,
    }
  }, [pendingDispatchCount])

  const effectiveQueueStatus = queueStatus ?? optimisticQueueStatus

  const { state, send, requestHistory, clearHistory } = useRelaySession(sessionId, {
    onMessage,
    onTyping,
    onSessionEvent,
    onHistoryResponse,
  })

  // Request history on connect
  useEffect(() => {
    if (state === 'connected') {
      publishAvatarEvent({ type: 'history_request' })
      requestHistory()
    }
  }, [state, requestHistory, publishAvatarEvent])

  useEffect(() => {
    setQueueStatus(null)
    setPendingDispatchCount(0)
    setAiTyping(false)
  }, [sessionId])

  const handleSend = useCallback(
    (text: string) => {
      const msg = createUserMessage(text)
      msg.targetLobsterId = lobsterId
      addMessage(msg)
      setPendingDispatchCount(prev => prev + 1)
      publishAvatarEvent({ type: 'message' })
      send(msg)
      setAiTyping(true)
      touchSession(msg.sessionId)
    },
    [createUserMessage, addMessage, send, lobsterId, setAiTyping, touchSession, publishAvatarEvent],
  )

  const handleToolbarAction = useCallback(
    (key: string) => {
      switch (key) {
        case 'new_conversation':
          createNextSession()
          break
        case 'system_status':
          setShowStatusPanel(prev => !prev)
          break
        case 'context':
          handleSend('/context')
          break
        case 'clear_context':
          handleSend('/clear')
          clearAllMessages()
          publishAvatarEvent({ type: 'history_clear' })
          clearHistory()
          setQueueStatus(null)
          setPendingDispatchCount(0)
          break
        case 'summary':
          handleSend('/summary')
          break
        case 'plan':
          handleSend('/plan')
          break
        case 'tools':
          handleSend('/tools')
          break
      }
    },
    [clearAllMessages, clearHistory, createNextSession, handleSend, publishAvatarEvent],
  )

  const sortedSessions = useMemo(
    () => [...sessions].sort((a, b) => b.updatedAt - a.updatedAt),
    [sessions],
  )

  const activeSession = useMemo(
    () => sessions.find(session => session.id === activeSessionId) ?? null,
    [sessions, activeSessionId],
  )

  if (!sessionId) {
    return (
      <div className="flex h-full items-center justify-center">
        <p className="text-sm text-slate-500">Loading session...</p>
      </div>
    )
  }

  return (
    <div className="flex h-full flex-col">
      <header className="grid grid-cols-[minmax(0,1fr)_minmax(220px,260px)_auto] items-center gap-3 border-b border-slate-200 px-4 py-3">
        <div className="flex items-center gap-3 pl-10 md:pl-0">
          <span
            className={`inline-block h-2.5 w-2.5 rounded-full ${isOnline ? 'bg-green-400' : 'bg-slate-300'}`}
          />
          <div>
            <p className="text-sm font-medium text-slate-900">{lobsterName}</p>
            <p className="text-xs text-slate-500">
              {userName ? `${userName} · ` : ''}
              {activeSession ? `${activeSession.title} · ` : ''}
              {isOnline ? 'Online' : 'Offline'}
            </p>
          </div>
        </div>
        <div className="flex justify-center">
          <label className="flex min-w-0 items-center gap-2 rounded-lg border border-slate-200 bg-slate-50 px-3 py-2">
            <span className="shrink-0 text-xs font-medium text-slate-500">
              会话
            </span>
            <select
              value={activeSessionId}
              onChange={event => setActiveSessionId(event.target.value)}
              className="min-w-0 flex-1 bg-transparent text-sm font-medium text-slate-700 outline-none"
            >
              {sortedSessions.map(session => (
                <option key={session.id} value={session.id}>
                  {session.title}
                </option>
              ))}
            </select>
          </label>
        </div>
        <div className="flex items-center justify-end gap-2">
          <ConnectionStatus state={state} />
          <ChatToolbar
            onAction={handleToolbarAction}
            disabled={state !== 'connected'}
          />
        </div>
      </header>

      {showStatusPanel && (
        <SystemStatusPanel
          connectionState={state}
          isLobsterOnline={isOnline}
          sessionId={sessionId}
          messageCount={messages.length}
          onClose={() => setShowStatusPanel(false)}
        />
      )}

      {effectiveQueueStatus && (
        <div className="border-b border-amber-200 bg-amber-50 px-4 py-2 text-xs text-amber-900">
          {effectiveQueueStatus.state === 'processing' && '正在处理当前消息'}
          {effectiveQueueStatus.state === 'enqueued' &&
            `消息已加入队列${typeof effectiveQueueStatus.depth === 'number' && effectiveQueueStatus.depth > 0 ? `，前方 ${effectiveQueueStatus.depth} 条` : ''}`}
        </div>
      )}

      <MessageList messages={messages} aiTyping={aiTyping} />

      <ChatInput
        onSend={handleSend}
        disabled={state !== 'connected'}
        lobsterId={lobsterId}
      />
    </div>
  )
}
