import React, { useState } from 'react'
import { ChevronLeft, Download, X } from 'lucide-react'
import { cn } from '@/utils/cn'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import type { TaskArtifact, ImageAttachment } from '../types'
import { isImageFile } from './utils'
import { useNovaKit } from '../context/useNovaKit'
import { MarkdownPreview, MarkdownContent, CsvPreview, ToolCallPreview, ShellExecutePreview, UrlScriptPreview, VirtualPdfPreview } from './Preview'
import { detectToolType, ToolType, extractShellOutput, extractScriptCode, getDisplayTitle, isScriptLikeFile } from './Preview/previewUtils'
import { ImageEditor } from '@/components/image-editor'
import { TaskArtifactHtml } from '@/components/html-editor'
import PptPreview from '@/components/ppt-editor'
import { ImageAttachmentItem } from '../message-list/message-item/ImageAttachmentItem'

export interface ArtifactPreviewProps {
  /** 当前展示的文件 */
  artifact: TaskArtifact | null
  /** 所有图片（用于切换） */
  images?: TaskArtifact[]
  /** 获取文件 URL 的函数 */
  getUrl?: (artifact: TaskArtifact) => string | Promise<string>
  /** 返回按钮点击回调 */
  onBack?: () => void
  /** 是否从文件列表点击进入（用于决定是否显示悬浮工具栏） */
  fromFileList?: boolean
  /** 下载按钮点击回调 */
  onDownload?: (artifact: TaskArtifact) => void
  /** 关闭面板回调 */
  onClose?: () => void
  /** 自定义类名 */
  className?: string
}

const PREVIEW_MIME_TYPES = ['xlsx', 'xls', 'doc', 'docx']

/**
 * 文件预览组件
 */
