import React, { useState, useCallback, useMemo, useEffect, useRef } from 'react'
import { cn } from '@/utils/cn'
import type { TaskArtifact } from '../types'
import { ArtifactList } from './ArtifactList'
import { isImageFile } from './utils'
import { ArtifactPreview } from './ArtifactPreview'
import { useEventStore } from '../store/useEventStore'
import { extractToolOutputArtifact } from './Preview/previewUtils'
import { useNovaKit } from '../context/useNovaKit'
import { Dialog, DialogContent } from '@/components/ui/dialog'

export interface TaskPanelProps {
  /** 文件列表 */
  artifacts: TaskArtifact[]
  /** 是否可见 */
  visible?: boolean
  /** 面板宽度 */
  width?: number | string
  /** 获取文件 URL 的函数 */
  getUrl?: (artifact: TaskArtifact) => string | Promise<string>
  /** 下载文件回调 */
  onDownload?: (artifact: TaskArtifact) => void
  /** 关闭面板回调 */
  onClose?: () => void
  /** 自定义类名 */
  className?: string
  /** 初始选中的文件 */
  initialSelected?: TaskArtifact | null
}

/**
 * 任务面板组件 - 展示图片和文件
 */
function InnerTaskPanel({
  artifacts: artifactsProp,
  visible = true,
  width = '50%',
  getUrl,
  onDownload,
  onClose,
  className,
  initialSelected,
}: TaskPanelProps) {
  const { panelMode } = useNovaKit()
  const [selectedArtifact, setSelectedArtifact] = useState<TaskArtifact | null>(initialSelected || null)
  const [fromFileList, setFromFileList] = useState(false)
  // 记录用户是否已主动选择过文件，避免流式消息到来时强制刷新预览
  const userSelectedRef = useRef(false)
  
  // 从 store 获取 events 和 artifacts
  const events = useEventStore((state) => state.events)
  const artifactsFromStore = useEventStore((state) => state.artifacts)

  // 将 tool_call 类型的 events 转换为 artifacts
  const toolCallArtifacts = useMemo((): TaskArtifact[] => {
    return events
      .filter((event) => event.event_type === 'tool_call')
      .map((event) => {
        const actionType = (event.content?.action_type as string | undefined) || undefined
        const toolName = event.content?.tool_name as string | undefined
        const actionName = event.content?.action_name as string | undefined

        const isSkillLoader =
          actionType === 'skill_loader' ||
          actionName === 'skill_loader' ||
          toolName === 'skill_loader'

        const base: TaskArtifact = {
          path: event.event_id,
          file_name: toolName || '工具调用',
          file_type: 'tool_call',
          event_type: 'tool_call',
          action_type: isSkillLoader
            ? 'skill_loader'
            : actionType || actionName || toolName,
          tool_name: toolName,
          event_arguments: event.content?.arguments,
          tool_input: event.content?.tool_input,
          tool_output: event.content?.tool_output,
        }

        // Skill Loader：按照 remix 中的逻辑，作为 Markdown 文件渲染
        if (isSkillLoader) {
          const metaToolName = (event.content?.metadata as Record<string, unknown>)?.tool_name as string | undefined
          const output = event.content?.tool_output
          const content =
            typeof output === 'string'
              ? output
              : output != null
                ? JSON.stringify(output, null, 2)
                : ''

          return {
            ...base,
            file_type: 'md',
            file_name: metaToolName || base.file_name || 'Skill 文档',
            content,
          }
        }

        const outputArtifact = extractToolOutputArtifact(base)
        if (outputArtifact) {
          return outputArtifact
        }

        return base
      })
  }, [events])

  // 合并所有 artifacts：优先使用 store 中的，然后是 props 传入的，最后是 tool_call
  const allArtifacts = useMemo(() => {
    // 如果 store 中有数据，优先使用 store
    const baseArtifacts = artifactsFromStore.length > 0 ? artifactsFromStore : artifactsProp
    const merged = [...baseArtifacts, ...toolCallArtifacts]

    // 过滤掉 http(s) URL 中，看起来不像「文件」的条目（避免普通网页链接出现在文件列表）
    return merged.filter((artifact) => {
      const path = artifact.path || artifact.file_name || ''

      // 不是 http(s) 链接的，一律保留
      if (!/^https?:\/\//.test(path)) return true

      try {
        const url = new URL(path)
        const pathname = url.pathname || ''

        // 没有路径（如 https://example.com）——按非文件处理，过滤掉
        if (!pathname || pathname === '/') return false

        // 根据路径末尾扩展名判断是否是「文件」
        const lastSegment = pathname.split('/').filter(Boolean).pop() || ''
        const match = lastSegment.match(/\.([a-zA-Z0-9]+)$/)
        if (!match) return false

        const ext = match[1].toLowerCase()
        const fileLikeExts = [
          'pdf',
          'png',
          'jpg',
          'jpeg',
          'gif',
          'webp',
          'csv',
          'ppt',
          'pptx',
          'doc',
          'docx',
          'xls',
          'xlsx',
          'md',
          'markdown',
          'txt',
          'json',
        ]

        // 只有在扩展名属于常见文件类型时，才当作文件保留；否则视为网页链接，过滤掉
        return fileLikeExts.includes(ext)
      } catch {
        // URL 解析失败时保留，避免误删正常路径
        return true
      }
    })
  }, [artifactsFromStore, artifactsProp, toolCallArtifacts])

  // 仅在 initialSelected 实际变化时同步（不依赖 allArtifacts，避免流推时反复触发）
  useEffect(() => {
    if (initialSelected) {
      userSelectedRef.current = false
      setSelectedArtifact(initialSelected)
      setFromFileList(false)
    }
  }, [initialSelected])

  // 只有「当前没有选中」时才自动选中单一文件，防止流式推送中途重置预览
  useEffect(() => {
    if (!initialSelected && allArtifacts.length === 1) {
      setSelectedArtifact(prev => prev ?? allArtifacts[0])
      setFromFileList(false)
    }
  // 用 length 而非整个 allArtifacts，避免每次新事件导致数组引用变化而触发
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [allArtifacts.length, initialSelected])

  // 筛选出所有图片
  const images = useMemo(() => {
    return allArtifacts.filter(a => isImageFile(a.path))
  }, [allArtifacts])

  // 选择文件
  const handleSelect = useCallback((artifact: TaskArtifact) => {
    userSelectedRef.current = true
    setSelectedArtifact(artifact)
    setFromFileList(true)
  }, [])

  // 返回列表
  const handleBack = useCallback(() => {
    setSelectedArtifact(null)
    setFromFileList(false)
  }, [])

  const panel = (
    <div
      className={cn(
        'h-full flex flex-col rounded-none border-l border-border',
        'transition-all duration-300 ease-in-out',
        className
      )}
      style={{ width: panelMode === 'dialog' ? '100%' : width }}
    >
      {/* 内容区 */}
      <div className="flex-1 overflow-hidden relative">
        {selectedArtifact || (allArtifacts.length === 1 && allArtifacts[0]) ? (
          <div className="absolute inset-0 animate-in fade-in-0 slide-in-from-right-4 duration-300">
            <ArtifactPreview
              artifact={selectedArtifact || allArtifacts[0]}
              fromFileList={fromFileList}
              images={images}
              getUrl={getUrl}
              onBack={allArtifacts.length > 1 ? handleBack : undefined}
              onDownload={onDownload}
              onClose={onClose}
            />
          </div>
        ) : (
          <div className="absolute inset-0 animate-in fade-in-0 slide-in-from-left-4 duration-300">
            <ArtifactList
              artifacts={allArtifacts}
              onClick={handleSelect}
              selected={selectedArtifact}
              className="h-full"
            />
          </div>
        )}
      </div>
    </div>
  )

  if (panelMode === 'dialog') {
    return (
      <Dialog open={visible} onOpenChange={(open) => { if (!open) onClose?.() }}>
        <DialogContent className="max-w-5xl w-[90vw] h-[80vh] p-0 overflow-hidden">
          {panel}
        </DialogContent>
      </Dialog>
    )
  }

  return panel
}

export const TaskPanel = React.memo(InnerTaskPanel)
export default TaskPanel

// 导出子组件
export { ArtifactList } from './ArtifactList'
export { ArtifactPreview } from './ArtifactPreview'
