import React, { useState, useRef, useEffect, useCallback } from 'react'
import { BsFolder2, BsClockHistory } from 'react-icons/bs'
import { Contact, Message } from '../types'
import { MessageBubble } from '../components/ChatWindow/MessageBubble'
import { formatFullDateTime } from '../utils/timeUtils'
import { isNotificationLikeMessage } from '../utils/messageTypes'
import { formatConversationRemark } from '../utils/conversationRemark'
import { getDefaultAvatar, getSessionAvatar } from '../utils/avatarUtils'

interface ChatPageProps {
  contacts: Contact[]
  activeContact: Contact | undefined
  activeContactId: number | null
  messages: Record<number, Message[]>
  isLoadingMessages: boolean
  uploadProgress: { [key: string]: number }
  token: string
  currentUserId: number | null
  currentUserName: string
  inputValue: string
  setInputValue: (value: string) => void
  onSendMessage: (content: string) => Promise<void>
  onFileSelect: (file: File) => void
  onShowChatSearch: () => void
  onContextMenu: (e: React.MouseEvent, msgId: number) => void
  setMessages: React.Dispatch<React.SetStateAction<Record<number, Message[]>>>
  isLoadingMore: boolean
  hasMoreMessages: Record<number, boolean>
  onLoadMoreMessages: (contactId: number) => void
}

const MAX_FILE_SIZE_BYTES = 50 * 1024 * 1024

function isFileSizeAllowed(file: File): boolean {
  if (file.size > MAX_FILE_SIZE_BYTES) {
    alert('文件大小不能超过 50MB')
    return false
  }
  return true
}

function getFileFromClipboardEvent(e: React.ClipboardEvent): File | null {
  const dt = e.clipboardData
  if (!dt) return null
  if (dt.files.length > 0) {
    return dt.files[0]
  }
  for (let i = 0; i < dt.items.length; i++) {
    const item = dt.items[i]
    if (item.kind === 'file') {
      const f = item.getAsFile()
      if (f) return f
    }
  }
  return null
}

function dragEventHasFilePayload(e: React.DragEvent): boolean {
  const types = e.dataTransfer?.types
  if (!types) return false
  for (let i = 0; i < types.length; i++) {
    if (types[i] === 'Files') return true
  }
  return false
}

