import React, { useEffect, useState, useRef } from 'react';
import './Promotion.css';
import { useUser } from '../../../context/UserContext';
import axios from 'axios';
import PromotionCarousel from './PromotionCarousel';
import PromotionDetailDialog from './PromotionDetailDialog';
import TorrentDetailDialog from './TorrentDetailDialog';
import CreatePromotionDialog from './CreatePromotionDialog';
import CategoryPromotionDialog from './CategoryPromotionDialog';
import ColdTorrentsDialog from './ColdTorrentsDialog';

const Promotion = () => {
  const { user } = useUser();
  const [promotions, setPromotions] = useState([]);
  const [torrents, setTorrents] = useState([]);
  const [loading, setLoading] = useState(true);
  const [promoIndex, setPromoIndex] = useState(0);
  const promoTimerRef = useRef(null);
  const [showCreateDialog, setShowCreateDialog] = useState(false);
  const [showCategoryDialog, setShowCategoryDialog] = useState(false);
  const [formData, setFormData] = useState({
    name: '',
    startTime: '',
    endTime: '',
    discountPercentage: '',
    applicableTorrentIds: []
  });
  const [categoryFormData, setCategoryFormData] = useState({
    name: '',
    startTime: '',
    endTime: '',
    discountPercentage: '',
    category: 'movie'
  });

  // 冷门资源列表状态
  const [coldTorrents, setColdTorrents] = useState([]);
  const [showColdDialog, setShowColdDialog] = useState(false);
  // 新增状态：控制促销对话框中冷门资源表格的显示
  const [showPromoColdTable, setShowPromoColdTable] = useState(false);

  // 新增状态：促销详情数据和详情对话框显示控制
  const [promotionDetail, setPromotionDetail] = useState(null);
  const [showDetailDialog, setShowDetailDialog] = useState(false);

  // 新增状态：种子详情数据和种子详情对话框显示控制
  const [torrentDetail, setTorrentDetail] = useState(null);
  const [showTorrentDialog, setShowTorrentDialog] = useState(false);

  useEffect(() => {
    fetchData();
    fetchTorrentList();
  }, []);

  useEffect(() => {
    if (promotions.length === 0) return;
    clearInterval(promoTimerRef.current);
    promoTimerRef.current = setInterval(() => {
      setPromoIndex(prev => (prev + 1) % promotions.length);
    }, 5000);
    return () => clearInterval(promoTimerRef.current);
  }, [promotions]);

  const fetchData = async () => {
    try {
      const response = await fetch('/seeds/promotions');
      const json = await response.json();
      if (json.code === 0 || json.code === 200) {
        setPromotions(json.data || []);
      } else {
        console.error('获取促销活动失败:', json.msg);
      }
    } catch (error) {
      console.error('获取促销活动失败:', error);
    } finally {
      setLoading(false);
    }
  };

  const formatImageUrl = (url) => {
    if (!url) return '';
    const filename = url.split('/').pop();
    return `http://localhost:5011/uploads/torrents/${filename}`;
  };

  // 修正后的获取种子详情函数
  const fetchTorrentDetail = async (torrentId) => {
  try {
    // 修正参数名称为torrentId
    const res = await axios.post(`/seeds/info/${torrentId}`);
    if (res.data.code === 0) {
      const seedData = res.data.data;
      
      // 处理封面图片
      let cover = seedData.imageUrl;
      if (!cover && seedData.imgUrl) {
        const imgs = seedData.imgUrl
          .split(',')
          .map((i) => i.trim())
          .filter(Boolean);
        cover = imgs.length > 0 ? formatImageUrl(imgs[0]) : null;
      }
      
      setTorrentDetail({...seedData, coverImage: cover});
      setShowTorrentDialog(true);
    } else {
      alert(`获取种子详情失败: ${res.data.msg || '未知错误'}`);
    }
  } catch (err) {
    console.error('获取种子详情失败:', err);
    alert('获取种子详情失败');
  }
};


const fetchPromotionDetail = async (promotionId) => {
  try {
    const response = await fetch(`/seeds/promotions/${promotionId}`);
    const json = await response.json();
    if (json.code === 0 || json.code === 200) {
      // 正确解析applicableTorrentIds
      const data = {
        ...json.data,
        applicableTorrentIds: parseTorrentIds(json.data.applicableTorrentIds)
      };
      setPromotionDetail(data);
      setShowDetailDialog(true);
    } else {
      alert(`获取促销详情失败: ${json.msg || '未知错误'}`);
    }
  } catch (error) {
    console.error('获取促销详情失败:', error);
    alert('获取促销详情失败');
  }
};

// 解析种子ID字符串为数组
const parseTorrentIds = (idString) => {
  try {
    // 处理类似 "[69, 49, 6]" 的字符串
    return JSON.parse(idString);
  } catch (e) {
    console.error('解析种子ID失败:', e);
    return [];
  }
};

  // 关闭详情对话框
  const closeDetailDialog = () => {
    setShowDetailDialog(false);
    setPromotionDetail(null);
  };

  // 关闭种子详情对话框
  const closeTorrentDialog = () => {
    setShowTorrentDialog(false);
    setTorrentDetail(null);
  };

  const fetchTorrentList = async () => {
    try {
      const response = await fetch('/seeds/list');
      const json = await response.json();
      if (json.code === 0 || json.code === 200) {
        // 为每个种子添加selected状态
        const torrentsWithSelection = (json.data || []).map(torrent => ({
          ...torrent,
          selected: false
        }));
        setTorrents(torrentsWithSelection);
      } else {
        console.error('获取种子列表失败:', json.msg);
      }
    } catch (error) {
      console.error('获取种子列表失败:', error);
    }
  };

  const fetchColdTorrents = async () => {
    try {
      const response = await fetch('/seeds/cold');
      const json = await response.json();
      if (json.code === 0 || json.code === 200) {
        setColdTorrents(json.data || []); // 存储冷门资源数据
        setShowColdDialog(true); // 打开模态框
      } else {
        alert(`获取冷门资源失败: ${json.msg || '未知错误'}`);
      }
    } catch (error) {
      console.error('获取冷门资源失败:', error);
      alert('获取冷门资源失败');
    }
  };

  // 从服务器获取冷门资源并显示在促销对话框中
  const fetchPromoColdTorrents = async () => {
    try {
      const response = await fetch('/seeds/cold');
      const json = await response.json();
      if (json.code === 0 || json.code === 200) {
        setColdTorrents(json.data || []);
        setShowPromoColdTable(true);
      } else {
        alert(`获取冷门资源失败: ${json.msg || '未知错误'}`);
      }
    } catch (error) {
      console.error('获取冷门资源失败:', error);
      alert('获取冷门资源失败');
    }
  };

  // 处理促销对话框中种子的选择
  const handlePromoTorrentSelection = (torrentId, isChecked) => {
    setFormData(prev => {
      const ids = [...prev.applicableTorrentIds];
      if (isChecked) {
        ids.push(torrentId);
      } else {
        const index = ids.indexOf(torrentId);
        if (index !== -1) ids.splice(index, 1);
      }
      return {
        ...prev,
        applicableTorrentIds: ids
      };
    });
  };

  // 关闭冷门资源模态框
  const closeColdDialog = () => {
    setShowColdDialog(false);
    setColdTorrents([]);
  };

  const openCreateDialog = () => {
    setFormData({
      name: '',
      startTime: '',
      endTime: '',
      discountPercentage: '',
      applicableTorrentIds: []
    });
    setShowCreateDialog(true);
  };

  const closeCreateDialog = () => {
    setShowCreateDialog(false);
  };

  const openCategoryDialog = () => {
    setCategoryFormData({
      name: '',
      startTime: '',
      endTime: '',
      discountPercentage: '',
      category: 'movie'
    });
    setShowCategoryDialog(true);
  };

  const closeCategoryDialog = () => {
    setShowCategoryDialog(false);
  };

  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({
      ...prev,
      [name]: value
    }));
  };

  const handleCategoryInputChange = (e) => {
    const { name, value } = e.target;
    setCategoryFormData(prev => ({
      ...prev,
      [name]: value
    }));
  };

  const formatSize = (bytes) => {
    if (bytes === 0) return '0 B';
    
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
    const i = Math.floor(Math.log(bytes) / Math.log(1024));
    
    return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + ' ' + sizes[i];
  };

  const handleTorrentSelection = (torrentId, isChecked) => {
    setTorrents(prev => prev.map(torrent => 
      torrent.id === torrentId 
        ? {...torrent, selected: isChecked} 
        : torrent
    ));
    
    setFormData(prev => {
      const ids = [...prev.applicableTorrentIds];
      if (isChecked) {
        ids.push(torrentId);
      } else {
        const index = ids.indexOf(torrentId);
        if (index !== -1) ids.splice(index, 1);
      }
      return {
        ...prev,
        applicableTorrentIds: ids
      };
    });
  };

  const handleCreatePromotion = async () => {
    if (!formData.name.trim()) {
      alert('促销名称不能为空');
      return;
    }
    if (!formData.startTime || !formData.endTime) {
      alert('促销开始时间和结束时间不能为空');
      return;
    }
    if (new Date(formData.startTime) >= new Date(formData.endTime)) {
      alert('促销结束时间必须晚于开始时间');
      return;
    }
    if (!formData.discountPercentage || isNaN(formData.discountPercentage)) {
      alert('折扣百分比必须是数字');
      return;
    }
    if (formData.applicableTorrentIds.length === 0) {
      alert('请至少选择一个适用的种子');
      return;
    }

    const newPromo = {
      name: formData.name,
      startTime: new Date(formData.startTime).toISOString(),
      endTime: new Date(formData.endTime).toISOString(),
      discountPercentage: Number(formData.discountPercentage),
      applicableTorrentIds: formData.applicableTorrentIds // 使用formData中的种子ID
    };

    try {
      const res = await fetch('/seeds/promotions', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(newPromo)
      });
      const json = await res.json();
      if (json.code === 0 || json.code === 200) {
        alert('促销活动创建成功');
        fetchData();
        setShowCreateDialog(false);
      } else {
        alert(`创建失败: ${json.msg || '未知错误'}`);
      }
    } catch (err) {
      console.error('创建促销失败:', err);
      alert('创建促销失败');
    }
  };

  const handleCreateCategoryPromotion = async () => {
    if (!categoryFormData.name.trim()) {
      alert('促销名称不能为空');
      return;
    }
    if (!categoryFormData.startTime || !categoryFormData.endTime) {
      alert('促销开始时间和结束时间不能为空');
      return;
    }
    if (new Date(categoryFormData.startTime) >= new Date(categoryFormData.endTime)) {
      alert('促销结束时间必须晚于开始时间');
      return;
    }
    if (!categoryFormData.discountPercentage || isNaN(categoryFormData.discountPercentage)) {
      alert('折扣百分比必须是数字');
      return;
    }

    const newPromo = {
      name: categoryFormData.name,
      startTime: new Date(categoryFormData.startTime).toISOString(),
      endTime: new Date(categoryFormData.endTime).toISOString(),
      discountPercentage: Number(categoryFormData.discountPercentage)
    };

    try {
      const res = await fetch(`/seeds/promotions/category?category=${categoryFormData.category}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(newPromo)
      });
      const json = await res.json();
      if (json.code === 0 || json.code === 200) {
        alert('分类促销活动创建成功');
        fetchData();
        setShowCategoryDialog(false);
      } else {
        alert(`创建失败: ${json.msg || '未知错误'}`);
      }
    } catch (err) {
      console.error('创建分类促销失败:', err);
      alert('创建分类促销失败');
    }
  };

  const handleDeletePromotion = async (promotionId) => {
    if (!window.confirm('确认删除该促销活动吗？')) return;

    try {
      const res = await fetch(`/seeds/promotions/${promotionId}`, { method: 'DELETE' });
      const json = await res.json();
      if (json.code === 0 || json.code === 200) {
        alert('删除成功');
        fetchData();
      } else {
        alert(`删除失败: ${json.msg || '未知错误'}`);
      }
    } catch (err) {
      console.error('删除失败:', err);
    }
  };

  const isAdmin = user?.role === 'admin';
  const prevPromo = () => setPromoIndex((promoIndex - 1 + promotions.length) % promotions.length);
  const nextPromo = () => setPromoIndex((promoIndex + 1) % promotions.length);
  const currentPromo = promotions[promoIndex];

  const formatDateTime = (dateTime) => {
    if (!dateTime) return '未知';
    return new Date(dateTime).toLocaleString();
  };

  const getUploadBonusDisplay = (promo) => {
    if (!promo || !promo.discountPercentage) return '无';
    const bonus = promo.discountPercentage;
    return bonus > 0 ? `+${bonus}%` : `-${Math.abs(bonus)}%`;
  };

  const getDownloadDiscountDisplay = (promo) => {
    if (!promo || !promo.downloadDiscount) return '无';
    const discount = (1 - promo.downloadDiscount) * 100;
    return discount > 0 ? `-${discount.toFixed(1)}%` : '无';
  };

  if (loading) {
    return <div className="promotion-container">加载中...</div>;
  };

  return (
    <div className="promotion-container carousel-container">
      <PromotionCarousel
        promotions={promotions}
        currentPromo={currentPromo}
        prevPromo={prevPromo}
        nextPromo={nextPromo}
        isAdmin={isAdmin}
        openCreateDialog={openCreateDialog}
        openCategoryDialog={openCategoryDialog}
        fetchColdTorrents={fetchColdTorrents}
        handleDeletePromotion={handleDeletePromotion}
        fetchPromotionDetail={fetchPromotionDetail}
      />

      {/* 新增：冷门资源模态框 */}
      <ColdTorrentsDialog
        showColdDialog={showColdDialog}
        coldTorrents={coldTorrents}
        closeColdDialog={closeColdDialog}
        fetchTorrentDetail={fetchTorrentDetail}
      />

      {/* 促销详情对话框 */}
      <PromotionDetailDialog
        showDetailDialog={showDetailDialog}
        promotionDetail={promotionDetail}
        closeDetailDialog={closeDetailDialog}
        torrents={torrents}
        fetchTorrentDetail={fetchTorrentDetail}
      />

      {/* 种子详情对话框 */}
      <TorrentDetailDialog
        showTorrentDialog={showTorrentDialog}
        torrentDetail={torrentDetail}
        closeTorrentDialog={closeTorrentDialog}
      />

      {/* 创建冷门资源促销弹窗 */}
      <CreatePromotionDialog
        showCreateDialog={showCreateDialog}
        formData={formData}
        handleInputChange={handleInputChange}
        closeCreateDialog={closeCreateDialog}
        handleCreatePromotion={handleCreatePromotion}
        fetchPromoColdTorrents={fetchPromoColdTorrents}
        showPromoColdTable={showPromoColdTable}
        coldTorrents={coldTorrents}
        handlePromoTorrentSelection={handlePromoTorrentSelection}
      />

      {/* 创建特定分类促销弹窗 */}
      <CategoryPromotionDialog
        showCategoryDialog={showCategoryDialog}
        categoryFormData={categoryFormData}
        handleCategoryInputChange={handleCategoryInputChange}
        closeCategoryDialog={closeCategoryDialog}
        handleCreateCategoryPromotion={handleCreateCategoryPromotion}
      />
    </div>
  );
};

export default Promotion;    

