import React, { createContext, useContext, useCallback, useRef, useState } from 'react'
import type { ReactNode } from 'react'
import type { ChatInputProps, FolderPermissionConfig, GenerationStatusConfig, FooterLeftModelSwitchConfig } from './types'

export interface ChatInputContextValue {
  // Portal 主题透传（供 DropdownMenuContent/SubContent 等弹层继承）
  dataStyle?: string
  dataTheme?: string
  // 输入与发送
  value: string
  onChange: (value: string) => void
  onSend?: (value: string) => void
  disabled: boolean
  placeholder: string
  maxRows: number
  form?: string
  textareaRef: React.RefObject<HTMLTextAreaElement | null>
  setTextareaRef: (node: HTMLTextAreaElement | null) => void
  handleSend: () => void
  handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void
  sendButtonStatus: 'normal' | 'generating'
  canSend: boolean
  // 文件夹 / 更多 / 模式切换（默认操作区左侧）
  hasFolderSelected: boolean
  setHasFolderSelected: (v: boolean) => void
  handleFolderSelect: (files: FileList) => void
  handleFolderClear: () => void
  folderPermission?: FolderPermissionConfig
  footerLeftConfig?: FooterLeftModelSwitchConfig
  showFolderButton: boolean
  showMoreButton: boolean
  folderButtonLabel: string
  onFolderButtonClick?: () => void
  onFolderClear?: () => void
  onMoreButtonClick?: () => void
  addLargeIcon?: ReactNode
  folderIcon?: ReactNode
  folderOpenIcon?: ReactNode
  historyIcon?: ReactNode
  arrowDownIcon?: ReactNode
  subMenuArrowIcon?: ReactNode
  folderFillIcon?: ReactNode
  closeIcon?: ReactNode
  // 框外 / 框内显隐（默认布局用）
  showGenerationStatus?: boolean
  generationStatus?: GenerationStatusConfig
  attachments?: { files?: ReactNode; images?: ReactNode } | ReactNode
  showFooter?: boolean
}

const ChatInputContext = createContext<ChatInputContextValue | null>(null)

export function useChatInputContext() {
  const ctx = useContext(ChatInputContext)
  if (!ctx) throw new Error('ChatInput compound components must be used within ChatInput.Root')
  return ctx
}

export type ChatInputRootProps = ChatInputProps & { children?: ReactNode }

export function ChatInputRootProvider({
  value: controlledValue,
  onChange,
  onSend,
  placeholder = 'What can I help you with today?',
  disabled = false,
  maxRows = 6,
  form,
  sendButtonStatus = 'normal',
  showFooter = true,
  showFolderButton = true,
  folderButtonLabel = 'Work in a Folder',
  onFolderButtonClick,
  onFolderClear,
  folderPermission,
  showMoreButton = true,
  onMoreButtonClick,
  footerLeftConfig,
  showGenerationStatus = false,
  generationStatus,
  attachments,
  addLargeIcon,
  folderIcon,
  folderOpenIcon,
  historyIcon,
  arrowDownIcon,
  subMenuArrowIcon,
  folderFillIcon,
  closeIcon,
  dataStyle,
  dataTheme,
  children,
  ...rest
}: ChatInputRootProps) {
  const [internalValue, setInternalValue] = useState('')
  const textareaRef = useRef<HTMLTextAreaElement | null>(null)
  const [hasFolderSelected, setHasFolderSelected] = useState(false)
  const isControlled = controlledValue !== undefined
  const value = isControlled ? controlledValue : internalValue

  const setTextareaRef = useCallback((node: HTMLTextAreaElement | null) => {
    (textareaRef as React.MutableRefObject<HTMLTextAreaElement | null>).current = node
  }, [])

  const handleChange = useCallback(
    (v: string) => {
      if (!isControlled) setInternalValue(v)
      onChange?.(v)
    },
    [isControlled, onChange]
  )

  const handleSend = useCallback(() => {
    const raw = textareaRef.current?.value ?? value
    const trimmed = (raw ?? '').trim()
    if (!trimmed || disabled || !onSend) return
    onSend(trimmed)
    if (!isControlled) setInternalValue('')
    if (textareaRef.current) textareaRef.current.style.height = 'auto'
  }, [value, disabled, onSend, isControlled])

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
      if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) {
        e.preventDefault()
        handleSend()
      }
      rest.onKeyDown?.(e)
    },
    [handleSend, rest]
  )

  const handleFolderSelect = useCallback(() => setHasFolderSelected(true), [])
  const handleFolderClear = useCallback(() => {
    setHasFolderSelected(false)
    onFolderClear?.()
  }, [onFolderClear])

  const canSend = value.trim().length > 0 && !disabled

  const ctxValue: ChatInputContextValue = {
    dataStyle,
    dataTheme,
    value,
    onChange: handleChange,
    onSend,
    disabled,
    placeholder,
    maxRows,
    form,
    textareaRef,
    setTextareaRef,
    handleSend,
    handleKeyDown,
    sendButtonStatus,
    canSend,
    hasFolderSelected,
    setHasFolderSelected,
    handleFolderSelect,
    handleFolderClear,
    folderPermission,
    footerLeftConfig,
    showFolderButton,
    showMoreButton,
    folderButtonLabel,
    onFolderButtonClick,
    onFolderClear,
    onMoreButtonClick,
    addLargeIcon,
    folderIcon,
    folderOpenIcon,
    historyIcon,
    arrowDownIcon,
    subMenuArrowIcon,
    folderFillIcon,
    closeIcon,
    showGenerationStatus,
    generationStatus,
    attachments,
    showFooter,
  }

  return (
    <ChatInputContext.Provider value={ctxValue}>
      {children}
    </ChatInputContext.Provider>
  )
}

ChatInputRootProvider.displayName = 'ChatInputRootProvider'

export { ChatInputContext }
