/**
 * FileBrowser Component
 *
 * 文件浏览器组件
 */

import { useState, useEffect, useCallback } from 'react';
import { listFiles, readFile, type FileInfo } from '../api/client.js';

interface FileBrowserProps {
  onFileSelect?: (path: string, content: string) => void;
  className?: string;
}

// 文件图标
const FileIcon = ({ type, extension }: { type: 'file' | 'directory'; extension?: string }) => {
  if (type === 'directory') {
    return (
      <svg className="w-4 h-4 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
        <path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" />
      </svg>
    );
  }

  // 根据扩展名显示不同颜色
  const colors: 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',
    html: 'text-orange-400',
    py: 'text-green-400',
    go: 'text-cyan-400',
    rs: 'text-orange-500',
  };

  const color = colors[extension || ''] || 'text-fg-muted';

  return (
    <svg className={`w-4 h-4 ${color}`} fill="currentColor" viewBox="0 0 20 20">
      <path
        fillRule="evenodd"
        d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4z"
        clipRule="evenodd"
      />
    </svg>
  );
};

// 格式化文件大小
const formatSize = (bytes: number): string => {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
};

export function FileBrowser({ onFileSelect, className = '' }: FileBrowserProps) {
  const [currentPath, setCurrentPath] = useState('.');
  const [files, setFiles] = useState<FileInfo[]>([]);
  const [parentPath, setParentPath] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [selectedFile, setSelectedFile] = useState<string | null>(null);
  const [fileContent, setFileContent] = useState<string | null>(null);
  const [showHidden, setShowHidden] = useState(false);

  // 加载目录内容
  const loadDirectory = useCallback(async (path: string) => {
    setLoading(true);
    setError(null);
    setSelectedFile(null);
    setFileContent(null);

    try {
      const response = await listFiles(path, showHidden);
      setFiles(response.data.files);
      setCurrentPath(response.data.path);
      setParentPath(response.data.parent);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load directory');
    } finally {
      setLoading(false);
    }
  }, [showHidden]);

  // 初始加载
  useEffect(() => {
    loadDirectory('.');
  }, [loadDirectory]);

  // 处理文件/目录点击
  const handleItemClick = async (item: FileInfo) => {
    if (item.type === 'directory') {
      loadDirectory(item.path);
    } else {
      setSelectedFile(item.path);
      try {
        const response = await readFile(item.path);
        if (response.data.encoding === 'utf-8') {
          setFileContent(response.data.content);
          onFileSelect?.(item.path, response.data.content);
        } else {
          setFileContent('[Binary file]');
        }
      } catch (err) {
        setFileContent(`Error: ${err instanceof Error ? err.message : 'Failed to read file'}`);
      }
    }
  };

  // 返回上级目录
  const handleGoUp = () => {
    if (parentPath !== null) {
      loadDirectory(parentPath);
    }
  };

  // 刷新
  const handleRefresh = () => {
    loadDirectory(currentPath);
  };

  return (
    <div className={`flex flex-col h-full bg-surface-base ${className}`}>
      {/* 工具栏 */}
      <div className="flex items-center gap-2 p-2 border-b border-line bg-surface-subtle">
        <button
          onClick={handleGoUp}
          disabled={parentPath === null}
          className="p-1.5 rounded hover:bg-surface-muted disabled:opacity-50 disabled:cursor-not-allowed"
          title="Go up"
        >
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 15l7-7 7 7" />
          </svg>
        </button>

        <button
          onClick={handleRefresh}
          className="p-1.5 rounded hover:bg-surface-muted"
          title="Refresh"
        >
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
            />
          </svg>
        </button>

        <div className="flex-1 px-2 py-1 text-sm text-fg-muted bg-surface-base rounded truncate">
          {currentPath}
        </div>

        <label className="flex items-center gap-1 text-xs text-fg-muted cursor-pointer">
          <input
            type="checkbox"
            checked={showHidden}
            onChange={(e) => {
              setShowHidden(e.target.checked);
              loadDirectory(currentPath);
            }}
            className="w-3 h-3"
          />
          Hidden
        </label>
      </div>

      {/* 文件列表 */}
      <div className="flex-1 overflow-auto">
        {loading ? (
          <div className="flex items-center justify-center h-32 text-fg-muted">
            Loading...
          </div>
        ) : error ? (
          <div className="flex items-center justify-center h-32 text-red-400">
            {error}
          </div>
        ) : files.length === 0 ? (
          <div className="flex items-center justify-center h-32 text-fg-subtle">
            Empty directory
          </div>
        ) : (
          <div className="divide-y divide-surface-subtle">
            {files.map((file) => (
              <div
                key={file.path}
                onClick={() => handleItemClick(file)}
                className={`flex items-center gap-2 px-3 py-2 cursor-pointer hover:bg-surface-subtle ${
                  selectedFile === file.path ? 'bg-surface-subtle border-l-2 border-blue-500' : ''
                }`}
              >
                <FileIcon type={file.type} extension={file.extension} />
                <span className="flex-1 truncate text-sm">{file.name}</span>
                {file.type === 'file' && (
                  <span className="text-xs text-fg-subtle">{formatSize(file.size)}</span>
                )}
              </div>
            ))}
          </div>
        )}
      </div>

      {/* 文件预览 */}
      {selectedFile && fileContent && (
        <div className="border-t border-line max-h-48 overflow-auto">
          <div className="sticky top-0 flex items-center justify-between px-3 py-1 bg-surface-subtle border-b border-line">
            <span className="text-xs text-fg-muted truncate">{selectedFile}</span>
            <button
              onClick={() => {
                setSelectedFile(null);
                setFileContent(null);
              }}
              className="p-1 hover:bg-surface-muted rounded"
            >
              <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          </div>
          <pre className="p-3 text-xs text-fg-secondary whitespace-pre-wrap font-mono">
            {fileContent.slice(0, 5000)}
            {fileContent.length > 5000 && '\n... (truncated)'}
          </pre>
        </div>
      )}
    </div>
  );
}
