'use client'

import { useState } from 'react'
import type React from 'react'
import { Check, Copy, FileText } from 'lucide-react'
import type { ContentBlock } from '@/lib/types'
import { H5MarkdownRenderer } from '@/components/h5/h5-markdown-renderer'
import { formatFileSize } from '@/lib/h5/format'
import { copyToClipboard } from '@/lib/h5/clipboard'

/**
 * h5-message-render — user/assistant 消息内容渲染 + 附件卡片 + 复制按钮。
 *
 * 从 h5-client-app.tsx 抽离：renderUserContent / renderAssistantContent /
 * extractAssistantText / H5CopyButton 原为模块级私有函数，现集中于此，
 * 供 client-app 及未来的消息子组件复用。
 *
 * 附件卡片（图片缩略图 / 文件 chip）统一走 <H5AttachmentList>，
 * 消除 renderUser / renderAssistant / 流式气泡三处重复。
 * 样式仍由 h5-client-app 的 :global(.h5-attachment-*) 提供（h5- 前缀命名空间隔离）。
 */

/** 附件卡片数据：ContentBlock 附件块与 StreamingAttachment 共用的结构超集。 */
export interface H5AttachmentItem {
  type: 'image_attachment' | 'file_attachment'
  url: string
  name: string
  size?: number
  mimeType?: string
}

/** 图片缩略图 + 文件 chip 的统一渲染。空数组返回 null。 */
export function H5AttachmentList({ attachments }: { attachments: H5AttachmentItem[] }): React.JSX.Element | null {
  if (attachments.length === 0) return null
  const images = attachments.filter((a) => a.type === 'image_attachment')
  const files = attachments.filter((a) => a.type === 'file_attachment')
  return (
    <>
      {images.length > 0 ? (
        <div className="h5-attachments">
          {images.map((img, i) => (
            <a key={`img-${i}`} href={img.url} target="_blank" rel="noopener noreferrer">
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img src={img.url} alt={img.name} className="h5-attachment-image" loading="lazy" />
            </a>
          ))}
        </div>
      ) : null}
      {files.length > 0 ? (
        <div className="h5-attachments">
          {files.map((f, i) => {
            const sizeStr = formatFileSize(f.size ?? 0)
            return (
              <a
                key={`file-${i}`}
                href={f.url}
                target="_blank"
                rel="noopener noreferrer"
                className="h5-attachment-file"
              >
                <FileText size={16} className="h5-attachment-icon" />
                <span className="h5-attachment-name">{f.name}</span>
                {sizeStr ? <span className="h5-attachment-size">{sizeStr}</span> : null}
              </a>
            )
          })}
        </div>
      ) : null}
    </>
  )
}

/** 从 ContentBlock[] 提取附件块（图片 + 文件），保持原顺序。 */
function extractAttachments(blocks: ContentBlock[]): H5AttachmentItem[] {
  const result: H5AttachmentItem[] = []
  for (const b of blocks) {
    if (b.type === 'image_attachment') {
      result.push({ type: 'image_attachment', url: b.url, name: b.name })
    } else if (b.type === 'file_attachment') {
      result.push({ type: 'file_attachment', url: b.url, name: b.name, size: b.size, mimeType: b.mimeType })
    }
  }
  return result
}

/**
 * 渲染 user 消息内容：
 * - content 是 JSON 化的 ContentBlock[]（含 text + image_attachment + file_attachment）
 * - 解析失败或为纯文本 → 直接显示文本（兼容旧数据）
 * - 图片渲染为缩略图（点击可打开），文件渲染为 chip 卡片
 */
export function renderUserContent(content: string): React.ReactNode {
  let blocks: ContentBlock[] = []
  try {
    const parsed = JSON.parse(content)
    if (Array.isArray(parsed)) blocks = parsed as ContentBlock[]
  } catch {
    // 旧数据：纯文本
    return <span className="h5-md">{content}</span>
  }

  if (blocks.length === 0) return null

  const textBlock = blocks.find((b) => b.type === 'text')
  const text = textBlock?.type === 'text' ? textBlock.text : ''

  return (
    <>
      {text ? <span className="h5-md">{text}</span> : null}
      <H5AttachmentList attachments={extractAttachments(blocks)} />
    </>
  )
}

/**
 * 从 assistant content 提取纯 markdown 文本：解析 ContentBlock[]，
 * 抽取所有 text 块按顺序用空行拼接；非数组 / 解析失败 → 原样返回（兼容纯文本历史数据）。
 * renderAssistantContent 渲染与「复制」按钮共用，保证复制的是完整 markdown 源。
 */
export function extractAssistantText(content: string): string {
  try {
    const parsed = JSON.parse(content)
    if (!Array.isArray(parsed)) return content
    const parts: string[] = []
    for (const b of parsed as ContentBlock[]) {
      if (b.type === 'text' && typeof b.text === 'string' && b.text.length > 0) parts.push(b.text)
    }
    return parts.join('\n\n')
  } catch {
    return content
  }
}

/** assistant 消息左下角的「复制」按钮：复制完整 markdown 源，复制后短暂回显「已复制」。 */
export function H5CopyButton({ text }: { text: string }): React.JSX.Element {
  const [copied, setCopied] = useState(false)
  const onClick = async () => {
    const ok = await copyToClipboard(text)
    if (ok) {
      setCopied(true)
      setTimeout(() => setCopied(false), 2000)
    }
  }
  return (
    <button
      type="button"
      className={`h5-copy-btn${copied ? ' copied' : ''}`}
      onClick={onClick}
      aria-label={copied ? '已复制' : '复制'}
    >
      {copied ? <Check size={14} /> : <Copy size={14} />}
    </button>
  )
}

/**
 * 渲染 assistant 消息内容：
 * - content 是 JSON 化的 ContentBlock[]；抽取所有 text 块拼接为 markdown 文本
 *   交给 H5MarkdownRenderer 渲染（H5 独立样式，不依赖宿主 MarkdownRenderer）。
 * - tool_use / tool_result / thinking / agent_content / tool_progress /
 *   permission_request 一律忽略（H5 端不展示工具与思考过程）。
 * - image_attachment / file_attachment 仍渲染（AI 输出包含文件部分时一并展示）。
 * - 解析失败或为纯文本 → 直接当作 markdown 渲染（兼容历史数据）。
 */
export function renderAssistantContent(content: string): React.ReactNode {
  let blocks: ContentBlock[] = []
  try {
    const parsed = JSON.parse(content)
    if (Array.isArray(parsed)) blocks = parsed as ContentBlock[]
  } catch {
    // 非数组：当作纯 markdown 文本
    return <H5MarkdownRenderer content={content} />
  }

  if (blocks.length === 0) return null

  // 抽取所有 text 块（过滤掉 tool/thinking 等），按顺序用空行拼接
  const textParts: string[] = []
  for (const b of blocks) {
    if (b.type === 'text' && typeof b.text === 'string' && b.text.length > 0) {
      textParts.push(b.text)
    }
  }
  const markdownText = textParts.join('\n\n')

  return (
    <>
      {markdownText ? <H5MarkdownRenderer content={markdownText} /> : null}
      <H5AttachmentList attachments={extractAttachments(blocks)} />
    </>
  )
}
