// export default PublishSeed;
import React, { useState, useRef, useEffect } from 'react';
import axios from 'axios';
import Header from '../../components/Header';
import './PublishSeed.css';
import { useUser } from '../../context/UserContext';

const PublishSeed = () => {
  const [title, setTitle] = useState('');
  const [description, setDescription] = useState('');
  const [tags, setTags] = useState([]);
  const [category, setCategory] = useState('movie');
  const [message, setMessage] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [fileName, setFileName] = useState('');
  const [imageFile, setImageFile] = useState(null);
  const [previewUrl, setPreviewUrl] = useState('');

  const fileInputRef = useRef(null);
  const imageInputRef = useRef(null);
  const { user } = useUser();

  useEffect(() => {
    console.log('[DEBUG] 当前用户:', user);
  }, [user]);

  const handleTagsChange = (e) => {
    console.log('[DEBUG] 标签输入变化:', e.target.value);
    setTags(e.target.value.split(',').map(tag => tag.trim()).filter(Boolean));
  };

  const handleFileButtonClick = () => {
    console.log('[DEBUG] 触发文件选择按钮点击');
    fileInputRef.current?.click();
  };

  const handleImageButtonClick = () => {
    console.log('[DEBUG] 触发封面图片选择按钮点击');
    imageInputRef.current?.click();
  };

  const handleFileChange = (e) => {
    console.log('[DEBUG] 种子文件选择变化:', e.target.files);
    const selectedFile = e.target.files[0];
    if (selectedFile) {
      setFileName(selectedFile.name);
    }
  };

  const handleImageChange = (e) => {
    console.log('[DEBUG] 封面图片选择变化:', e.target.files);
    const img = e.target.files[0];
    if (!img) return;
    setImageFile(img);
    setPreviewUrl(URL.createObjectURL(img));
  };

  const handleSubmit = async (e) => {
    console.log('[DEBUG] handleSubmit 被触发', e);
    e.preventDefault();

    setIsLoading(true);
    setMessage('');

    const currentFile = fileInputRef.current?.files[0];
    console.log('[DEBUG] 当前选择文件:', currentFile);

    if (!user || !user.userId) {
      console.log('[DEBUG] 用户未登录，阻止上传');
      setMessage('请先登录');
      setIsLoading(false);
      return;
    }

    if (!currentFile || !currentFile.name.toLowerCase().endsWith('.torrent')) {
      console.log('[DEBUG] 文件校验失败');
      setMessage('请上传一个 .torrent 文件');
      setIsLoading(false);
      return;
    }

    const formData = new FormData();
    formData.append('file', currentFile);
    formData.append('title', title);
    formData.append('description', description);
    formData.append('category', category);
    formData.append('tags', tags.join(',')); // 逗号分隔字符串
    formData.append('uploader', user.userId);

    if (imageFile) {
      formData.append('coverImage', imageFile);
    }

    try {
      console.log('[DEBUG] 发送上传请求...');
      const response = await axios.post('/seeds/upload', formData, {
        // axios 会自动处理 multipart/form-data Content-Type 边界，不用手动设置
        // headers: { 'Content-Type': 'multipart/form-data' },
      });
      console.log('[DEBUG] 请求成功，响应:', response.data);

      if (response.data.status === 'success') {
        setMessage('种子上传成功');
      } else {
        setMessage(response.data.message || '上传失败，请稍后再试');
      }
    } catch (error) {
      console.error('[handleSubmit] 上传失败:', error);
      setMessage('上传失败，发生了错误');
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div className="publish-seed-container">
      <Header />
      <div className="pub-card">
        {message && <div className="message">{message}</div>}
        <form
          onSubmit={(e) => {
            console.log('[DEBUG] form onSubmit 触发');
            handleSubmit(e);
          }}
          encType="multipart/form-data"
        >
          <div className="title-tag">
            <label>标题</label>
            <input
              type="text"
              value={title}
              onChange={(e) => {
                console.log('[DEBUG] 标题输入变化:', e.target.value);
                setTitle(e.target.value);
              }}
              required
            />
          </div>

          <div className="discription">
            <label>描述</label>
            <textarea
              value={description}
              onChange={(e) => {
                console.log('[DEBUG] 描述输入变化:', e.target.value);
                setDescription(e.target.value);
              }}
              required
            />
          </div>

          <div className="title-tag">
            <label>标签 (逗号分隔)</label>
            <input
              type="text"
              value={tags.join(', ')}
              onChange={handleTagsChange}
              placeholder="例如：科幻, 动作"
              required
            />
          </div>

          <div className="pub-categoty">
            <label>分类</label>
            <select
              value={category}
              onChange={(e) => {
                console.log('[DEBUG] 分类选择变化:', e.target.value);
                setCategory(e.target.value);
              }}
              required
            >
              <option value="movie">电影</option>
              <option value="tv">电视剧</option>
              <option value="music">音乐</option>
              <option value="anime">动漫</option>
              <option value="game">游戏</option>
              <option value="variety">综艺</option>
              <option value="software">软件</option>
              <option value="sports">体育</option>
              <option value="study">学习</option>
              <option value="documentary">纪录片</option>
              <option value="other">其他</option>
            </select>
          </div>

          <div className="seed-file">
            <label>种子文件</label>
            <div
              className="seed-file-label"
              onClick={handleFileButtonClick}
              style={{ cursor: 'pointer' }}
            >
              点击选择文件
            </div>
            <input
              type="file"
              accept=".torrent"
              ref={fileInputRef}
              onChange={handleFileChange}
              style={{ display: 'none' }}
            />
            {fileName && <div style={{ marginTop: '5px' }}>{fileName}</div>}
          </div>

          <div className="form-group">
            <label>封面图</label>
            <div className="cover-upload">
              <button type="button" onClick={handleImageButtonClick}>
                上传图片
              </button>
              <input
                type="file"
                accept="image/*"
                ref={imageInputRef}
                onChange={handleImageChange}
                style={{ display: 'none' }}
              />
            </div>
            {previewUrl && (
              <div style={{ marginTop: '10px' }}>
                <img
                  src={previewUrl}
                  alt="封面预览"
                  style={{ maxWidth: '100%', maxHeight: '200px' }}
                />
              </div>
            )}
          </div>

          <div className="upload-button">
            <button
              type="submit"
              disabled={isLoading}
              onClick={() => console.log('[DEBUG] 上传按钮 onClick 触发')}
            >
              {isLoading ? '正在上传...' : '上传种子'}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};

export default PublishSeed;
