import React, { useState, useEffect, useContext, useCallback } from "react";
import axios from "axios";
import { toast } from "react-toastify";

import { AuthContext } from "../context/AuthContext";
import { SSEContext } from "../context/SSEContext";

/**
 * SocialFeed component displays community posts and allows creating new posts
 * Includes real-time updates via SSE
 */
const SocialFeed = () => {
  const { auth } = useContext(AuthContext);
  const { connected, on, off, subscribe, unsubscribe } = useContext(SSEContext);
  const [posts, setPosts] = useState([]);
  const [content, setContent] = useState("");
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [submitting, setSubmitting] = useState(false);
  const [likingPostId, setLikingPostId] = useState(null);

  // Load posts from API
  const loadPosts = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const res = await axios.get("/api/posts");
      setPosts(res.data);
    } catch (err) {
      console.error("Error loading posts:", err);
      const errorMessage =
        err.response?.data?.msg ||
        err.response?.data?.message ||
        "Failed to load posts. Please try again later.";
      setError(errorMessage);
      toast.error(errorMessage);
    } finally {
      setLoading(false);
    }
  }, []);

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

  // Subscribe to posts topic on mount
  useEffect(() => {
    if (!connected) return;

    subscribe(["posts"]);

    return () => {
      unsubscribe(["posts"]);
    };
  }, [connected, subscribe, unsubscribe]);

  // Handle real-time post updates via SSE
  useEffect(() => {
    if (!connected) return;

    const handleNewPost = (data) => {
      console.log("Received new post:", data);
      setPosts((prevPosts) => [data.post, ...prevPosts]);
      toast.info("New post added to feed!");
    };

    const handlePostUpdate = (data) => {
      console.log("Received post update:", data);

      if (data.type === "post_liked") {
        // Update specific post likes
        setPosts((prevPosts) =>
          prevPosts.map((post) =>
            post._id === data.postId ? { ...post, likes: data.likes } : post
          )
        );
      } else if (data.type === "post_updated") {
        // Update existing post
        setPosts((prevPosts) =>
          prevPosts.map((post) =>
            post._id === data.post._id ? data.post : post
          )
        );
      } else if (data.type === "post_deleted") {
        // Remove deleted post
        setPosts((prevPosts) =>
          prevPosts.filter((post) => post._id !== data.postId)
        );
      }
    };

    const handleNewComment = (data) => {
      console.log("Received new comment:", data);
      // Update post with new comment
      setPosts((prevPosts) =>
        prevPosts.map((post) =>
          post._id === data.postId
            ? { ...post, comments: [...(post.comments || []), data.comment] }
            : post
        )
      );
    };

    // Subscribe to post events
    on("newPost", handleNewPost);
    on("postUpdate", handlePostUpdate);
    on("newComment", handleNewComment);

    // Cleanup on unmount
    return () => {
      off("newPost", handleNewPost);
      off("postUpdate", handlePostUpdate);
      off("newComment", handleNewComment);
    };
  }, [connected, on, off]);

  // Like a post
  const likePost = async (id) => {
    if (!auth.isAuthenticated) {
      toast.warning("Please login to like posts");
      return;
    }

    try {
      setLikingPostId(id);
      const token = localStorage.getItem("token");
      const res = await axios.put(
        `/api/posts/like/${id}`,
        {},
        {
          headers: {
            "x-auth-token": token,
          },
        }
      );
      setPosts(
        posts.map((post) =>
          post._id === id ? { ...post, likes: res.data } : post
        )
      );
    } catch (err) {
      console.error("Error liking post:", err);
      const errorMessage =
        err.response?.data?.msg ||
        err.response?.data?.message ||
        "Failed to like post. Please try again.";
      toast.error(errorMessage);
    } finally {
      setLikingPostId(null);
    }
  };

  // Submit a new post
  const onSubmit = async (e) => {
    e.preventDefault();

    if (!auth.isAuthenticated) {
      toast.warning("Please login to create posts");
      return;
    }

    if (!content.trim()) {
      toast.warning("Post content cannot be empty");
      return;
    }

    try {
      setSubmitting(true);
      const token = localStorage.getItem("token");
      const res = await axios.post(
        "/api/posts",
        { content },
        {
          headers: {
            "x-auth-token": token,
          },
        }
      );
      setPosts([res.data, ...posts]);
      setContent("");
      toast.success("Post created successfully!");
    } catch (err) {
      console.error("Error creating post:", err);
      const errorMessage =
        err.response?.data?.msg ||
        err.response?.data?.message ||
        "Failed to create post. Please try again.";
      toast.error(errorMessage);
    } finally {
      setSubmitting(false);
    }
  };

  if (loading) {
    return (
      <div className="text-center mt-5">
        <div className="spinner-border" role="status">
          <span className="sr-only">Loading...</span>
        </div>
        <p>Loading posts...</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className="alert alert-danger m-3" role="alert">
        <h4 className="alert-heading">Error Loading Posts</h4>
        <p>{error}</p>
        <hr />
        <button className="btn btn-primary" onClick={loadPosts}>
          Retry
        </button>
      </div>
    );
  }

  return (
    <div data-testid="social-feed-container">
      <div className="d-flex justify-content-between align-items-center mb-3">
        <h1>Social Feed</h1>
        {connected && (
          <span className="badge badge-success" data-testid="feed-live-updates">
            <span className="mr-1">&#9679;</span> Live Updates
          </span>
        )}
      </div>

      {auth.isAuthenticated && (
        <div className="card mb-4" data-testid="create-post-card">
          <div className="card-body">
            <h5 className="card-title">Create a Post</h5>
            <form onSubmit={onSubmit} data-testid="create-post-form">
              <div className="form-group">
                <textarea
                  className="form-control"
                  rows="3"
                  value={content}
                  onChange={(e) => setContent(e.target.value)}
                  placeholder="What's on your mind?"
                  required
                  disabled={submitting}
                  data-testid="post-content-textarea"
                />
              </div>
              <button
                type="submit"
                className="btn btn-primary"
                disabled={submitting || !content.trim()}
                data-testid="create-post-btn"
              >
                {submitting ? (
                  <>
                    <span
                      className="spinner-border spinner-border-sm mr-2"
                      role="status"
                      aria-hidden="true"
                    ></span>
                    Posting...
                  </>
                ) : (
                  "Post"
                )}
              </button>
            </form>
          </div>
        </div>
      )}

      {posts.length === 0 ? (
        <div className="alert alert-info" data-testid="no-posts-message">
          No posts yet. Be the first to share something!
        </div>
      ) : (
        <ul className="list-group" data-testid="posts-list">
          {posts.map((post) => (
            <li key={post._id} className="list-group-item" data-testid={`post-item-${post._id}`}>
              <div className="mb-2">
                <p className="mb-2" data-testid={`post-content-${post._id}`}>{post.content}</p>
                <small className="text-muted" data-testid={`post-metadata-${post._id}`}>
                  By: <strong>{post.user?.name || "Unknown User"}</strong>
                  {post.createdAt && (
                    <span className="ml-2">
                      {new Date(post.createdAt).toLocaleDateString()}{" "}
                      {new Date(post.createdAt).toLocaleTimeString()}
                    </span>
                  )}
                </small>
              </div>
              <button
                className="btn btn-sm btn-outline-primary"
                onClick={() => likePost(post._id)}
                disabled={!auth.isAuthenticated || likingPostId === post._id}
                data-testid={`like-btn-${post._id}`}
              >
                {likingPostId === post._id ? (
                  <>
                    <span
                      className="spinner-border spinner-border-sm mr-1"
                      role="status"
                      aria-hidden="true"
                    ></span>
                    Liking...
                  </>
                ) : (
                  <>
                    Like ({post.likes?.length || 0})
                  </>
                )}
              </button>
              {post.comments && post.comments.length > 0 && (
                <div className="mt-2" data-testid={`post-comments-${post._id}`}>
                  <small className="text-muted">
                    {post.comments.length} comment{post.comments.length !== 1 ? "s" : ""}
                  </small>
                </div>
              )}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};

export default SocialFeed;
