import React, { useState, useEffect } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import UploadPage from './UploadPage'
import { 
  createPost, 
  updatePost, 
  fetchPost as fetchPostDetail 
} from '../api/posts_wzy'
import { getUserInfo } from '../utils/auth'
import '../style/CreatePost.css'

export default function CreatePost() {
  const navigate = useNavigate()
  const { postId } = useParams()
  const isEdit = Boolean(postId)
  // 步骤：新帖先上传，编辑则直接到 detail
  const [step, setStep] = useState(isEdit ? 'detail' : 'upload')
  const [mediaUrls, setMediaUrls] = useState([])

  // 表单字段
  const [title, setTitle]     = useState('')
  const [content, setContent] = useState('')
  const [topicId, setTopicId] = useState('')
  const [status, setStatus]   = useState('published')

  const [error, setError]     = useState(null)
  const [loading, setLoading] = useState(isEdit)

  // 静态话题
  const TOPICS = [
    { id: 1, name: '世俱杯环球评大会' },
    { id: 2, name: '我的REDmentor' },
    { id: 3, name: '我染上了拼豆' },
  ]

  // 获取当前登录用户id
  const user = getUserInfo()
  const currentUserId = user?.id

  // 编辑模式：拉取原帖数据填入
  useEffect(() => {
    if (!isEdit) return
    fetchPostDetail(postId)
      .then(data => {
        setTitle(data.title)
        setContent(data.content)
        setTopicId(data.topic_id || '')
        setStatus(data.status)
        setMediaUrls(data.media_urls || [])
      })
      .catch(err => setError(err.message))
      .finally(() => setLoading(false))
  }, [isEdit, postId])

  // 上传回调 - 保存原始文件对象
  const handleUploadComplete = async uploadedFiles => {
    setFiles(uploadedFiles)
    // 为预览创建临时URLs
    const urls = uploadedFiles.map(f => URL.createObjectURL(f))
    setMediaUrls(urls)
    setStep('detail')
  }

  // 提交（创建/更新）
  const handleSubmit = async () => {
    if (!title.trim() || !content.trim()) {
      setError('标题和正文必填')
      return
    }
    if (!currentUserId) {
      setError('未获取到用户ID，请重新登录')
      return
    }
    setError(null)
    
    try {
      // 创建FormData对象
      const formData = new FormData()
      
      // 添加文本字段
      formData.append('user_id', currentUserId)
      formData.append('title', title.trim())
      formData.append('content', content.trim())
      formData.append('status', status)
      if (topicId) {
        formData.append('topic_id', topicId)
      }
      
      if (isEdit) {
        // 编辑模式：如果有新文件，添加新文件；否则保留现有URLs
        if (files.length > 0) {
          files.forEach((file, index) => {
            formData.append(`media_${index}`, file)
          })
          formData.append('media_count', files.length)
        } else {
          // 保留现有的media_urls
          formData.append('existing_media_urls', JSON.stringify(mediaUrls))
        }
        
        await updatePost(postId, formData)
        alert('更新成功！')
      } else {
        // 创建模式：添加文件
        files.forEach((file, index) => {
          formData.append(`media_${index}`, file)
        })
        formData.append('media_count', files.length)
        
        await createPost(formData)
        alert('发布成功！')
      }
      navigate('/notebooks', { replace: true })
    } catch (e) {
      setError(e.message)
    }
  }

  if (loading) return <p>加载中…</p>
  if (step === 'upload' && !isEdit) {
    return <UploadPage onComplete={handleUploadComplete} />
  }

  return (
    <div className="create-post">
      <h2>{isEdit ? '编辑帖子' : '填写帖子内容'}</h2>
      {error && <div className="error">{error}</div>}

      {/* 媒体预览 */}
      <div className="preview-media">
        {mediaUrls.map((url, i) => (
          <div key={i} className="preview-item">
            {url.match(/\.(mp4|mov|avi)$/) ? (
              <video src={url} controls />
            ) : (
              <img src={url} alt={`预览 ${i}`} />
            )}
          </div>
        ))}
      </div>

      {/* 标题 */}
      <label className="form-label">
        标题（最多20字）
        <input
          type="text"
          maxLength={20}
          value={title}
          onChange={e => setTitle(e.target.value)}
        />
        <span className="char-count">{title.length}/20</span>
      </label>

      {/* 正文 */}
      <label className="form-label">
        正文（最多1000字）
        <textarea
          maxLength={1000}
          value={content}
          onChange={e => setContent(e.target.value)}
        />
        <span className="char-count">{content.length}/1000</span>
      </label>

      {/* 话题选择 */}
      <label className="form-label">
        选择话题（可选）
        <select
          value={topicId}
          onChange={e => setTopicId(e.target.value)}
        >
          <option value="">不添加话题</option>
          {TOPICS.map(t => (
            <option key={t.id} value={t.id}>
              #{t.name}
            </option>
          ))}
        </select>
      </label>

      {/* 发布状态 */}
      <div className="status-group">
        <label>
          <input
            type="radio"
            name="status"
            value="published"
            checked={status === 'published'}
            onChange={() => setStatus('published')}
          />
          立即发布
        </label>
        <label>
          <input
            type="radio"
            name="status"
            value="draft"
            checked={status === 'draft'}
            onChange={() => setStatus('draft')}
          />
          存为草稿
        </label>
      </div>

      {/* 按钮 */}
      <div className="btn-group">
        <button className="btn btn-primary" onClick={handleSubmit}>
          {isEdit ? '更新' : '发布'}
        </button>
        {!isEdit && (
          <button className="btn btn-secondary" onClick={() => setStep('upload')}>
            上一步
          </button>
        )}
      </div>
    </div>
  )
}
