import React, { useEffect, useMemo, useState, useRef } from 'react';
import { useApp } from '../context/AppContext';
import { NODE_TYPES } from '../utils/fileUtils';
import './Sidebar.css';

function TreeNode({ node, level = 0 }) {
  const { selectFile, toggleNodeExpansion, currentFile } = useApp();

  // 计算当前目录下的直接文章数量
  const articleCount = useMemo(() => {
    if (node.type !== NODE_TYPES.FOLDER || !node.children) {
      return 0;
    }
    return node.children.filter(child => 
      child.type === NODE_TYPES.FILE && child.name.endsWith('.md')
    ).length;
  }, [node]);

  const handleClick = () => {
    if (node.type === NODE_TYPES.FOLDER) {
      toggleNodeExpansion(node.path);
    } else {
      selectFile(node.path);
    }
  };

  const isSelected = currentFile === node.path;
  const hasChildren = node.children && node.children.length > 0;
  const paddingLeft = `${level * 18 + 14}px`;
  const contentClass = isSelected ? 'tree-node-content selected' : 'tree-node-content';
  const folderIconClass = `tree-node-icon${node.isExpanded ? ' expanded' : ''}`;

  return (
    <div className="tree-node">
      <div
        className={contentClass}
        style={{ paddingLeft }}
        onClick={handleClick}
        role="button"
        tabIndex={0}
        onKeyDown={(event) => {
          if (event.key === 'Enter' || event.key === ' ') {
            event.preventDefault();
            handleClick();
          }
        }}
      >
        {node.type === NODE_TYPES.FOLDER && (
          <span className={folderIconClass} aria-hidden>
            {hasChildren ? (node.isExpanded ? '📂' : '📁') : '📁'}
          </span>
        )}
        {node.type === NODE_TYPES.FILE && (
          <span className="tree-node-icon" aria-hidden>📄</span>
        )}
        <span className="tree-node-name">
          {node.type === NODE_TYPES.FILE && node.name.endsWith('.md') 
            ? node.name.slice(0, -3) 
            : node.name}
        </span>
        {node.type === NODE_TYPES.FOLDER && articleCount > 0 && (
          <span className="article-count-badge">{articleCount}</span>
        )}
      </div>

      {node.type === NODE_TYPES.FOLDER && node.isExpanded && hasChildren && (
        <div className="tree-node-children">
          {node.children.map((child) => (
            <TreeNode key={child.path} node={child} level={level + 1} />
          ))}
        </div>
      )}
    </div>
  );
}

export default function Sidebar() {
  const { directoryTree, isLoading, error, sidebarOpen, toggleSidebar } = useApp();
  
  // 拖动相关状态
  const [isDragging, setIsDragging] = useState(false);
  const [dragPosition, setDragPosition] = useState(() => {
    // 从localStorage读取保存的位置，默认右上角
    const saved = localStorage.getItem('sidebar-toggle-position');
    return saved ? JSON.parse(saved) : { x: window.innerWidth - 60, y: 20 };
  });
  const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
  const [touchStartPos, setTouchStartPos] = useState({ x: 0, y: 0 });
  const [hasMoved, setHasMoved] = useState(false);
  const buttonRef = useRef(null);

  // 拖动事件处理函数
  const handleTouchStart = (e) => {
    if (window.innerWidth > 768) return; // 只在移动端启用拖动
    
    const touch = e.touches[0];
    const rect = buttonRef.current.getBoundingClientRect();
    
    setTouchStartPos({ x: touch.clientX, y: touch.clientY });
    setDragOffset({
      x: touch.clientX - rect.left,
      y: touch.clientY - rect.top
    });
    setHasMoved(false);
    // 不要在这里preventDefault，让点击事件能正常触发
  };

  const handleTouchMove = (e) => {
    if (window.innerWidth > 768) return;
    
    const touch = e.touches[0];
    const deltaX = Math.abs(touch.clientX - touchStartPos.x);
    const deltaY = Math.abs(touch.clientY - touchStartPos.y);
    
    // 如果移动距离超过5px，认为是拖动
    if (deltaX > 5 || deltaY > 5) {
      if (!hasMoved) {
        setHasMoved(true);
        setIsDragging(true);
      }
      
      const newX = touch.clientX - dragOffset.x;
      const newY = touch.clientY - dragOffset.y;
      
      // 限制在屏幕范围内
      const maxX = window.innerWidth - 44;
      const maxY = window.innerHeight - 44;
      
      setDragPosition({
        x: Math.max(0, Math.min(newX, maxX)),
        y: Math.max(0, Math.min(newY, maxY))
      });
      
      e.preventDefault(); // 只在确认拖动时阻止默认行为
    }
  };

  const handleTouchEnd = (e) => {
    if (hasMoved && isDragging) {
      // 保存位置到localStorage
      localStorage.setItem('sidebar-toggle-position', JSON.stringify(dragPosition));
      e.preventDefault(); // 阻止点击事件
    }
    
    setIsDragging(false);
    setHasMoved(false);
  };

  // 处理点击事件
  const handleButtonClick = (e) => {
    // 如果刚刚完成拖动，不触发点击
    if (hasMoved) {
      return;
    }
    toggleSidebar();
  };

  // 处理窗口大小变化
  useEffect(() => {
    const handleResize = () => {
      if (window.innerWidth > 768) {
        // 桌面端重置位置
        return;
      }
      
      // 移动端调整位置确保按钮在屏幕范围内
      const maxX = window.innerWidth - 44;
      const maxY = window.innerHeight - 44;
      
      setDragPosition(prev => ({
        x: Math.max(0, Math.min(prev.x, maxX)),
        y: Math.max(0, Math.min(prev.y, maxY))
      }));
    };

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  const toggleLabel = sidebarOpen ? '隐藏目录' : '展开目录';
  const toggleSymbol = sidebarOpen ? '◀' : '☰';
  const sidebarClass = sidebarOpen ? 'sidebar open' : 'sidebar closed';
  const toggleButtonClass = sidebarOpen ? 'toggle-button open' : 'toggle-button';

  return (
    <>
      <aside className={sidebarClass} aria-hidden={!sidebarOpen}>
        <div className="sidebar-header">
          <h2>📚 文章目录</h2>
        </div>

        <div className="sidebar-content">
          {isLoading && (
            <div className="loading">
              <div className="loading-spinner" aria-hidden />
              <span>加载中...</span>
            </div>
          )}

          {error && (
            <div className="error">
              <span>目录加载失败: {error}</span>
            </div>
          )}

          {!isLoading && !error && (
            <div className="directory-tree">
              {directoryTree.map((node) => (
                <TreeNode key={node.path} node={node} />
              ))}
            </div>
          )}
        </div>
      </aside>

      <button
        ref={buttonRef}
        type="button"
        onClick={handleButtonClick}
        onTouchStart={handleTouchStart}
        onTouchMove={handleTouchMove}
        onTouchEnd={handleTouchEnd}
        className={`sidebar-toggle ${toggleButtonClass} ${isDragging ? 'dragging' : ''}`.trim()}
        style={{
          left: `${dragPosition.x}px`,
          top: `${dragPosition.y}px`,
          right: 'auto',
          transform: isDragging ? 'scale(1.1)' : 'scale(1)',
          zIndex: isDragging ? 1000 : 130
        }}
        aria-label={toggleLabel}
      >
        {toggleSymbol}
      </button>
    </>
  );
}
