import React, { useState, useEffect } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { getUserTorrents, deleteTorrent } from '../../api/personal';
import './personalSubpage.css';

const Upload = ({ onLogout }) => {
  const navigate = useNavigate();
  const location = useLocation();
  const [torrents, setTorrents] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [pagination, setPagination] = useState({
    page: 1,
    size: 5,
    total: 0
  });



  // 格式化日期
  const formatDate = (dateString) => {
    const date = new Date(dateString);
    return date.toLocaleString();
  };

  // 获取上传记录
  const fetchTorrents = async () => {
    try {
      setLoading(true);
      const { records, total } = await getUserTorrents(pagination.page, pagination.size);
      setTorrents(records);
      setPagination(prev => ({ ...prev, total }));
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  

  // 删除种子
  const handleDelete = async (id) => {
    if (window.confirm('确定要删除这个种子吗？此操作不可撤销！')) {
      try {
        await deleteTorrent(id);
        // 删除成功后刷新列表
        fetchTorrents();
      } catch (err) {
        alert('删除失败: ' + err.message);
      }
    }
  };

  // 计算总页数
  const totalPages = Math.ceil(pagination.total / pagination.size);

  // 生成页码数组
  const getPageNumbers = () => {
    const pages = [];
    const maxVisiblePages = 5; // 最多显示5个页码
    
    let startPage = Math.max(1, pagination.page - Math.floor(maxVisiblePages / 2));
    let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
    
    // 调整起始页码，确保始终显示 maxVisiblePages 个页码（如果总页数足够）
    if (endPage - startPage + 1 < maxVisiblePages) {
      startPage = Math.max(1, endPage - maxVisiblePages + 1);
    }
    
    for (let i = startPage; i <= endPage; i++) {
      pages.push(i);
    }
    
    return pages;
  };

  // 直接跳转到指定页码
  const jumpToPage = (page) => {
    if (page >= 1 && page <= totalPages && page !== pagination.page) {
      setPagination(prev => ({ ...prev, page }));
    }
  };

  // 分页改变
  const handlePageChange = (newPage) => {
    setPagination(prev => ({ ...prev, page: newPage }));
  };

  useEffect(() => {
    fetchTorrents();
  }, [pagination.page]);

  const handleBack = () => {
    navigate('/personal', { 
      state: { 
        fromSubpage: true,
        dashboardTab: location.state?.dashboardTab
      },
      replace: true
    });
  };

  if (loading) {
    return <div className="subpage-container">加载中...</div>;
  }

  if (error) {
    return <div className="subpage-container">错误: {error}</div>;
  }

  return (
    <div className="subpage-container">
      <button className="back-button" onClick={handleBack}>
        ← 返回个人中心
      </button>

      <h2 className="page-title">上传记录</h2>
      
      <table className="uploads-table">
        <thead>
          <tr>
            <th>资源名称</th>
            <th>大小</th>
            <th>上传时间</th>
            <th>下载次数</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          {torrents.map(torrent => (
            <tr key={torrent.id} className="list-item">
              <td>{torrent.torrentName}</td>
              <td>{torrent.formattedSize}</td>
              <td>{formatDate(torrent.createTime)}</td>
              <td>{torrent.downloadCount || 0}</td>
              <td>
                <button 
                  className="action-btn delete-btn"
                  onClick={() => handleDelete(torrent.id)}
                >
                  删除
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>

     {/* 修改后的分页控件 */}
     <div className="pagination">
        <button 
          disabled={pagination.page <= 1}
          onClick={() => jumpToPage(1)}
          className="page-nav"
        >
          首页
        </button>
        <button 
          disabled={pagination.page <= 1}
          onClick={() => jumpToPage(pagination.page - 1)}
          className="page-nav"
        >
          上一页
        </button>
        
        {/* 显示页码 */}
        {getPageNumbers().map(number => (
          <button
            key={number}
            onClick={() => jumpToPage(number)}
            className={`page-number ${pagination.page === number ? 'active' : ''}`}
          >
            {number}
          </button>
        ))}
        
        {/* 显示省略号（如果有更多页） */}
        {totalPages > getPageNumbers()[getPageNumbers().length - 1] && (
          <span className="ellipsis">...</span>
        )}
        
        <button 
          disabled={pagination.page >= totalPages}
          onClick={() => jumpToPage(pagination.page + 1)}
          className="page-nav"
        >
          下一页
        </button>
        <button 
          disabled={pagination.page >= totalPages}
          onClick={() => jumpToPage(totalPages)}
          className="page-nav"
        >
          末页
        </button>
        
        <div className="page-info">
          <span>共 {totalPages} 页</span>
          <span>跳至</span>
          <input
            type="number"
            min="1"
            max={totalPages}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                const page = parseInt(e.target.value);
                if (!isNaN(page)) {
                  jumpToPage(Math.max(1, Math.min(page, totalPages)));
                  e.target.value = '';
                }
              }
            }}
          />
          <span>页</span>
        </div>
      </div>
    </div>
  );
};

export default Upload;