import React, { useState, useEffect } from 'react';
import { fetchRecordLog } from '../api/posts_trm';

function TransactionLogs({ userId }) {
  const [allRecords, setAllRecords] = useState([]);
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize] = useState(10);
  const [loading, setLoading] = useState(false);

  const loadRecords = async () => {
    setLoading(true);
    try {
      const data = await fetchRecordLog();
      setAllRecords(data);
    } catch (err) {
      console.error('fetchRecordLog error:', err);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    loadRecords();
  }, [userId]);

  const total = allRecords.length;
  const totalPages = Math.ceil(total / pageSize);
  
  // 计算当前页显示的数据
  const startIndex = (currentPage - 1) * pageSize;
  const endIndex = startIndex + pageSize;
  const currentRecords = allRecords.slice(startIndex, endIndex);

  const handlePrevPage = () => {
    if (currentPage > 1) {
      setCurrentPage(currentPage - 1);
    }
  };

  const handleNextPage = () => {
    if (currentPage < totalPages) {
      setCurrentPage(currentPage + 1);
    }
  };

  const handlePageClick = (page) => {
    setCurrentPage(page);
  };

  const renderPageNumbers = () => {
    const pages = [];
    const maxVisiblePages = 5;
    
    let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
    let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
    
    if (endPage - startPage < maxVisiblePages - 1) {
      startPage = Math.max(1, endPage - maxVisiblePages + 1);
    }

    for (let i = startPage; i <= endPage; i++) {
      pages.push(
        <button
          key={i}
          onClick={() => handlePageClick(i)}
          className={`page-btn ${currentPage === i ? 'active' : ''}`}
        >
          {i}
        </button>
      );
    }
    return pages;
  };

  return (
    <section className="dashboard-logs">
      <table className="admin-table">
        <thead>
          <tr>
            <th>ID</th>
            <th>用户ID</th>
            <th>类型</th>
            <th>内容</th>
            <th>IP</th>
            <th>创建时间</th>
          </tr>
        </thead>
        <tbody>
          {loading ? (
            <tr>
              <td colSpan="6" style={{ textAlign: 'center' }}>加载中...</td>
            </tr>
          ) : currentRecords.length > 0 ? (
            currentRecords.map((r, i) => (
              <tr key={r.id || i}>
                <td>{r.id}</td>
                <td>{r.user_id}</td>
                <td>{r.type}</td>
                <td>{r.content}</td>
                <td>{r.ip}</td>
                <td>{new Date(r.created_at).toLocaleString()}</td>
              </tr>
            ))
          ) : (
            <tr>
              <td colSpan="6" style={{ textAlign: 'center' }}>暂无数据</td>
            </tr>
          )}
        </tbody>
      </table>
      
      {totalPages > 1 && (
        <div className="pagination">
          <button 
            onClick={handlePrevPage} 
            disabled={currentPage === 1}
            className="page-btn"
          >
            上一页
          </button>
          
          {renderPageNumbers()}
          
          <button 
            onClick={handleNextPage} 
            disabled={currentPage === totalPages}
            className="page-btn"
          >
            下一页
          </button>
          
          <span className="page-info">
            第 {currentPage} 页，共 {totalPages} 页，总计 {total} 条记录
          </span>
        </div>
      )}
      
      <style jsx>{`
        .pagination {
          display: flex;
          align-items: center;
          justify-content: center;
          gap: 8px;
          margin-top: 16px;
          flex-wrap: wrap;
        }
        
        .page-btn {
          padding: 6px 12px;
          border: 1px solid #ddd;
          background: white;
          cursor: pointer;
          border-radius: 4px;
          transition: all 0.2s;
        }
        
        .page-btn:hover:not(:disabled) {
          background: #f5f5f5;
          border-color: #999;
        }
        
        .page-btn:disabled {
          opacity: 0.5;
          cursor: not-allowed;
        }
        
        .page-btn.active {
          background: #007bff;
          color: white;
          border-color: #007bff;
        }
        
        .page-info {
          margin-left: 16px;
          font-size: 14px;
          color: #666;
        }
      `}</style>
    </section>
  );
}

export default TransactionLogs;
