import { loggerService } from '@logger'
import { COMPOSER_FILE_KIND, type PastedTextFileMetadata } from '@renderer/types/file'
import { getFileExtension, isSupportedFile } from '@renderer/utils/file'
import { type ComposerAttachment, toComposerAttachment } from '@renderer/utils/message/composerAttachment'

import { LONG_TEXT_PASTE_THRESHOLD } from '../composerPaste'

const logger = loggerService.withContext('pasteHandling')

// Track last focused component
type ComponentType = 'inputbar' | 'messageEditor' | 'TranslatePage' | null
let lastFocusedComponent: ComponentType = 'inputbar' // Default to inputbar

// 处理函数类型
type PasteHandler = (event: ClipboardEvent) => Promise<boolean>

// 处理函数存储
const handlers: {
  inputbar?: PasteHandler
  messageEditor?: PasteHandler
} = {}

// 初始化标志
let isInitialized = false

/**
 * 处理粘贴事件的通用服务
 * 处理各种粘贴场景，包括文本和文件
 */
export const handlePaste = async (
  event: ClipboardEvent,
  supportExts: string[],
  setFiles: (updater: (prevFiles: ComposerAttachment[]) => ComposerAttachment[]) => void,
  setText?: (text: string) => void,
  text?: string,
  resizeTextArea?: () => void,
  t?: (key: string) => string
): Promise<boolean> => {
  try {
    // 优先处理文本粘贴
    const clipboardText = event.clipboardData?.getData('text')
    if (clipboardText) {
      // 1. 文本粘贴
      if (clipboardText.length > LONG_TEXT_PASTE_THRESHOLD) {
        // 长文本直接转文件，阻止默认粘贴
        event.preventDefault()

        const tempFilePath = await window.api.file.createTempFile('pasted_text.txt')
        await window.api.file.write(tempFilePath, clipboardText)
        const selectedFile = await window.api.file.get(tempFilePath)
        if (selectedFile) {
          const pastedTextFile: PastedTextFileMetadata = {
            ...selectedFile,
            origin_name: t?.('chat.input.pasted_text_file_name') ?? selectedFile.origin_name,
            composerFileKind: COMPOSER_FILE_KIND.PASTED_TEXT
          }
          setFiles((prevFiles) => [...prevFiles, toComposerAttachment(pastedTextFile)])
          if (setText && text) setText(text) // 保持输入框内容不变
          if (resizeTextArea) setTimeout(() => resizeTextArea(), 50)
        }
        return true
      }
      // 短文本走默认粘贴行为，直接返回
      return false
    }
    // 2. 文件/图片粘贴（仅在无文本时处理）
    if (event.clipboardData?.files && event.clipboardData.files.length > 0) {
      event.preventDefault()
      const extensionSet = new Set(supportExts)
      try {
        for (const file of event.clipboardData.files) {
          // 使用新的API获取文件路径
          const filePath = window.api.file.getPathForFile(file)

          // 如果没有路径，可能是剪贴板中的图像数据
          if (!filePath) {
            // 图像生成也支持图像编辑
            if (file.type.startsWith('image/') && supportExts.includes(getFileExtension(file.name))) {
              const tempFilePath = await window.api.file.createTempFile(file.name)
              const arrayBuffer = await file.arrayBuffer()
              const uint8Array = new Uint8Array(arrayBuffer)
              await window.api.file.write(tempFilePath, uint8Array)
              const selectedFile = await window.api.file.get(tempFilePath)
              if (selectedFile) {
                setFiles((prevFiles) => [...prevFiles, toComposerAttachment(selectedFile)])
                break
              }
            } else {
              if (t) {
                window.toast.info(t('chat.input.file_not_supported'))
              }
            }
            continue
          }

          // 有路径的情况
          if (await isSupportedFile(filePath, extensionSet)) {
            const selectedFile = await window.api.file.get(filePath)
            if (selectedFile) {
              setFiles((prevFiles) => [...prevFiles, toComposerAttachment(selectedFile)])
            }
          } else {
            if (t) {
              window.toast.info(t('chat.input.file_not_supported'))
            }
          }
        }
      } catch (error) {
        logger.error('onPaste:', error as Error)
        if (t) {
          window.toast.error(t('chat.input.file_error'))
        }
      }
      return true
    }
    // 其他情况默认粘贴
    return false
  } catch (error) {
    logger.error('handlePaste error:', error as Error)
    return false
  }
}

/**
 * 设置最后聚焦的组件
 */
export const setLastFocusedComponent = (component: ComponentType) => {
  lastFocusedComponent = component
}

/**
 * 获取最后聚焦的组件
 */
export const getLastFocusedComponent = (): ComponentType => {
  return lastFocusedComponent
}

/**
 * 初始化全局粘贴事件监听
 * 应用启动时只调用一次
 */
export const init = () => {
  if (isInitialized) return

  // 添加全局粘贴事件监听
  document.addEventListener('paste', async (event) => {
    await handleGlobalPaste(event)
  })

  isInitialized = true
  logger.verbose('Global paste handler initialized')
}

/**
 * 注册组件的粘贴处理函数
 */
export const registerHandler = (component: ComponentType, handler: PasteHandler) => {
  if (!component) return

  // Only log and update if the handler actually changes
  if (!handlers[component] || handlers[component] !== handler) {
    handlers[component] = handler
  }
}

/**
 * 移除组件的粘贴处理函数
 */
export const unregisterHandler = (component: ComponentType) => {
  if (!component || !handlers[component]) return

  delete handlers[component]
}

/**
 * 全局粘贴处理函数，根据最后聚焦的组件路由粘贴事件
 */
const handleGlobalPaste = async (event: ClipboardEvent): Promise<boolean> => {
  // 如果当前有活动元素且是输入区域，不执行全局处理
  const activeElement = document.activeElement
  if (
    activeElement &&
    (activeElement.tagName === 'INPUT' ||
      activeElement.tagName === 'TEXTAREA' ||
      activeElement.getAttribute('contenteditable') === 'true')
  ) {
    return false
  }

  // 根据最后聚焦的组件调用相应处理程序
  if (lastFocusedComponent && handlers[lastFocusedComponent]) {
    const handler = handlers[lastFocusedComponent]
    if (handler) {
      return await handler(event)
    }
  }

  // 如果没有匹配的处理程序，默认使用inputbar处理
  if (handlers.inputbar) {
    const handler = handlers.inputbar
    if (handler) {
      return await handler(event)
    }
  }

  return false
}

export default {
  handlePaste,
  setLastFocusedComponent,
  getLastFocusedComponent,
  init,
  registerHandler,
  unregisterHandler
}
