import React from 'react'
import { ScrollArea } from '@/components/ui/scroll-area'
import { cn } from '@/utils/cn'
import type { TaskArtifact } from '../../types'
import { UrlScriptPreview } from './UrlScriptPreview'
import { ShellExecutePreview } from './ShellExecutePreview'
import { WebSearchPreview } from './WebSearchPreview'
import { extractToolOutputArtifact, normalizeArtifactFileType } from './previewUtils'
import { ToolOutputArtifactPreview } from './ToolOutputArtifactPreview'

export interface ToolCallPreviewProps {
  /** 工具名称 */
  toolName?: string
  /** 原始事件参数（event.content.arguments） */
  eventArguments?: unknown
  /** 工具输入参数 */
  toolInput?: unknown
  /** 工具输出结果 */
  toolOutput?: unknown
  /** 自定义类名 */
  className?: string
  /** 主题 */
  theme?: string
}

function getBaseName(path?: string): string {
  if (!path) return ''
  const cleanPath = path.split(/[?#]/)[0]
  const segments = cleanPath.split('/').filter(Boolean)
  return segments[segments.length - 1] || ''
}

function extractArrayToolOutputArtifact(
  toolOutput: unknown,
  toolName?: string,
): TaskArtifact | null {
  if (!Array.isArray(toolOutput) || toolOutput.length === 0) {
    return null
  }

  const firstObject = toolOutput.find(
    item => item && typeof item === 'object' && !Array.isArray(item),
  ) as Record<string, unknown> | undefined

  if (!firstObject) {
    return null
  }

  const outputPathFields = ['image_path', 'path', 'file_path', 'file_url', 'url', 'download_url']
  const outputNameFields = ['file_name', 'name', 'title']
  const outputTypeFields = ['file_type', 'type', 'mime_type']

  const outputPath = outputPathFields.find(
    field => typeof firstObject[field] === 'string' && firstObject[field],
  )
  const pathValue = outputPath ? String(firstObject[outputPath]) : ''

  if (!pathValue) {
    return null
  }

  const outputName = outputNameFields.find(
    field => typeof firstObject[field] === 'string' && firstObject[field],
  )
  const fileName = outputName
    ? String(firstObject[outputName])
    : getBaseName(pathValue) || `${toolName || 'tool_output'}`

  const outputType = outputTypeFields.find(
    field => typeof firstObject[field] === 'string' && firstObject[field],
  )
  const fileType = normalizeArtifactFileType(
    outputType ? String(firstObject[outputType]) : '',
    fileName,
    pathValue,
  )

  return {
    path: pathValue,
    file_name: fileName,
    file_type: fileType,
    url: /^https?:\/\//.test(pathValue) ? pathValue : undefined,
  }
}

/**
 * 从工具输入/输出中提取代码内容
 */
function extractCodeFromData(data: unknown): string | null {
  if (!data || typeof data !== 'object') {
    return null
  }
  
  const obj = data as Record<string, unknown>
  
  // 常见的代码字段
  const codeFields = [
    'code',
    'script',
    'command',
    'cmd',
    'content',
    'source',
    'text',
    'body',
  ]
  
  for (const field of codeFields) {
    if (typeof obj[field] === 'string' && obj[field]) {
      return obj[field] as string
    }
  }
  
  return null
}

/**
 * 从工具输出中智能提取脚本 URL
 * 优先支持几种常见字段：url / script_url / file_url / download_url
 */
function extractScriptUrl(data: unknown): string | null {
  if (!data) return null

  // 纯字符串且是 URL
  if (typeof data === 'string') {
    return /^https?:\/\//.test(data) ? data : null
  }

  if (typeof data !== 'object' || data === null) return null

  const obj = data as Record<string, unknown>
  const urlLikeFields = ['script_url', 'url', 'file_url', 'download_url']

  for (const field of urlLikeFields) {
    const val = obj[field]
    if (typeof val === 'string' && /^https?:\/\//.test(val)) {
      return val
    }
  }

  return null
}

/**
 * 提取 event.content.arguments[0] 作为搜索词
 */
function extractFirstArgument(args: unknown): string | null {
  if (!args) return null

  let normalized: unknown[] = []

  if (Array.isArray(args)) {
    normalized = args
  } else if (typeof args === 'string') {
    try {
      const parsed = JSON.parse(args)
      if (Array.isArray(parsed)) {
        normalized = parsed
      } else {
        normalized = [args]
      }
    } catch {
      normalized = [args]
    }
  } else {
    return null
  }

  if (!normalized.length) return null

  const first = normalized[0]
  if (typeof first === 'string') return first
  if (typeof first === 'number' || typeof first === 'boolean') return String(first)
  return null
}

/**
 * 格式化数据为字符串，尝试保持原始格式
 */
function formatData(data: unknown, toolName?: string): string {
  // 如果是字符串，直接返回
  if (typeof data === 'string') {
    return data
  }
  
  // 如果是脚本执行类工具，尝试提取代码
  const isCodeExecutionTool = toolName && (
    toolName.includes('execute') ||
    toolName.includes('shell') ||
    toolName.includes('code') ||
    toolName.includes('script') ||
    toolName.includes('python') ||
    toolName.includes('javascript') ||
    toolName.includes('node') ||
    toolName.includes('bash')
  )
  
  if (isCodeExecutionTool) {
    const code = extractCodeFromData(data)
    if (code) {
      return code
    }
  }
  
  // 默认格式化为 JSON
  return JSON.stringify(data, null, 2)
}


/**
 * 将任意值拍平为 [key, displayValue][] 用于 table 渲染
 * - 对象：每个 key-value 一行
 * - 其他：单行 value
 */
function flattenToRows(data: unknown): Array<[string, string]> {
  if (!data) return []

  // 特殊处理：当只有 value 且它是 JSON 字符串时，优先解析并展开内部字段
  if (
    typeof data === 'object' &&
    data !== null &&
    !Array.isArray(data) &&
    'value' in (data as Record<string, unknown>)
  ) {
    const rawValue = (data as Record<string, unknown>).value
    if (typeof rawValue === 'string') {
      try {
        const parsed = JSON.parse(rawValue)
        // 解析成功且是对象/数组时，递归拍平内部结构
        if (parsed && typeof parsed === 'object') {
          return flattenToRows(parsed)
        }
      } catch {
        // 解析失败则继续按下面的逻辑处理
      }
    }
  }

  // 普通对象：按 key → value 展开
  if (typeof data === 'object' && data !== null && !Array.isArray(data)) {
    return Object.entries(data as Record<string, unknown>).map(([k, v]) => [
      k,
      typeof v === 'string' ? v : JSON.stringify(v, null, 2),
    ])
  }

  // 根就是 JSON 字符串：尝试解析并展开
  if (typeof data === 'string') {
    try {
      const parsed = JSON.parse(data)
      if (parsed && typeof parsed === 'object') {
        return flattenToRows(parsed)
      }
    } catch {
      // 不是合法 JSON，则按原始字符串展示
    }
  }

  const str = typeof data === 'string' ? data : JSON.stringify(data, null, 2)
  return [['value', str]]
}

function ToolLabel({ label, desc }: { label: string, desc: string }) {
  return <div className="flex items-baseline justify-between mb-4">
    <h2 className="text-[14px] font-bold text-muted-foreground uppercase tracking-[0.2em]">
      {label}
    </h2>
    <div className="mx-4 h-px flex-1 bg-border/80" />
    <span className="text-[11px] font-mono text-muted-foreground">
      {desc}
    </span>
  </div>
}

/**
 * 输入参数详情面板（参考设计稿样式）
 */
function InputPanel({ data }: { data: unknown }) {
  const rows = flattenToRows(data)
  if (!rows.length) return null

  const [first, ...rest] = rows
  const pairs: Array<Array<[string, string]>> = []

  for (let i = 0; i < rest.length; i += 2) {
    pairs.push(rest.slice(i, i + 2))
  }

  return (
    <div className="space-y-6">
      {/* 顶部标题行 */}
     <ToolLabel label="输入参数" desc={`${rows.length} keys`} />

      <div className="grid grid-cols-1 gap-y-6">
        {/* 首行：做成醒目的大块 */}
        {first && (
          <div className="group">
            <label className="mb-1.5 block text-[10px] font-bold uppercase tracking-wider text-muted-foreground transition-colors group-hover:text-primary">
              {first[0]}
            </label>
            <div className="rounded-lg border border-border bg-card/84 px-3 py-2.5 font-mono text-sm text-foreground transition-all group-hover:border-primary/40">
              {first[1]}
            </div>
          </div>
        )}

        {/* 后续参数，两列栅格，自动铺排 */}
        {pairs.map((rowGroup, idx) => (
          <div className="grid grid-cols-1 md:grid-cols-2 gap-6 md:gap-8" key={idx}>
            {rowGroup.map(([key, val]) => (
              <div className="group" key={key}>
                <label className="mb-1.5 block text-[10px] font-bold uppercase tracking-wider text-muted-foreground transition-colors group-hover:text-primary">
                  {key}
                </label>
                <div className="break-all font-mono text-sm text-foreground">
                  {val}
                </div>
              </div>
            ))}
          </div>
        ))}
      </div>
    </div>
  )
}

/**
 * 工具调用预览组件
 * - 输入参数：table 展示
 * - 输出结果：浅色主题代码块
 */
export function ToolCallPreview({
  toolName,
  eventArguments,
  toolInput,
  toolOutput,
  className,
}: ToolCallPreviewProps) {
  // info_search_web：复刻 Remix 的 WebSearch 展示逻辑（列表 + 可点击链接）
  if (toolName === 'info_search_web') {
    const searchQuery = extractFirstArgument(eventArguments)
    return (
      <WebSearchPreview
        results={toolOutput}
        searchQuery={searchQuery}
        className={className}
      />
    )
  }

  const outputCode = formatData(toolOutput, toolName)
  const outputArtifact = extractToolOutputArtifact({
    path: '',
    file_name: toolName || 'tool_output',
    file_type: 'tool_call',
    event_type: 'tool_call',
    tool_name: toolName,
    event_arguments: eventArguments,
    tool_input: toolInput,
    tool_output: toolOutput,
  }) ?? extractArrayToolOutputArtifact(toolOutput, toolName)

  if (outputArtifact) {
    return (
      <div className={cn('h-full overflow-hidden', className)}>
        <ToolOutputArtifactPreview artifact={outputArtifact} />
      </div>
    )
  }

  // 对脚本类工具，优先尝试用 UrlScriptPreview（复用 ShellExecutePreview 风格）
  const isScriptTool = !!toolName && toolName.toLowerCase().includes('script')
  const scriptUrl = isScriptTool ? extractScriptUrl(toolOutput) : null

  return (
    <div className={cn('flex flex-col h-full', className)}>
      <ScrollArea className="flex-1">
        <div className="p-6 space-y-8 mt-[50px]">
          {/* 工具名称 */}
          {toolName && (
            <div className="mb-6">
              <ToolLabel label="工具调用" desc={toolName} />
              <div className="inline-flex items-center rounded-md bg-primary/10 px-3 py-1.5 font-mono text-sm text-primary">
                {toolName}
              </div>
            </div>
          )}

          {/* 输入参数 - Table */}
          {toolInput != null && (
            <div>
              <InputPanel data={toolInput} />
            </div>
          )}

          {/* 输出结果 */}
          {toolOutput != null && (
            <div>
              <ToolLabel label="输出结果" desc="200 ok" />

              {/* 脚本工具 + 有 URL：用 UrlScriptPreview（内部再用 ShellExecutePreview） */}
              {!outputArtifact && scriptUrl && (
                <div className="rounded-lg border border-border overflow-hidden">
                  <UrlScriptPreview url={scriptUrl} title={toolName} />
                </div>
              )}

              {/* 其他情况：走原来的浅色代码高亮 */}
              {!scriptUrl && (
                <ShellExecutePreview output={outputCode} />
              )}
            </div>
          )}
        </div>
      </ScrollArea>
    </div>
  )
}

export default ToolCallPreview
