import { Send, Loader2, Square, Sparkles, Eye, Paperclip, X, FileIcon, ImageIcon, MusicIcon, VideoIcon } from 'lucide-react'
import { useState, useRef, useEffect } from 'react'
import type { Attachment } from '../../types/protocol'

const MAX_FILE_SIZE = 50 * 1024 * 1024 // 50MB

interface MessageInputProps {
  onSend: (content: string, attachments: Attachment[]) => void
  onStop?: () => void
  disabled?: boolean
  isLoading?: boolean
  placeholder?: string
  isReadOnly?: boolean
  channelName?: string
}

interface FileAttachment {
  file: File
  attachment: Attachment
  preview?: string // 用于图片预览
}

// 根据 MIME 类型判断 media_type
function getMediaType(mimeType: string): string {
  if (mimeType.startsWith('image/')) return 'image'
  if (mimeType.startsWith('audio/')) return 'audio'
  if (mimeType.startsWith('video/')) return 'video'
  return 'file'
}

export function MessageInput({
  onSend,
  onStop,
  disabled = false,
  isLoading = false,
  placeholder = '输入消息...按 / 查看命令',
  isReadOnly = false,
  channelName,
}: MessageInputProps) {
  const [content, setContent] = useState('')
  const [attachments, setAttachments] = useState<FileAttachment[]>([])
  const [isDragging, setIsDragging] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const textareaRef = useRef<HTMLTextAreaElement>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const wasLoadingRef = useRef(false)

  useEffect(() => {
    const textarea = textareaRef.current
    if (textarea) {
      textarea.style.height = 'auto'
      textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`
    }
  }, [content])

  // 当 isLoading 从 true 变为 false 时，自动聚焦输入框
  useEffect(() => {
    if (wasLoadingRef.current && !isLoading && !isReadOnly) {
      textareaRef.current?.focus()
    }
    wasLoadingRef.current = isLoading
  }, [isLoading, isReadOnly])

  // 处理文件选择
  const handleFileSelect = async (files: FileList | null) => {
    if (!files) return
    setError(null)

    const newAttachments: FileAttachment[] = []
    for (const file of Array.from(files)) {
      // 检查文件大小
      if (file.size > MAX_FILE_SIZE) {
        setError(`文件 "${file.name}" 超过 50MB 限制`)
        continue
      }

      // 读取文件为 base64
      const base64 = await readFileAsBase64(file)
      const mimeType = file.type || 'application/octet-stream'
      const mediaType = getMediaType(mimeType)

      const attachment: Attachment = {
        path: file.name,
        media_type: mediaType,
        mime_type: mimeType,
        content_base64: base64,
        file_name: file.name,
      }

      const fileAttachment: FileAttachment = {
        file,
        attachment,
        preview: mediaType === 'image' ? base64 : undefined,
      }

      newAttachments.push(fileAttachment)
    }

    setAttachments(prev => [...prev, ...newAttachments])
  }

  // 读取文件为 base64
  const readFileAsBase64 = (file: File): Promise<string> => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = () => {
        const result = reader.result as string
        // 移除 data:xxx;base64, 前缀
        const base64 = result.split(',')[1]
        resolve(base64)
      }
      reader.onerror = reject
      reader.readAsDataURL(file)
    })
  }

  // 点击附件按钮
  const handleAttachClick = () => {
    fileInputRef.current?.click()
  }

  // 删除附件
  const handleRemoveAttachment = (index: number) => {
    setAttachments(prev => prev.filter((_, i) => i !== index))
  }

  // 粘贴事件处理
  const handlePaste = async (e: React.ClipboardEvent) => {
    if (disabled || isReadOnly) return

    const clipboardData = e.clipboardData
    const items = clipboardData.items

    // 检查是否有文件（图片或其他文件）
    const files: File[] = []
    for (const item of Array.from(items)) {
      if (item.kind === 'file') {
        const file = item.getAsFile()
        if (file) {
          files.push(file)
        }
      }
    }

    // 如果有文件，处理文件并阻止默认粘贴行为
    if (files.length > 0) {
      e.preventDefault()
      // 直接处理文件数组
      setError(null)
      for (const file of files) {
        if (file.size > MAX_FILE_SIZE) {
          setError(`文件 "${file.name}" 超过 50MB 限制`)
          continue
        }

        const base64 = await readFileAsBase64(file)
        const mimeType = file.type || 'application/octet-stream'
        const mediaType = getMediaType(mimeType)

        const attachment: Attachment = {
          path: file.name,
          media_type: mediaType,
          mime_type: mimeType,
          content_base64: base64,
          file_name: file.name,
        }

        const fileAttachment: FileAttachment = {
          file,
          attachment,
          preview: mediaType === 'image' ? base64 : undefined,
        }

        setAttachments(prev => [...prev, fileAttachment])
      }
    }
    // 否则让默认的文本粘贴行为继续
  }

  // 拖拽事件
  const handleDragEnter = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    if (!disabled && !isReadOnly) {
      setIsDragging(true)
    }
  }

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    // 检查是否真的离开了拖拽区域（而不是进入子元素）
    const relatedTarget = e.relatedTarget as Node | null
    const currentTarget = e.currentTarget
    if (!relatedTarget || !currentTarget.contains(relatedTarget)) {
      setIsDragging(false)
    }
  }

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
  }

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setIsDragging(false)
    if (!disabled && !isReadOnly) {
      handleFileSelect(e.dataTransfer.files)
    }
  }

  const handleSend = () => {
    const hasContent = content.trim() || attachments.length > 0
    if (hasContent && !disabled && !isReadOnly) {
      onSend(
        content.trim(),
        attachments.map(a => a.attachment)
      )
      setContent('')
      setAttachments([])
      setError(null)
      if (textareaRef.current) {
        textareaRef.current.style.height = 'auto'
      }
    }
  }

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      handleSend()
    }
  }

  // 获取附件图标
  const getAttachmentIcon = (mediaType: string) => {
    switch (mediaType) {
      case 'image':
        return <ImageIcon className="h-4 w-4" />
      case 'audio':
        return <MusicIcon className="h-4 w-4" />
      case 'video':
        return <VideoIcon className="h-4 w-4" />
      default:
        return <FileIcon className="h-4 w-4" />
    }
  }

  // 只读模式：显示提示占位符
  if (isReadOnly) {
    return (
      <div className="border-t border-[var(--border-color)] bg-[var(--bg-secondary)]/80 backdrop-blur-md p-4">
        <div className="max-w-5xl mx-auto">
          <div className="rounded-xl border border-[var(--border-color)] bg-[var(--bg-tertiary)]/50 px-4 py-5 text-center">
            <div className="flex flex-col items-center gap-2">
              <div className="flex items-center gap-2 text-[var(--text-secondary)]">
                <Eye className="h-5 w-5" />
                <span className="font-medium">只读模式</span>
              </div>
              <p className="text-sm text-[var(--text-muted)]">
                {channelName ? (
                  <>{channelName} 通道仅支持查看历史消息</>
                ) : (
                  '当前通道仅支持查看历史消息'
                )}
              </p>
              <p className="text-xs text-[var(--text-muted)]">
                请切换至 WebSocket 通道进行输入
              </p>
            </div>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className="border-t border-[var(--border-color)] bg-[var(--bg-secondary)]/80 backdrop-blur-md p-4">
      <div className="max-w-5xl mx-auto">
        {/* 错误提示 */}
        {error && (
          <div className="mb-2 rounded-lg bg-red-500/10 border border-red-500/20 px-3 py-2 text-sm text-red-400">
            {error}
          </div>
        )}

        {/* 附件预览列表 */}
        {attachments.length > 0 && (
          <div className="mb-2 flex flex-wrap gap-2">
            {attachments.map((att, index) => (
              <div
                key={index}
                className="flex items-center gap-2 rounded-lg border border-[var(--border-color)] bg-[var(--bg-tertiary)] px-2 py-1.5 text-sm"
              >
                {att.preview ? (
                  <img
                    src={`data:${att.attachment.mime_type};base64,${att.preview}`}
                    alt={att.attachment.file_name}
                    className="h-8 w-8 rounded object-cover"
                  />
                ) : (
                  <div className="h-8 w-8 rounded bg-[var(--bg-hover)] flex items-center justify-center text-[var(--text-secondary)]">
                    {getAttachmentIcon(att.attachment.media_type)}
                  </div>
                )}
                <span className="text-[var(--text-secondary)] max-w-[120px] truncate">
                  {att.attachment.file_name}
                </span>
                <button
                  onClick={() => handleRemoveAttachment(index)}
                  className="text-[var(--text-muted)] hover:text-red-400 transition-colors"
                >
                  <X className="h-4 w-4" />
                </button>
              </div>
            ))}
          </div>
        )}

        {/* 输入区域 */}
        <div
          className={`flex gap-3 items-center relative ${isDragging ? 'ring-2 ring-[var(--accent-cyan)]/50 rounded-xl' : ''}`}
          onDragEnter={handleDragEnter}
          onDragLeave={handleDragLeave}
          onDragOver={handleDragOver}
          onDrop={handleDrop}
        >
          {/* 拖拽提示 */}
          {isDragging && (
            <div className="absolute inset-0 rounded-xl bg-[var(--accent-cyan)]/10 border-2 border-[var(--accent-cyan)]/50 flex items-center justify-center z-10">
              <div className="text-[var(--accent-cyan)] text-sm font-medium">
                拖放文件到这里
              </div>
            </div>
          )}

          {/* 附件按钮 */}
          <button
            onClick={handleAttachClick}
            disabled={disabled}
            className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl border border-[var(--border-color)] bg-[var(--bg-tertiary)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:border-[var(--border-color)] disabled:opacity-50 transition-all"
          >
            <Paperclip className="h-5 w-5" />
          </button>
          <input
            ref={fileInputRef}
            type="file"
            multiple
            className="hidden"
            onChange={(e) => handleFileSelect(e.target.files)}
          />

          {/* 输入框 */}
          <div className="flex-1 relative flex items-center">
            <textarea
              ref={textareaRef}
              value={content}
              onChange={(e) => setContent(e.target.value)}
              onKeyDown={handleKeyDown}
              onPaste={handlePaste}
              placeholder={placeholder}
              disabled={disabled}
              rows={1}
              className="w-full resize-none rounded-xl border border-[var(--border-color)] bg-[var(--bg-tertiary)] px-4 py-3 pr-12 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-muted)] focus:border-[var(--accent-cyan)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--focus-ring)] disabled:opacity-50 transition-all self-center scrollbar-hide"
            />
            <Sparkles className="absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[var(--text-muted)] pointer-events-none" />
          </div>

          {/* 发送/停止按钮 */}
          {isLoading && onStop ? (
            <button
              onClick={onStop}
              title="停止执行"
              className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-red-500/10 border border-red-500/20 text-red-400 hover:bg-red-500/20 hover:text-red-300 transition-all"
            >
              <Square className="h-4 w-4" />
            </button>
          ) : (
            <button
              onClick={handleSend}
              disabled={disabled || (!content.trim() && attachments.length === 0)}
              className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-gradient-to-r from-[var(--accent-cyan)] to-[var(--accent-blue)] text-white shadow-lg shadow-[var(--accent-cyan)]/20 hover:shadow-xl hover:shadow-[var(--accent-cyan)]/30 hover:scale-105 disabled:opacity-50 disabled:hover:scale-100 disabled:cursor-not-allowed transition-all"
            >
              {disabled ? (
                <Loader2 className="h-4 w-4 animate-spin" />
              ) : (
                <Send className="h-4 w-4" />
              )}
            </button>
          )}
        </div>

        {/* 提示 */}
        <div className="mt-2 text-center text-xs text-[var(--text-muted)]">
          按 Enter 发送，Shift+Enter 换行 · 支持拖拽/粘贴文件 · 最大 50MB
        </div>
      </div>
    </div>
  )
}
