/**
 * FileExplorer Component
 *
 * 文件树组件，支持展开/折叠和文件选择
 */

import { useState, useEffect, useCallback } from 'react';
import { ChevronRight, ChevronDown, File, Folder, FolderOpen, RefreshCw } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { cn } from '../utils/cn.js';
import { getFileTree, type FileTreeNode } from '../api/client.js';

interface FileExplorerProps {
  onFileSelect?: (path: string, name: string) => void;
  className?: string;
  /** 工作目录路径，显示在标题栏 */
  workingDirectory?: string;
}

// 文件图标颜色映射
const fileIconColors: Record<string, string> = {
  ts: 'text-blue-400',
  tsx: 'text-blue-400',
  js: 'text-yellow-300',
  jsx: 'text-yellow-300',
  json: 'text-yellow-500',
  md: 'text-fg-muted',
  css: 'text-pink-400',
  scss: 'text-pink-400',
  html: 'text-orange-400',
  py: 'text-green-400',
  go: 'text-cyan-400',
  rs: 'text-orange-500',
  java: 'text-red-400',
  c: 'text-blue-500',
  cpp: 'text-blue-500',
  h: 'text-purple-400',
};

function getFileIconColor(name: string): string {
  const ext = name.split('.').pop()?.toLowerCase() || '';
  return fileIconColors[ext] || 'text-fg-muted';
}

interface TreeNodeProps {
  node: FileTreeNode;
  depth: number;
  onFileSelect?: (path: string, name: string) => void;
  expandedPaths: Set<string>;
  onToggleExpand: (path: string) => void;
}

function TreeNode({ node, depth, onFileSelect, expandedPaths, onToggleExpand }: TreeNodeProps) {
  const isExpanded = expandedPaths.has(node.path);
  const isDirectory = node.type === 'directory';
  const hasChildren = isDirectory && node.children && node.children.length > 0;

  const handleClick = () => {
    if (isDirectory) {
      onToggleExpand(node.path);
    } else {
      onFileSelect?.(node.path, node.name);
    }
  };

  return (
    <div>
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        className={cn(
          'flex items-center gap-1 py-1 px-2 cursor-pointer rounded',
          'hover:bg-surface-muted transition-colors',
          'text-sm'
        )}
        style={{ paddingLeft: `${depth * 16 + 8}px` }}
        onClick={handleClick}
      >
        {/* 展开/折叠图标 */}
        {isDirectory ? (
          <span className="w-4 h-4 flex items-center justify-center text-fg-muted">
            {hasChildren ? (
              isExpanded ? (
                <ChevronDown size={14} />
              ) : (
                <ChevronRight size={14} />
              )
            ) : null}
          </span>
        ) : (
          <span className="w-4" />
        )}

        {/* 文件/文件夹图标 */}
        {isDirectory ? (
          isExpanded ? (
            <FolderOpen size={16} className="text-yellow-400 flex-shrink-0" />
          ) : (
            <Folder size={16} className="text-yellow-400 flex-shrink-0" />
          )
        ) : (
          <File size={16} className={cn('flex-shrink-0', getFileIconColor(node.name))} />
        )}

        {/* 文件名 */}
        <span className="truncate text-fg">{node.name}</span>
      </motion.div>

      {/* 子节点 */}
      <AnimatePresence>
        {isDirectory && isExpanded && node.children && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: 'auto', opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            transition={{ duration: 0.15 }}
          >
            {node.children.map((child) => (
              <TreeNode
                key={child.path}
                node={child}
                depth={depth + 1}
                onFileSelect={onFileSelect}
                expandedPaths={expandedPaths}
                onToggleExpand={onToggleExpand}
              />
            ))}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

const STORAGE_KEY_EXPANDED = 'ai-assistant-file-explorer-expanded';

export function FileExplorer({ onFileSelect, className, workingDirectory }: FileExplorerProps) {
  const [tree, setTree] = useState<FileTreeNode[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  // 从 localStorage 恢复展开状态
  const [expandedPaths, setExpandedPaths] = useState<Set<string>>(() => {
    try {
      const saved = localStorage.getItem(STORAGE_KEY_EXPANDED);
      return saved ? new Set(JSON.parse(saved)) : new Set();
    } catch {
      return new Set();
    }
  });

  // 加载文件树
  const loadTree = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await getFileTree('.', 4);
      if (result.success) {
        setTree(result.data.tree);
        // 保持已保存的展开状态（不重置）
      } else {
        setError('Failed to load file tree');
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load file tree');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    loadTree();
  }, [loadTree]);

  const handleToggleExpand = useCallback((path: string) => {
    setExpandedPaths((prev) => {
      const next = new Set(prev);
      if (next.has(path)) {
        next.delete(path);
      } else {
        next.add(path);
      }
      // 保存到 localStorage
      localStorage.setItem(STORAGE_KEY_EXPANDED, JSON.stringify([...next]));
      return next;
    });
  }, []);

  if (loading) {
    return (
      <div className={cn('flex items-center justify-center h-full', className)}>
        <div className="w-6 h-6 border-2 border-primary-500 border-t-transparent rounded-full animate-spin" />
      </div>
    );
  }

  if (error) {
    return (
      <div className={cn('flex flex-col items-center justify-center h-full gap-3 p-4', className)}>
        <p className="text-red-400 text-sm">{error}</p>
        <button
          onClick={loadTree}
          className="flex items-center gap-2 px-3 py-1.5 bg-surface-muted hover:bg-surface-emphasis rounded text-sm text-fg-secondary transition-colors"
        >
          <RefreshCw size={14} />
          Retry
        </button>
      </div>
    );
  }

  return (
    <div className={cn('flex flex-col h-full bg-surface-subtle', className)}>
      {/* Header */}
      <div className="flex items-center justify-between px-3 py-2 border-b border-line gap-2">
        <div className="flex items-center gap-1.5 min-w-0 flex-1 group relative">
          <Folder size={14} className="flex-shrink-0 text-fg-muted" />
          <span className="text-sm font-mono text-fg-muted truncate">
            {workingDirectory || 'Files'}
          </span>
          {/* Tooltip - 悬浮时显示完整路径 */}
          {workingDirectory && (
            <div className="absolute left-0 top-full mt-1 z-50 hidden group-hover:block">
              <div className="bg-surface-emphasis border border-line rounded-md shadow-lg px-3 py-2 max-w-[400px]">
                <p className="text-xs font-mono text-fg break-all whitespace-pre-wrap">
                  {workingDirectory}
                </p>
              </div>
            </div>
          )}
        </div>
        <button
          onClick={loadTree}
          className="p-1 hover:bg-surface-muted rounded transition-colors flex-shrink-0"
          title="Refresh"
        >
          <RefreshCw size={14} className="text-fg-muted" />
        </button>
      </div>

      {/* Tree */}
      <div className="flex-1 overflow-auto py-2">
        {tree.length === 0 ? (
          <p className="text-fg-muted text-sm text-center py-4">No files found</p>
        ) : (
          tree.map((node) => (
            <TreeNode
              key={node.path}
              node={node}
              depth={0}
              onFileSelect={onFileSelect}
              expandedPaths={expandedPaths}
              onToggleExpand={handleToggleExpand}
            />
          ))
        )}
      </div>
    </div>
  );
}
