import React, { useState } from 'react';
import './PromotionCarousel.css'; 

const PromotionCarousel = ({
  promotions,
  isAdmin,
  openCreateDialog,
  openCategoryDialog,
  fetchColdTorrents,
  handleDeletePromotion,
  fetchPromotionDetail
}) => {
  // 1. 新增状态：跟踪当前轮播项的索引
  const [currentIndex, setCurrentIndex] = useState(0);

  // 2. 上一个/下一个轮播的逻辑
  const prevPromo = () => {
    if (promotions.length === 0) return;
    setCurrentIndex(prev => 
      prev === 0 ? promotions.length - 1 : prev - 1
    );
  };

  const nextPromo = () => {
    if (promotions.length === 0) return;
    setCurrentIndex(prev => 
      prev === promotions.length - 1 ? 0 : prev + 1
    );
  };

  // 3. 当前显示的促销项（从数组中取）
  const currentPromo = promotions[currentIndex];

  // 原有工具函数保持不变
  const formatDateTime = (dateTime) => {
    if (!dateTime) return '未知';
    // dateTime [2025,1,3,12,10]
    return new Date(...dateTime).toLocaleString();

  };

  // 修改为一个统一的处理函数，避免混淆
const getUploadBonusDisplay = (promo) => {
  if (!promo || typeof promo.discountPercentage !== 'number') return '无';
  const bonus = promo.discountPercentage;
  return bonus > 0 ? `${(bonus * 100).toFixed(0)}%` : '无';
};

const getDownloadDiscountDisplay = (promo) => {
  if (!promo || typeof promo.discountPercentage !== 'number') return '无';
  const discount = promo.discountPercentage;
  return discount < 0 ? `${Math.abs(discount * 100).toFixed(0)}%` : '无';
};


  if (!Array.isArray(promotions) || promotions.length === 0 || !promotions[currentIndex]) {
  return (
    <section className="carousel-section">
      <h2 style={{ marginLeft: '1.6rem' }}>当前促销活动</h2>
      {isAdmin && (
        <div style={{ display: 'flex', gap: '0px', marginBottom: '10px' }}>
          <button className="create-btn" onClick={openCreateDialog}>
            +创建冷门资源促销
          </button>
          <button className="create-btn" onClick={openCategoryDialog}>
            +创建特定分类促销
          </button>
        </div>
      )}
      <div className="empty-state">暂无促销活动</div>
    </section>
  );
}


  return (
    <section className="carousel-section">
      <h2 style={{ marginLeft: '1.6rem' }}>当前促销活动</h2>

      {isAdmin && (
        <div style={{ display: 'flex', gap: '0px', marginBottom: '10px' }}>
          <button className="create-btn" onClick={openCreateDialog}>
            +创建冷门资源促销
          </button>
          <button className="create-btn" onClick={openCategoryDialog}>
            +创建特定分类促销
          </button>
        </div>
      )}

      <div
        className="carousel"
        onMouseEnter={() => {}}
        onMouseLeave={() => {}}
      >

        <button className="arrow left" onClick={prevPromo}>&lt;</button>
        <div className="slide">
          <div className='promotion-name'><strong>{currentPromo?.name ?? '未知'}</strong></div>
          <div style={{ color: '#135c69' }}><strong>促销时间：</strong>
            {currentPromo?.startTime && currentPromo?.endTime
              ? `${formatDateTime(currentPromo.startTime)} ～ ${formatDateTime(currentPromo.endTime)}`
              : '未知'}
          </div>
          <div style={{ color: '#135c69' }}><strong>上传奖励：</strong>{getUploadBonusDisplay(currentPromo)}</div>
          <div style={{ color: '#135c69' }}><strong>下载折扣：</strong>{getDownloadDiscountDisplay(currentPromo)}</div>
          {currentPromo?.description && (
            <div><strong>描述：</strong>{currentPromo.description}</div>
          )}            

          <div className="action-buttons" style={{ display: 'flex', gap: '10px' }}>
            {isAdmin && (
              <button className="delete-btn" onClick={() => handleDeletePromotion(currentPromo.id)}>
                删除活动
              </button>
            )}
            <button
              className="view-btn"
              onClick={() => fetchPromotionDetail(currentPromo.id)}
              aria-label={`查看${currentPromo.name}的详情`}
            >
              查看详情
            </button>
          </div>
        </div>
        <button className="arrow right" onClick={nextPromo}>&gt;</button>

        {/* 4. 新增：底部指示器 */}
        <div className="carousel-indicators">
          {promotions.map((_, index) => (
            <div
              key={index}
              className={`indicator ${currentIndex === index ? 'active' : ''}`}
              onClick={() => setCurrentIndex(index)} // 点击切换轮播项
            />
          ))}
        </div>
      </div>
    </section>
  );
};

export default PromotionCarousel;