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 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(`/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(`/upload`, fd, {
      headers: {'Content-Type':'multipart/form-data'}
    });
    return res.data.url;
  };

  // 对话框内：提交新动态
  const handleSubmit = async () => {
    if (!content.trim()) {
      alert('内容不能为空');
      return;
    }
    try {
      await axios.post(
        `/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(`/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;