export const ChatPage: React.FC<ChatPageProps> = ({
  contacts,
  activeContact,
  activeContactId,
  messages,
  isLoadingMessages,
  uploadProgress,
  token,
  currentUserId,
  currentUserName,
  inputValue,
  setInputValue,
  onSendMessage,
  onFileSelect,
  onShowChatSearch,
  onContextMenu,
  setMessages,
  isLoadingMore,
  hasMoreMessages,
  onLoadMoreMessages
}) => {
  const messagesEndRef = useRef<HTMLDivElement>(null)
  const chatContainerRef = useRef<HTMLDivElement>(null)
  const isFirstLoadRef = useRef(true)
  const prevScrollHeightRef = useRef(0)
  const isLoadingMoreRef = useRef(false)
  const [isFileDragOver, setIsFileDragOver] = useState(false)

  useEffect(() => {
    const container = chatContainerRef.current
    if (!container) return

    if (isLoadingMoreRef.current) {
      const newScrollHeight = container.scrollHeight
      const addedHeight = newScrollHeight - prevScrollHeightRef.current
      if (addedHeight > 0) {
        container.scrollTop = addedHeight
      }
      isLoadingMoreRef.current = false
      prevScrollHeightRef.current = container.scrollHeight
      return
    }

    if (isFirstLoadRef.current) {
      messagesEndRef.current?.scrollIntoView({ behavior: 'instant' })
      isFirstLoadRef.current = false
    } else {
      messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
    }
    prevScrollHeightRef.current = container.scrollHeight
  }, [messages])

  useEffect(() => {
    isFirstLoadRef.current = true
    prevScrollHeightRef.current = 0
    messagesEndRef.current?.scrollIntoView({ behavior: 'instant' })
  }, [activeContactId])

  const handleScroll = useCallback(() => {
    const container = chatContainerRef.current
    if (!container || !activeContactId) return

    if (container.scrollTop < 50 && hasMoreMessages[activeContactId] && !isLoadingMore) {
      prevScrollHeightRef.current = container.scrollHeight
      isLoadingMoreRef.current = true
      onLoadMoreMessages(activeContactId)
    }
  }, [activeContactId, hasMoreMessages, isLoadingMore, onLoadMoreMessages])

  useEffect(() => {
    const container = chatContainerRef.current
    if (!container) return
    container.addEventListener('scroll', handleScroll)
    return () => container.removeEventListener('scroll', handleScroll)
  }, [handleScroll])

  const handleSend = async () => {
    if (!inputValue.trim() || !activeContactId) return
    try {
      await onSendMessage(inputValue)
      setInputValue('')
    } catch (error: any) {
      alert('发送消息失败：' + (error.message || '网络错误'))
    }
  }

  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]
    if (!file) return
    if (!isFileSizeAllowed(file)) return
    onFileSelect(file)
    event.target.value = ''
  }

  const handlePaste = useCallback(
    (e: React.ClipboardEvent<HTMLTextAreaElement>) => {
      const file = getFileFromClipboardEvent(e)
      if (!file) return
      e.preventDefault()
      if (!isFileSizeAllowed(file)) return
      onFileSelect(file)
    },
    [onFileSelect]
  )

  const isAppNotificationSession = activeContactId != null && activeContactId < 0

  const handleChatDragEnter = useCallback(
    (e: React.DragEvent) => {
      if (isAppNotificationSession) return
      if (!dragEventHasFilePayload(e)) return
      e.preventDefault()
      setIsFileDragOver(true)
    },
    [isAppNotificationSession]
  )

  const handleChatDragLeave = useCallback(
    (e: React.DragEvent) => {
      if (isAppNotificationSession) return
      if (!dragEventHasFilePayload(e)) return
      e.preventDefault()
      const el = e.currentTarget as HTMLElement
      const rel = e.relatedTarget as Node | null
      if (rel && el.contains(rel)) return
      setIsFileDragOver(false)
    },
    [isAppNotificationSession]
  )

  const handleChatDragOver = useCallback(
    (e: React.DragEvent) => {
      if (isAppNotificationSession) return
      if (!dragEventHasFilePayload(e)) return
      e.preventDefault()
      e.dataTransfer.dropEffect = 'copy'
    },
    [isAppNotificationSession]
  )

  const handleChatDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault()
      setIsFileDragOver(false)
      if (isAppNotificationSession) return
      const file = e.dataTransfer.files[0]
      if (!file) return
      if (!isFileSizeAllowed(file)) return
      onFileSelect(file)
    },
    [isAppNotificationSession, onFileSelect]
  )

  if (contacts.length === 0) {
    return (
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#999', flexDirection: 'column' }}>
        <div style={{ fontSize: '60px', marginBottom: '20px', opacity: 0.3 }}>💬</div>
        <div>暂无联系人</div>
      </div>
    )
  }

  if (!activeContact) {
    return (
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#ccc', flexDirection: 'column' }}>
        <div style={{ fontSize: '100px', marginBottom: '20px', opacity: 0.2 }}>💬</div>
        <div style={{ fontSize: '18px' }}>韫珠IM</div>
      </div>
    )
  }

  const headerRemark = formatConversationRemark(activeContact.remarks)

  return (
    <div
      style={{
        flex: 1,
        display: 'flex',
        flexDirection: 'column',
        minHeight: 0,
        minWidth: 0,
        position: 'relative',
        boxSizing: 'border-box',
        outline: isFileDragOver ? '2px dashed #1aad19' : 'none',
        outlineOffset: isFileDragOver ? -2 : 0
      }}
      onDragEnter={handleChatDragEnter}
      onDragLeave={handleChatDragLeave}
      onDragOver={handleChatDragOver}
      onDrop={handleChatDrop}
    >
      <div style={{ padding: '0 20px', height: '60px', display: 'flex', alignItems: 'center', borderBottom: '1px solid #e7e7e7', WebkitAppRegion: 'drag' } as React.CSSProperties}>
        <div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', WebkitAppRegion: 'no-drag' } as React.CSSProperties}>
          <span style={{ fontWeight: 'bold', fontSize: '16px' }}>
            {activeContact.name}
          </span>
          {headerRemark && (
            <span
              style={{
                fontSize: '12px',
                color: '#d97706',
                marginLeft: '2px',
                whiteSpace: 'nowrap',
                display: 'inline-block'
              }}
              title={headerRemark}
            >
              {headerRemark}
            </span>
          )}
        </div>
      </div>
      
      <div 
        ref={chatContainerRef}
        style={{ flex: 1, padding: '20px', overflowY: 'auto', overflowX: 'hidden' }}
      >
        {isLoadingMessages && activeContactId && !messages[activeContactId] ? (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#999' }}>
            加载消息中...
          </div>
        ) : activeContactId && (messages[activeContactId] || []).length === 0 ? (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#999', flexDirection: 'column' }}>
            <div style={{ fontSize: '60px', marginBottom: '20px', opacity: 0.3 }}>💬</div>
            <div>暂无消息</div>
          </div>
        ) : activeContactId ? (
          <>
            {hasMoreMessages[activeContactId] && (
              <div style={{ textAlign: 'center', padding: '10px', color: '#999', fontSize: '12px' }}>
                {isLoadingMore ? '加载中...' : '向上滚动加载更多'}
              </div>
            )}
            {!hasMoreMessages[activeContactId] && (messages[activeContactId] || []).length > 0 && (
              <div style={{ textAlign: 'center', padding: '10px', color: '#ccc', fontSize: '12px' }}>
                已加载全部消息
              </div>
            )}
            {(messages[activeContactId] || []).map((msg) => {
            const isMediaMessage = msg.type === 'image' || msg.type === 'video' || msg.type === 'file' || 
                                 msg.content_type === 'IMAGE' || msg.content_type === 'VIDEO' || msg.content_type === 'FILE'
            const isNotificationMessage =
              msg.type === 'notification' ||
              isNotificationLikeMessage(msg.messageType, msg.content_type)
            
            return (
              <div
                key={msg.id}
                data-message-id={msg.id}
                style={{
                  display: 'flex',
                  flexDirection: 'column',
                  marginBottom: '15px'
                }}
              >
                <div style={{ 
                  display: 'flex',
                  justifyContent: 'center',
                  alignItems: 'center',
                  marginBottom: '8px'
                }}>
                  <div style={{ 
                    fontSize: '11px', 
                    color: '#999',
                    backgroundColor: 'rgba(0, 0, 0, 0.05)',
                    padding: '2px 8px',
                    borderRadius: '4px'
                  }}>
                    {formatFullDateTime(msg.timestamp)}
                  </div>
                </div>

                {isNotificationMessage ? (
                  <div
                    style={{
                      display: 'flex',
                      justifyContent: msg.isSelf ? 'flex-end' : 'flex-start',
                      alignItems: 'flex-start',
                      width: '100%'
                    }}
                  >
                    {!msg.isSelf && activeContact && (
                      <div style={{ width: '35px', height: '35px', borderRadius: '50%', marginRight: '10px', overflow: 'hidden', cursor: 'pointer', flexShrink: 0 }}>
                        {getSessionAvatar(activeContact.id, activeContact.name, 35)}
                      </div>
                    )}

                    <div
                      style={{
                        flex: 1,
                        maxWidth: '80%',
                        minWidth: 0,
                        position: 'relative',
                        overflow: 'hidden'
                      }}
                    >
                      <div
                        onContextMenu={(e) => onContextMenu(e, msg.id)}
                        className={msg.isSelf ? 'bubble-self' : 'bubble-other'}
                        style={{
                          padding: '0',
                          borderRadius: '4px',
                          backgroundColor: 'transparent',
                          border: 'none',
                          position: 'relative',
                          cursor: 'default',
                          color: '#000',
                          fontSize: '14px',
                          boxShadow: 'none'
                        }}
                      >
                        <MessageBubble
                          msg={msg}
                          uploadProgress={uploadProgress}
                          activeContactId={activeContactId}
                          currentUserId={currentUserId}
                          token={token}
                          setMessages={setMessages}
                        />
                      </div>
                    </div>

                    {msg.isSelf && (
                      <div style={{ width: '35px', height: '35px', borderRadius: '50%', marginLeft: '10px', overflow: 'hidden', cursor: 'pointer', fontSize: '35px', flexShrink: 0 }}>
                        {getDefaultAvatar(currentUserId || 0, currentUserName, { sizePx: 35 })}
                      </div>
                    )}
                  </div>
                ) : (
                  <div style={{
                    display: 'flex',
                    justifyContent: msg.isSelf ? 'flex-end' : 'flex-start',
                    alignItems: 'flex-start',
                    width: '100%'
                  }}>
                    {!msg.isSelf && activeContact && (
                      <div style={{ width: '35px', height: '35px', borderRadius: '50%', marginRight: '10px', overflow: 'hidden', cursor: 'pointer', flexShrink: 0 }}>
                        {getSessionAvatar(activeContact.id, activeContact.name, 35)}
                      </div>
                    )}
                    
                    <div style={{ maxWidth: '70%', position: 'relative', minWidth: 0, overflow: 'hidden' }}>
                      <div
                        onContextMenu={(e) => onContextMenu(e, msg.id)}
                        className={`${msg.isSelf ? 'bubble-self' : 'bubble-other'} ${isMediaMessage ? 'bubble-media' : ''}`}
                        style={{
                          padding: isMediaMessage ? '0' : '10px',
                          borderRadius: '4px',
                          backgroundColor: msg.isSelf ? '#95ec69' : '#ffffff',
                          border: '1px solid #e7e7e7',
                          position: 'relative',
                          cursor: 'default',
                          color: '#000',
                          fontSize: '14px',
                          boxShadow: '0 1px 1px rgba(0,0,0,0.05)',
                          display: isMediaMessage ? 'inline-block' : undefined
                        }}
                      >
                        <MessageBubble
                          msg={msg}
                          uploadProgress={uploadProgress}
                          activeContactId={activeContactId}
                          currentUserId={currentUserId}
                          token={token}
                          setMessages={setMessages}
                        />
                      </div>
                    </div>

                    {msg.isSelf && (
                      <div style={{ width: '35px', height: '35px', borderRadius: '50%', marginLeft: '10px', overflow: 'hidden', cursor: 'pointer', fontSize: '35px', flexShrink: 0 }}>
                        {getDefaultAvatar(currentUserId || 0, currentUserName, { sizePx: 35 })}
                      </div>
                    )}
                  </div>
                )}
              </div>
            )
          })}
          </>
        ) : null}
        <div ref={messagesEndRef} />
      </div>

      {isAppNotificationSession ? (
        <div
          style={{
            borderTop: '1px solid #e7e7e7',
            backgroundColor: '#ffffff',
            padding: '10px 15px',
            display: 'flex',
            alignItems: 'center',
            gap: '15px'
          }}
        >
          <BsClockHistory
            className="toolbar-icon"
            title="聊天记录"
            onClick={(e) => {
              e.preventDefault()
              e.stopPropagation()
              onShowChatSearch()
            }}
            style={{ cursor: 'pointer' }}
          />
        </div>
      ) : (
        <div style={{ height: '180px', borderTop: '1px solid #e7e7e7', backgroundColor: '#ffffff', display: 'flex', flexDirection: 'column' }}>
          <div style={{ padding: '10px 15px', display: 'flex', gap: '15px' }}>
            <label htmlFor="file-input" style={{ cursor: 'pointer' }}>
              <BsFolder2 className="toolbar-icon" title="发送文件" />
            </label>
            <input
              type="file"
              id="file-input"
              style={{ display: 'none' }}
              onChange={handleFileSelect}
              accept="image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.zip,.rar,.ppt,.pptx"
            />
            <BsClockHistory
              className="toolbar-icon"
              title="聊天记录"
              onClick={(e) => {
                e.preventDefault()
                e.stopPropagation()
                onShowChatSearch()
              }}
              style={{ cursor: 'pointer' }}
            />
          </div>

          <textarea
            style={{
              flex: 1,
              border: 'none',
              resize: 'none',
              padding: '0 20px',
              outline: 'none',
              fontSize: '14px',
              fontFamily: 'inherit',
              lineHeight: '1.5'
            }}
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
            onPaste={handlePaste}
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault()
                handleSend()
              }
            }}
          />
          <div style={{ padding: '10px 20px', display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
            <div style={{ fontSize: '12px', color: '#999', marginRight: '10px' }}>
              按 Enter 发送
            </div>
            <button
              onClick={handleSend}
              style={{
                padding: '6px 24px',
                backgroundColor: '#f5f5f5',
                border: '1px solid #e7e7e7',
                borderRadius: '4px',
                cursor: 'pointer',
                color: '#606060',
                fontSize: '14px',
                transition: 'all 0.2s'
              }}
              onMouseEnter={(e) => {
                e.currentTarget.style.backgroundColor = '#1aad19'
                e.currentTarget.style.color = 'white'
              }}
              onMouseLeave={(e) => {
                e.currentTarget.style.backgroundColor = '#f5f5f5'
                e.currentTarget.style.color = '#606060'
              }}
            >
              发送(S)
            </button>
          </div>
        </div>
      )}
    </div>
  )
}
