import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './FriendMoments.css';
import Header from '../../components/Header';
import { Edit } from '@icon-park/react';

const API_BASE = process.env.REACT_APP_API_BASE;
const USER_ID = 456;

const FriendMoments = () => {
  const [feeds, setFeeds] = useState([]);
  const [filteredFeeds, setFilteredFeeds] = useState([]);
  const [query, setQuery] = useState('');

  // Modal state & form fields
  const [showModal, setShowModal] = useState(false);
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');
  const [previewUrls, setPreviewUrls] = useState([]);
  const [images, setImages] = useState([]);

  // 拉取好友动态列表
  const fetchFeeds = async () => {
    try {
      const res = await axios.get(`${API_BASE}/echo/users/${USER_ID}/feeds`);
      setFeeds(res.data.feeds);
      setFilteredFeeds(res.data.feeds);
    } catch (err) {
      console.error('获取动态列表失败：', err);
    }
  };

  useEffect(() => {
    fetchFeeds();
  }, []);

  // 搜索处理
  const handleSearch = () => {
    const q = query.trim().toLowerCase();
    if (!q) return;
    setFilteredFeeds(
      feeds.filter(f => (f.title || '').toLowerCase().includes(q))
    );
  };
  const handleReset = () => {
    setQuery('');
    setFilteredFeeds(feeds);
  };

  // 对话框内：本地预览 & 上传
  const handleImageChange = async (e) => {
    const files = Array.from(e.target.files);
    if (!files.length) return;
    setPreviewUrls(files.map(f => URL.createObjectURL(f)));
    try {
      const uploaded = await Promise.all(files.map(f => uploadImageToServer(f)));
      setImages(uploaded);
    } catch (err) {
      console.error('图片上传失败', err);
      alert('图片上传失败，请重试');
    }
  };
  const uploadImageToServer = async (file) => {
    const fd = new FormData();
    fd.append('file', file);
    const res = await axios.post(`${API_BASE}/upload`, fd, {
      headers: {'Content-Type':'multipart/form-data'}
    });
    return res.data.url;
  };

  // 对话框内：提交新动态
  const handleSubmit = async () => {
    if (!content.trim()) {
      alert('内容不能为空');
      return;
    }
    try {
      await axios.post(
        `${API_BASE}/echo/users/${USER_ID}/createFeed`,
        { title: title.trim() || undefined, friend_content: content.trim(), images }
      );
      // 重置表单
      setTitle('');
      setContent('');
      setImages([]);
      setPreviewUrls([]);
      setShowModal(false);
      fetchFeeds();
    } catch (err) {
      console.error('发布失败', err);
      alert('发布失败，请稍后重试');
    }
  };

  // 删除动态
  const handleDelete = async (feedId) => {
    if (!window.confirm('确定要删除这条动态吗？')) return;
    try {
      await axios.delete(`${API_BASE}/echo/users/me/feed/${feedId}`);
      fetchFeeds();
    } catch (err) {
      console.error('删除失败', err);
      alert('删除失败');
    }
  };

  return (
    <div className="friend-moments-container">
      <Header />
      <div className="fm-header">
        <button className="create-btn" onClick={() => setShowModal(true)}>
          <Edit theme="outline" size="18" style={{ marginRight: '6px' }} />
          创建动态
        </button>
        <div className="f-search-bar">
          <input
            className="search-input"
            type="text"
            value={query}
            onChange={e => setQuery(e.target.value)}
            placeholder="输入要搜索的动态"
          />
          <button className="search-btn" onClick={handleSearch}>搜索</button>
          <button className="search-btn" onClick={handleReset}>重置</button>
        </div>
      </div>

      <div className="feed-list">
        {filteredFeeds.map(feed => (
          <div className="feed-item" key={feed.feed_id}>
            {feed.title && <h4>{feed.title}</h4>}
            <p>{feed.friend_content}</p>

            {feed.images?.length > 0 && (
              <div className="feed-images">
                {feed.images.map((url, i) => (
                  <img key={i} src={url} alt={`动态图${i}`} />
                ))}
              </div>
            )}

            <div className="feed-footer">
              <span className="feed-date">
                {new Date(feed.created_at).toLocaleString()}
              </span>
              {feed.is_mine && (
                <button className="delete-btn" onClick={() => handleDelete(feed.feed_id)}>
                  删除
                </button>
              )}
            </div>
          </div>
        ))}
      </div>

      {/* Modal 对话框 */}
      {showModal && (
        <div className="modal-overlay" onClick={() => setShowModal(false)}>
          <div className="modal-dialog" onClick={e => e.stopPropagation()}>
            <h3>发布新动态</h3>
            <input
              type="text"
              placeholder="标题"
              value={title}
              onChange={e => setTitle(e.target.value)}
            />
            <textarea
              placeholder="写下你的内容..."
              value={content}
              onChange={e => setContent(e.target.value)}
            />
            {/* <input
              type="file"
              accept="image/*"
              multiple
              onChange={handleImageChange}
            /> */}
            <label className="file-label">
              选择图片
              <input
                type="file"
                accept="image/*"
                multiple
                onChange={handleImageChange}
                style={{ display: 'none' }}
              />
            </label>
            <div className="cf-preview">
              {previewUrls.map((url, i) => (
                <img key={i} src={url} alt={`预览${i}`} />
              ))}
            </div>
            <div className="modal-actions">
              <button className="btn cancel" onClick={() => setShowModal(false)}>
                取消
              </button>
              <button className="btn submit" onClick={handleSubmit}>
                发布
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default FriendMoments;

