import React, { useMemo, useState } from 'react'
import { ChevronRight, Folder, FolderOpen, X } from 'lucide-react'
import { cn } from '@/utils/cn'
import type { TaskArtifact } from '../types'
import { getFileIconConfig } from '../utils/fileIcons'
import { Button } from '@/components/ui/button'
import { ScrollArea } from '@/components/ui/scroll-area'

export interface ArtifactListProps {
  artifacts: TaskArtifact[]
  onClick?: (artifact: TaskArtifact) => void
  onClose?: () => void
  selected?: TaskArtifact | null
  className?: string
}

function getFileTypeLabel(artifact: TaskArtifact) {
  const raw =
    artifact.file_type ||
    artifact.file_name.split('.').pop() ||
    artifact.path?.split('.').pop() ||
    ''

  const ext = raw.toLowerCase()

  if (!ext) return '文件'

  switch (ext) {
    case 'py':
      return 'Python 脚本'
    case 'html':
      return 'HTML 文档'
    case 'md':
    case 'markdown':
      return 'Markdown 文件'
    case 'png':
    case 'jpg':
    case 'jpeg':
    case 'gif':
    case 'webp':
      return '图片文件'
    case 'pdf':
      return 'PDF 文件'
    case 'csv':
      return 'CSV 文件'
    case 'ppt':
    case 'pptx':
      return '演示文稿'
    default:
      return `${ext.toUpperCase()} 文件`
  }
}

interface TreeNode {
  name: string
  path: string
  isFolder: boolean
  fileCount: number
  children?: TreeNode[]
  artifact?: TaskArtifact
}

type BuildNode = {
  name: string
  path: string
  isFolder: boolean
  fileCount: number
  children?: Record<string, BuildNode>
  artifact?: TaskArtifact
}

// 只要是 http/https 链接，一律视为「网页」，不在文件列表中展示
function isHttpUrlArtifact(artifact: TaskArtifact): boolean {
  const rawPath = artifact.path || artifact.file_name || ''
  return /^https?:\/\//.test(rawPath)
}

function buildFileTree(artifacts: TaskArtifact[]): TreeNode[] {
  const root: Record<string, BuildNode> = {}

  artifacts.forEach(artifact => {
    const fullPath = artifact.path || artifact.file_name

    // 对于 http/https URL，去掉协议和域名部分，只使用路径来构建「目录」
    let normalizedPath = fullPath
    if (fullPath.startsWith('http://') || fullPath.startsWith('https://')) {
      try {
        const url = new URL(fullPath)
        normalizedPath = url.pathname && url.pathname !== '/' ? url.pathname : url.hostname
      } catch {
        // 如果 URL 解析失败，退回原始 fullPath
        normalizedPath = fullPath
      }
    }

    const parts = normalizedPath.split('/').filter(Boolean)
    let cur = root
    let curPath = ''

    parts.forEach((part, i) => {
      curPath = curPath ? `${curPath}/${part}` : part
      const isLast = i === parts.length - 1

      if (!cur[part]) {
        cur[part] = {
          name: part,
          path: curPath,
          isFolder: !isLast,
          fileCount: 0,
          children: isLast ? undefined : {},
          artifact: isLast ? artifact : undefined,
        }
      } else if (isLast) {
        cur[part].artifact = artifact
      }

      if (!isLast && cur[part].children) {
        cur = cur[part].children!
      }
    })
  })

  const toArr = (obj: Record<string, BuildNode>): TreeNode[] =>
    Object.values(obj)
      .map((n) => {
        const children = n.children ? toArr(n.children) : undefined
        const fileCount = n.isFolder
          ? (children || []).reduce((sum, child) => sum + child.fileCount, 0)
          : 1

        return {
          name: n.name,
          path: n.path,
          isFolder: n.isFolder,
          fileCount,
          artifact: n.artifact,
          children,
        }
      })
      .sort((a, b) => {
        if (a.isFolder !== b.isFolder) return a.isFolder ? -1 : 1
        return a.name.localeCompare(b.name)
      })

  return toArr(root)
}

function isSelectedArtifact(node: TreeNode, selected?: TaskArtifact | null) {
  return !node.isFolder && !!node.artifact && selected?.path === node.artifact.path
}

interface TreeItemProps {
  node: TreeNode
  depth?: number
  collapsedPaths: Set<string>
  selected?: TaskArtifact | null
  onToggle: (path: string) => void
  onSelect?: (artifact: TaskArtifact) => void
}

