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 [files, setFiles] = useState([])
  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>
  )
}