function FilePreview({ artifact }: { artifact: TaskArtifact }) {
  const { api,conversationId } = useNovaKit()
  const [url, setUrl] = React.useState<string>('')
  const [isUrlLoading, setIsUrlLoading] = React.useState(false)

  // 检查是否是工具调用
  const isToolCall =
    artifact.event_type?.toLowerCase() === 'tool_call' ||
    artifact.file_type?.toLowerCase() === 'tool_call' ||
    artifact.file_type?.toLowerCase() === 'tool' ||
    !!artifact.tool_name

  // Skill Loader：按 Markdown 文档渲染
  const isSkillLoader = artifact.action_type === 'skill_loader'

  // 检测工具类型
  const toolType = isToolCall ? detectToolType(artifact) : ToolType.OTHER

  const isMarkdown = artifact.file_type?.toLowerCase() === 'md' ||
    artifact.file_name?.toLowerCase().endsWith('.md')

  // 仅当文件 path 变化时才重新获取 URL，避免流式推送时对象引用变化引起重复请求
  React.useEffect(() => {
    if (artifact.path && artifact.event_type !== 'tool_call') {
      setIsUrlLoading(true)
      setUrl('')
      api
        .getArtifactUrl?.(
          artifact,
          PREVIEW_MIME_TYPES.includes(artifact.file_type)
            ? {
                'x-oss-process': 'doc/preview,print_1,copy_1,export_1',
              }
            : undefined,
        )
        .then(res => {
          const originUrl = typeof res?.data === 'string' ? res.data : ''

          if (PREVIEW_MIME_TYPES.includes(artifact.file_type)) {
            // Office 文件：走文档预览服务并切到 betteryeah 域名
            const shortUrl = originUrl.replace(
              'oss-cn-hangzhou.aliyuncs.com',
              'betteryeah.com',
            )
            setUrl(
              shortUrl
                ? `${shortUrl}&x-oss-process=doc%2Fpreview%2Cprint_1%2Ccopy_1%2Cexport_1`
                : '',
            )
          } else {
            // 其他类型：直接使用后端返回的 URL
            setUrl(originUrl)
          }
          setIsUrlLoading(false)
        })
        .catch(() => {
          setIsUrlLoading(false)
        })
    } else {
      setIsUrlLoading(false)
    }
    // 用 artifact.path 而非整个 artifact 对象，api 不加入依赖（Context 每次渲染都会返回新引用）
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [artifact.path, toolType])

  // Skill Loader：直接将 tool_output 作为 Markdown 内容展示
  if (isSkillLoader) {
    const output = artifact.tool_output ?? artifact.content ?? ''
    const content =
      typeof output === 'string'
        ? output
        : output != null
          ? JSON.stringify(output, null, 2)
          : ''

    return (
      <div className="flex-1 h-full overflow-hidden">
        <div className="h-full overflow-y-auto p-6">
          <MarkdownContent content={content} />
        </div>
      </div>
    )
  }

  // 脚本执行：使用自定义 SHELL_EXECUTE 预览样式组件
  if (toolType === ToolType.SHELL_EXECUTE) {
    const outputText = extractShellOutput(artifact.tool_output || '')
    return <ShellExecutePreview output={outputText} />
  }

  if (toolType === ToolType.SCRIPT_FILE) {
    const code = extractScriptCode(artifact.tool_input)
    const displayTitle = getDisplayTitle(artifact)
    // 这里复用 ShellExecutePreview 的终端风格，而不是普通 ScriptPreview
    return <ShellExecutePreview output={code} toolLabel={displayTitle} />
  }

  // 其他工具调用：使用 ToolCallPreview
  if (isToolCall) {
    return (
      <ToolCallPreview
        toolName={artifact.tool_name}
        eventArguments={artifact.event_arguments}
        toolInput={artifact.tool_input}
        toolOutput={artifact.tool_output}
      />
    )
  }

  // Markdown：用 URL fetch 内容后渲染
  if (isMarkdown && url) {
    return <MarkdownPreview url={url} />
  }

  // PPT：如果是 PPT 文件且有 slideList，使用 PPT 预览
  const isPpt = artifact.file_type?.toLowerCase() === 'ppt' ||
    artifact.file_type?.toLowerCase() === 'pptx' ||
    artifact.file_name?.toLowerCase().endsWith('.ppt') ||
    artifact.file_name?.toLowerCase().endsWith('.pptx')

  if (isPpt && url) {
    return <PptPreview url={url} artifact={artifact} taskId={conversationId || ''} />
  }

  // CSV：fetch 内容后渲染为表格
  const isCsv = artifact.file_type?.toLowerCase() === 'csv' ||
    artifact.file_name?.toLowerCase().endsWith('.csv')

  if (isCsv && url) {
    return <CsvPreview url={url} />
  }

  const isPdf = artifact.file_type?.toLowerCase() === 'pdf' ||
    artifact.file_name?.toLowerCase().endsWith('.pdf')

  if (isPdf && url) {
    return <VirtualPdfPreview url={url} />
  }

  const isScriptFileByExt = isScriptLikeFile(artifact)

  if (isScriptFileByExt && url) {
    return <UrlScriptPreview url={url} title={artifact.file_name} />
  }

  if (url) {
    return (
      <iframe
        src={url}
        className="w-full h-full border-0"
        title={artifact.file_name}
      />
    )
  }

  // URL 解析中：避免先闪出“不支持预览”
  if (isUrlLoading) {
    return (
      <div className="flex-1 flex items-center justify-center p-8 text-muted-foreground h-full">
        <div className="text-sm">加载预览中...</div>
      </div>
    )
  }

  // 不支持预览的文件类型
  return (
    <div className="flex-1 flex flex-col items-center justify-center p-8 text-muted-foreground">
      <div className="text-6xl mb-4">📄</div>
      <div className="text-lg font-medium text-foreground mb-2">{artifact.file_name}</div>
      <div className="text-sm mb-4">
        {artifact.file_type?.toUpperCase() || '未知'} 文件
      </div>
      <p className="text-sm">此文件类型暂不支持预览</p>
    </div>
  )
}

/**
 * 文件预览组件
 */
function InnerArtifactPreview({
  artifact,
  onBack,
  fromFileList,
  onDownload,
  onClose,
  className,
}: ArtifactPreviewProps) {
  const [currentArtifact, setCurrentArtifact] = useState<TaskArtifact | null>(artifact)
  const { conversationId, panelMode } = useNovaKit()
  // 仅当 artifact 的“身份”变化时才同步，避免对象引用变化引起不必要的预览刷新
  React.useEffect(() => {
    const incomingIdentity = artifact
      ? `${artifact.path}|${artifact.file_name}|${artifact.file_type}|${artifact.tool_name}|${artifact.event_type}`
      : ''
    const currentIdentity = currentArtifact
      ? `${currentArtifact.path}|${currentArtifact.file_name}|${currentArtifact.file_type}|${currentArtifact.tool_name}|${currentArtifact.event_type}`
      : ''

    if (incomingIdentity !== currentIdentity) {
      setCurrentArtifact(artifact)
    }
  // currentArtifact 不加入依赖，避免 setCurrentArtifact 触发自身
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [artifact])

  if (!currentArtifact) {
    return (
      <div className={cn('flex items-center justify-center h-full text-muted-foreground', className)}>
        请选择一个文件预览
      </div>
    )
  }

  // 判断是否是图片：检查 path、file_name 和 file_type
  const isImage =
    isImageFile(currentArtifact.path) ||
    isImageFile(currentArtifact.file_name) ||
    ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp'].includes(currentArtifact.file_type?.toLowerCase() || '')

  // html预览
  const isHtml =
  currentArtifact.file_type?.toLowerCase() === 'html' ||
  currentArtifact.file_name?.toLowerCase().endsWith('.html');

  // 只用稳定标识避免同一文件流式更新时重复触发入场动画
  const previewIdentity = currentArtifact.path || currentArtifact.file_name

  return (
    <Card className={cn('flex flex-col h-full border-0 rounded-none relative', className)}>
      {/* 悬浮工具栏 */}
      {(panelMode === 'sidebar' || fromFileList) && <div className="absolute left-4 top-4 z-30 flex items-center gap-1.5 rounded-lg border border-border/50 bg-background/70 p-1 backdrop-blur-xl animate-in fade-in-0 slide-in-from-top-4 duration-300">
        {onBack && (
          <Button
            variant="ghost"
            size="icon"
            onClick={onBack}
            className="h-8 w-8 rounded-md transition-all hover:bg-primary hover:text-white"
          >
            <ChevronLeft className="w-4 h-4 transition-transform hover:-translate-x-0.5" />
          </Button>
        )}

        <span className="text-sm font-medium truncate max-w-[200px] px-2 text-foreground/80 select-none">
          {currentArtifact.file_name}
        </span>

        <div className="flex items-center gap-1 pl-1.5 border-l border-border/50">
          {onDownload && (
            <Button
              variant="ghost"
              size="icon"
              onClick={() => onDownload(currentArtifact)}
              title="下载"
              className="h-8 w-8 rounded-md transition-all hover:bg-primary/20"
            >
              <Download className="w-4 h-4 transition-transform hover:translate-y-0.5" />
            </Button>
          )}
          {onClose && (
            <Button
              variant="ghost"
              size="icon"
              onClick={onClose}
              title="关闭面板"
              className="h-8 w-8 rounded-md transition-all hover:bg-destructive/20 hover:text-destructive text-muted-foreground"
            >
              <X className="w-4 h-4 transition-transform hover:rotate-90" />
            </Button>
          )}
        </div>
      </div>}

      {/* 预览内容 */}
      <div className="flex-1 overflow-hidden">
        {isImage ? (
          panelMode === 'dialog' ? (
            <ImageAttachmentItem
              assetsType={currentArtifact.from!}
              image={
                {
                  url: currentArtifact.url,
                  path: currentArtifact.path,
                  file_name: currentArtifact.file_name,
                  file_url: (currentArtifact as unknown as { file_url?: string }).file_url,
                  file_type: currentArtifact.file_type,
                } as ImageAttachment
              }
            />
          ) : (
            <ImageEditor
              taskId={conversationId || ''}
              currentArtifact={currentArtifact}
              readOnly={false}
              onBack={() => {}}
              onClose={() => {}}
              expand={false}
              onToggleExpand={() => {}}
            />
          )
        ) : isHtml ? (
          <TaskArtifactHtml
            taskId={conversationId || ''}
            taskArtifact={currentArtifact}
            editable={true}
            type="web"
            onStateChange={(state) => {
              console.log(state)
            }}
          />
        ) : (
          <div
            key={previewIdentity}
            className="animate-in fade-in-0 zoom-in-95 duration-300 h-full"
          >
            <FilePreview artifact={currentArtifact} />
          </div>
        )}
      </div>
    </Card>
  )
}

export const ArtifactPreview = React.memo(InnerArtifactPreview)
export default ArtifactPreview