function TreeItem({
  node,
  depth = 0,
  collapsedPaths,
  selected,
  onToggle,
  onSelect,
}: TreeItemProps) {
  const isFolder = node.isFolder
  const isExpanded = isFolder && !collapsedPaths.has(node.path)
  const selectedState = isSelectedArtifact(node, selected)

  const { icon: FileIcon, color } = isFolder
    ? { icon: isExpanded ? FolderOpen : Folder, color: 'text-primary' }
    : getFileIconConfig(
        node.artifact?.file_type || node.artifact?.file_name.split('.').pop() || '',
      )

  return (
    <div>
      <button
        type="button"
        onClick={() => {
          if (isFolder) {
            onToggle(node.path)
            return
          }

          if (node.artifact) {
            onSelect?.(node.artifact)
          }
        }}
        className={cn(
          'flex w-full cursor-pointer items-center gap-2 rounded-lg px-2 py-4 text-left transition-colors',
          'hover:bg-accent/70',
          selectedState && 'bg-primary/10 text-primary dark:bg-primary/18 dark:text-primary-foreground',
        )}
        style={{ paddingLeft: `${depth * 16 + 8}px` }}
      >
        {isFolder && (<span className="flex h-4 w-4 shrink-0 items-center justify-center">
            <ChevronRight className={cn('h-4 w-4 text-muted-foreground transition-transform', isExpanded && 'rotate-90')} />
          </span>
        )}

        <FileIcon className={cn('h-4 w-4 shrink-0', color)} strokeWidth={1.8} />

        <span className="min-w-0 flex-1 truncate text-sm text-foreground">
          {node.name}
        </span>

        <span className="shrink-0 text-[10px] text-muted-foreground">
          {isFolder
            ? `${node.fileCount} 项`
            : node.artifact
              ? getFileTypeLabel(node.artifact)
              : '文件'}
        </span>
      </button>

      {isFolder && isExpanded && node.children?.length ? (
        <div className="ml-4 border-l border-border pl-2">
          {node.children.map(child => (
            <TreeItem
              key={child.path}
              node={child}
              depth={depth + 1}
              collapsedPaths={collapsedPaths}
              selected={selected}
              onToggle={onToggle}
              onSelect={onSelect}
            />
          ))}
        </div>
      ) : null}
    </div>
  )
}

function InnerArtifactList({ artifacts, onClick, onClose, selected, className }: ArtifactListProps) {
  const files = useMemo(
    () =>
      artifacts.filter(
        (a) =>
          a.event_type !== 'tool_call' &&
          !isHttpUrlArtifact(a),
      ),
    [artifacts],
  )
  const [collapsedPaths, setCollapsedPaths] = useState<Set<string>>(() => new Set())

  const tree = useMemo(
    () => buildFileTree(files),
    [files],
  )

  const fileCount = files.length

  if (fileCount === 0) {
    return (
      <div className={cn('flex items-center justify-center h-full text-sm text-muted-foreground', className)}>
        暂无文件
      </div>
    )
  }

  return (
    <div
      className={cn(
        'flex h-full bg-card overflow-hidden border border-border',
        className,
      )}
    >
      <main className="flex-1 flex min-w-0 flex-col">
        <header className="h-12 md:h-14 border-b border-border flex items-center justify-between px-4 md:px-6 bg-card">
          <div className="flex items-center gap-3">
            <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-accent text-accent-foreground">
              <FolderTreeIcon />
            </div>
            <div className="min-w-0">
              <div className="text-sm font-semibold text-foreground">文件树</div>
              <div className="text-xs text-muted-foreground">按目录结构查看产物</div>
            </div>
          </div>

          <div className="flex items-center gap-2 md:gap-3">
            {onClose && (
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-7 w-7 rounded-lg text-muted-foreground hover:text-primary hover:bg-accent transition-all"
                onClick={onClose}
                title="关闭面板"
              >
                <X className="w-3.5 h-3.5" />
              </Button>
            )}
          </div>
        </header>

        <ScrollArea className="flex-1">
          <div className="px-2 py-4">
            {tree.map(node => (
              <TreeItem
                key={node.path}
                node={node}
                collapsedPaths={collapsedPaths}
                selected={selected}
                onToggle={(path) => {
                  setCollapsedPaths(prev => {
                    const next = new Set(prev)
                    if (next.has(path)) {
                      next.delete(path)
                    } else {
                      next.add(path)
                    }
                    return next
                  })
                }}
                onSelect={onClick}
              />
            ))}
          </div>
        </ScrollArea>

        <footer className="h-9 md:h-10 border-t border-border flex items-center px-4 md:px-6 text-[11px] text-muted-foreground bg-card">
          <span>{fileCount} 个文件</span>
        </footer>
      </main>
    </div>
  )
}

function FolderTreeIcon() {
  return (
    <div className="relative h-4 w-4">
      <div className="absolute left-0 top-0 h-1.5 w-1.5 rounded-sm bg-current opacity-70" />
      <div className="absolute left-0 top-2.5 h-1.5 w-1.5 rounded-sm bg-current opacity-70" />
      <div className="absolute left-2.5 top-1.25 h-1.5 w-1.5 rounded-sm bg-current" />
      <div className="absolute left-[3px] top-[3px] h-px w-[7px] bg-current opacity-50" />
      <div className="absolute left-[3px] top-[11px] h-px w-[7px] bg-current opacity-50" />
      <div className="absolute left-[9px] top-[6px] h-[5px] w-px bg-current opacity-50" />
    </div>
  )
}

export const ArtifactList = React.memo(InnerArtifactList)
export default ArtifactList
