import React from 'react'
import { cn } from '@/utils/cn'
import type { ImageAttachment, TaskArtifact } from '../../types'
import { useNovaKit } from '../../context/useNovaKit'
import { isImageFile } from '../utils'
import { TaskArtifactHtml } from '@/components/html-editor'
import { Html } from '@/components/html-editor/components/html-render/task-html'
import PptPreview from '@/components/ppt-editor'
import { ImageAttachmentItem } from '../../message-list/message-item/ImageAttachmentItem'
import { UrlScriptPreview } from './UrlScriptPreview'
import { ShellExecutePreview } from './ShellExecutePreview'
import { MarkdownContent, MarkdownPreview } from './MarkdownPreview'
import { CsvPreview } from './CsvPreview'
import { VirtualPdfPreview } from './VirtualPdfPreview'
import { isScriptLikeFile, normalizeArtifactFileType } from './previewUtils'

export interface ToolOutputArtifactPreviewProps {
  artifact: TaskArtifact
  className?: string
}

const PREVIEW_FILE_TYPES = ['xlsx', 'xls', 'doc', 'docx']
const TEXT_LIKE_FILE_TYPES = ['txt', 'text', 'json', 'log', 'xml', 'yaml', 'yml']

export function ToolOutputArtifactPreview({
  artifact,
  className,
}: ToolOutputArtifactPreviewProps) {
  const { api, conversationId, mode } = useNovaKit()
  const [url, setUrl] = React.useState('')
  const [isUrlLoading, setIsUrlLoading] = React.useState(false)
  const editable = mode === 'chat'

  const normalizedFileType = normalizeArtifactFileType(
    artifact.file_type,
    artifact.file_name,
    artifact.path,
  )

  React.useEffect(() => {
    const directUrl = artifact.url || (/^https?:\/\//.test(artifact.path) ? artifact.path : '')

    if (directUrl) {
      setUrl(directUrl)
      setIsUrlLoading(false)
      return
    }

    if (artifact.path) {
      setIsUrlLoading(true)
      setUrl('')
      api
        .getArtifactUrl?.(
          artifact,
          PREVIEW_FILE_TYPES.includes(normalizedFileType)
            ? {
                'x-oss-process': 'doc/preview,print_1,copy_1,export_1',
              }
            : undefined,
        )
        .then(res => {
          const originUrl = typeof res?.data === 'string' ? res.data : ''

          if (PREVIEW_FILE_TYPES.includes(normalizedFileType)) {
            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 {
            setUrl(originUrl)
          }
          setIsUrlLoading(false)
        })
        .catch(() => {
          setIsUrlLoading(false)
        })
      return
    }

    setIsUrlLoading(false)
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [artifact.path, artifact.url, normalizedFileType])

  const isImage =
    isImageFile(artifact.path) ||
    isImageFile(artifact.file_name) ||
    ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp'].includes(normalizedFileType)

  if (isImage) {
    const imageAttachment: ImageAttachment = {
      url: artifact.url || '',
      path: artifact.path,
      file_name: artifact.file_name,
      file_url: artifact.url,
    }

    return (
      <div className={cn('flex h-full items-center justify-center p-6 bg-muted/10', className)}>
        <ImageAttachmentItem image={imageAttachment} />
      </div>
    )
  }

  const isHtml =
    normalizedFileType === 'html' ||
    artifact.file_name?.toLowerCase().endsWith('.html')

  if (isHtml && artifact.content && !artifact.path) {
    return <Html className={cn('h-full', className)} content={artifact.content} />
  }

  if (isHtml) {
    return (
      <div className={cn('h-full', className)}>
        <TaskArtifactHtml
          taskId={conversationId || ''}
          taskArtifact={artifact}
          editable={editable}
          type="web"
        />
      </div>
    )
  }

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

  if (isMarkdown && url) {
    return <div className={cn('h-full', className)}><MarkdownPreview url={url} /></div>
  }

  if (isMarkdown && artifact.content) {
    return (
      <div className={cn('h-full overflow-y-auto p-6', className)}>
        <MarkdownContent content={artifact.content} />
      </div>
    )
  }

  const isPpt =
    normalizedFileType === 'ppt' ||
    normalizedFileType === 'pptx' ||
    artifact.file_name?.toLowerCase().endsWith('.ppt') ||
    artifact.file_name?.toLowerCase().endsWith('.pptx')

  if (isPpt && url) {
    return (
      <div className={cn('h-full', className)}>
        <PptPreview
          url={url}
          artifact={artifact}
          taskId={conversationId || ''}
          editable={editable}
        />
      </div>
    )
  }

  const isCsv =
    normalizedFileType === 'csv' ||
    artifact.file_name?.toLowerCase().endsWith('.csv')

  if (isCsv && artifact.content) {
    return <div className={cn('h-full', className)}><CsvPreview content={artifact.content} /></div>
  }

  if (isCsv && url) {
    return <div className={cn('h-full', className)}><CsvPreview url={url} /></div>
  }

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

  if (isPdf && url) {
    return <div className={cn('h-full', className)}><VirtualPdfPreview url={url} /></div>
  }

  const isScript = isScriptLikeFile(artifact)
  if (isScript && artifact.content) {
    return (
      <div className={cn('h-full', className)}>
        <ShellExecutePreview output={artifact.content} toolLabel={artifact.file_name} />
      </div>
    )
  }

  const isTextLike = TEXT_LIKE_FILE_TYPES.includes(normalizedFileType)
  if (isTextLike && artifact.content) {
    return (
      <div className={cn('h-full', className)}>
        <ShellExecutePreview output={artifact.content} toolLabel={artifact.file_name} />
      </div>
    )
  }

  if ((isScript || isTextLike) && url) {
    return <div className={cn('h-full', className)}><UrlScriptPreview url={url} title={artifact.file_name} /></div>
  }

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

  if (isUrlLoading) {
    return (
      <div className={cn('flex h-full items-center justify-center p-8 text-muted-foreground', className)}>
        <div className="text-sm">加载预览中...</div>
      </div>
    )
  }

  return (
    <div className={cn('flex h-full items-center justify-center p-8 text-muted-foreground', className)}>
      <div className="text-sm">此文件类型暂不支持预览</div>
    </div>
  )
}

export default ToolOutputArtifactPreview
