using instavibe.Models; using InstaVibe.Models; using System; using System.Collections.Generic; using System.Configuration; using System.Data.SqlClient; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Security.Policy; using System.Web; using System.Web.Mvc; using System.Web.Services.Description; namespace InstaVibe.Controllers { public class HomeController : Controller { private static readonly string connectionString = ConfigurationManager .ConnectionStrings["InstaVibe"].ConnectionString; //SEARCH public JsonResult SearchSuggestions(string term) { List results = new List(); using (SqlConnection con = new SqlConnection(connectionString)) { string query = @"SELECT TOP 5 user_id, username, profile_picture FROM Users WHERE username LIKE @term OR fullname LIKE @term"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@term", "%" + term + "%"); con.Open(); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { results.Add(new { UserId = reader["user_id"], Username = reader["username"].ToString(), ProfilePicture = string.IsNullOrEmpty(reader["profile_picture"].ToString()) ? "/Content/images/default.jpg" : reader["profile_picture"].ToString() }); } } return Json(results, JsonRequestBehavior.AllowGet); } // ================== CREATE POST ================== [HttpPost] public JsonResult Create() { string caption = Request.Form["caption"]; HttpPostedFileBase file = Request.Files["UploadedFile"]; string fileName = ""; string mediaUrl = ""; bool isSaved = false; if (file != null && file.ContentLength > 0) { try { if (Session["UserId"] == null) { return Json(new { success = false, message = "Session expired. Please login again." }); } string extension = Path.GetExtension(file.FileName).ToLower(); string[] allowedImageExtensions = { ".jpg", ".jpeg", ".png" }; string[] allowedVideoExtensions = { ".mp4", ".mov", ".avi" }; if (!allowedImageExtensions.Contains(extension) && !allowedVideoExtensions.Contains(extension)) { return Json(new { success = false, message = "Only JPG, PNG, MP4, and MOV files are allowed." }); } // Size Validation if (allowedImageExtensions.Contains(extension) && file.ContentLength > 5 * 1024 * 1024) { return Json(new { success = false, message = "Image must be less than 5MB." }); } if (allowedVideoExtensions.Contains(extension) && file.ContentLength > 20 * 1024 * 1024) { return Json(new { success = false, message = "Video must be less than 20MB." }); } // Save file int userId = Convert.ToInt32(Session["UserId"]); fileName = Path.GetFileName(file.FileName); string uploadFolder = Server.MapPath("~/UserUploads"); if (!Directory.Exists(uploadFolder)) { Directory.CreateDirectory(uploadFolder); } string filePath = Path.Combine(uploadFolder, fileName); mediaUrl = "/UserUploads/" + fileName; file.SaveAs(filePath); using (SqlConnection con = new SqlConnection(connectionString)) { string query = "INSERT INTO Posts (user_id, caption, media_url, Accepted, IsDeleted, isAvailable) " + "VALUES (@user_id, @caption, @media_url, 0, 0, 1)"; using (SqlCommand cmd = new SqlCommand(query, con)) { cmd.Parameters.AddWithValue("@user_id", userId); cmd.Parameters.AddWithValue("@caption", caption); cmd.Parameters.AddWithValue("@media_url", mediaUrl); cmd.Parameters.AddWithValue("@is_available", true); // keeps the post visible cmd.Parameters.AddWithValue("@Accepted", 0); // admin hasn’t accepted yet cmd.Parameters.AddWithValue("@IsDeleted", 0); // not deleted con.Open(); int rowsAffected = cmd.ExecuteNonQuery(); isSaved = rowsAffected > 0; } } } catch (Exception ex) { return Json(new { success = false, message = "Error: " + ex.Message }); } } else { return Json(new { success = false, message = "Please upload a valid file." }); } return Json(new { success = isSaved, message = "Post uploaded successfully!", caption = caption, file = mediaUrl }); } // ================== HOME PAGE (Index) ================== public ActionResult Index() { // Get the logged-in user var currentUser = GetCurrentUser(); var currentUserId = currentUser.UserId; // Fetch posts var posts = GetPosts(); // Pass user info to the view ViewBag.User = currentUser; ViewBag.CurrentUser = currentUser; return View(posts); // Posts will be the model } // ================== GET POSTS ================== private List GetPosts() { List posts = new List(); int? currentUserId = Session["UserId"] as int?; using (SqlConnection con = new SqlConnection(connectionString)) { string postQuery = @" SELECT u.profile_picture, p.*, u.username, CASE WHEN YEAR(GETDATE()) <= u.joining_year + 4 THEN 'Student' ELSE 'Alumni' END AS UserType FROM Posts p LEFT JOIN users u ON p.user_id = u.user_id WHERE p.IsDeleted = 0 ORDER BY p.created_at DESC"; using (SqlCommand cmd = new SqlCommand(postQuery, con)) { con.Open(); using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { posts.Add(new Post { PostId = (int)reader["post_id"], UserId = (int)reader["user_id"], Caption = reader["caption"].ToString(), MediaUrl = reader["media_url"].ToString(), CreatedAt = (DateTime)reader["created_at"], UserProfilePic = reader["profile_picture"].ToString(), Username = reader["username"].ToString(), UserType = reader["UserType"].ToString() }); } } con.Close(); } // Likes and top liker if (currentUserId.HasValue) { con.Open(); foreach (var post in posts) { post.IsLikedByCurrentUser = IsLiked(post.PostId, currentUserId.Value); post.LikeCount = GetLikeCount(post.PostId); post.Likes = GetLikesForPost(post.PostId); } con.Close(); } } return posts; } public List GetLikesForPost(int postId) { var likes = new List(); using (SqlConnection con = new SqlConnection(connectionString)) { string query = @" SELECT l.like_id, l.post_id, l.user_id, u.username, u.profile_picture FROM Likes l JOIN Users u ON l.user_id = u.user_id WHERE l.post_id = @PostId"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@PostId", postId); con.Open(); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { likes.Add(new Like { LikeId = Convert.ToInt32(reader["like_id"]), PostId = Convert.ToInt32(reader["post_id"]), UserId = Convert.ToInt32(reader["user_id"]), User = new User { Username = reader["username"].ToString(), ProfilePicture = reader["profile_picture"].ToString() } }); } } return likes; } // ================== DELETE POSTS ================== [HttpPost] public ActionResult DeletePost(int postId) { if (Session["UserId"] == null) { return RedirectToAction("Login"); // or show an error } int loggedInUserId = Convert.ToInt32(Session["UserId"]); using (SqlConnection con = new SqlConnection(connectionString)) { string query = "DELETE FROM Posts WHERE post_id = @PostId AND user_id = @UserId"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@PostId", postId); cmd.Parameters.AddWithValue("@UserId", loggedInUserId); con.Open(); int rowsAffected = cmd.ExecuteNonQuery(); if (rowsAffected > 0) { return Json(new { success = true, message = "Post deleted successfully!" }, JsonRequestBehavior.AllowGet); } else { return Content("⚠️ Failed: Either post not found or not your post."); } } } // ================== EDIT POSTS ================== [HttpPost] public JsonResult EditPost(int postId, string caption) { try { using (SqlConnection con = new SqlConnection(connectionString)) { string query = "UPDATE Posts SET caption = @Caption WHERE post_id = @PostId"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@PostId", postId); cmd.Parameters.AddWithValue("@Caption", caption); con.Open(); cmd.ExecuteNonQuery(); return Json(new { success = true, message = "Post updated successfully." }); } } catch (Exception ex) { return Json(new { success = false, message = "Error: " + ex.Message }); } } // ================== REPORT POSTS ================== [HttpPost] public JsonResult ReportPost(int postId, string reason) { try { using (SqlConnection con = new SqlConnection(connectionString)) { string query = "INSERT INTO Reports (post_id, reason, reported_at) VALUES (@postId, @reason, GETDATE())"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@postId", postId); cmd.Parameters.AddWithValue("@reason", reason); con.Open(); cmd.ExecuteNonQuery(); } return Json(new { success = true, message = "Post reported successfully!" }); } catch (Exception ex) { return Json(new { success = false, message = "Error: " + ex.Message }); } } // ================== HIDE POSTS ================== [HttpPost] public JsonResult HidePost(int postId) { try { using (SqlConnection con = new SqlConnection(connectionString)) { string query = "UPDATE Posts SET isAvailable = 0 WHERE post_id = @PostId"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@PostId", postId); con.Open(); int rowsAffected = cmd.ExecuteNonQuery(); // Add this con.Close(); if (rowsAffected > 0) { return Json(new { success = true, message = "Post hidden from your feed!" }); } else { return Json(new { success = false, message = "No rows updated. Wrong post ID?" }); } } } catch (Exception ex) { return Json(new { success = false, message = "Error: " + ex.Message }); } } // ================== UNHIDE POSTS ================== [HttpPost] public JsonResult UnhidePost(int postId) { try { using (SqlConnection con = new SqlConnection(connectionString)) { string query = "UPDATE Posts SET isAvailable = 1 WHERE post_id = @PostId"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@PostId", postId); con.Open(); cmd.ExecuteNonQuery(); } return Json(new { success = true }); } catch (Exception ex) { return Json(new { success = false, message = "Error: " + ex.Message }); } } // ================== LIKE / UNLIKE SYSTEM ================== [HttpPost] public JsonResult ToggleLike(int postId) { int userId = (int)Session["UserId"]; bool liked = false; using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); // Check if already liked string checkQuery = "SELECT COUNT(*) FROM Likes WHERE user_id = @uid AND post_id = @pid"; using (SqlCommand checkCmd = new SqlCommand(checkQuery, con)) { checkCmd.Parameters.AddWithValue("@uid", userId); checkCmd.Parameters.AddWithValue("@pid", postId); int count = (int)checkCmd.ExecuteScalar(); if (count > 0) { // Unlike string deleteQuery = "DELETE FROM Likes WHERE user_id = @uid AND post_id = @pid"; using (SqlCommand delCmd = new SqlCommand(deleteQuery, con)) { delCmd.Parameters.AddWithValue("@uid", userId); delCmd.Parameters.AddWithValue("@pid", postId); delCmd.ExecuteNonQuery(); } } else { // Like string insertQuery = "INSERT INTO Likes (user_id, post_id, liked_at) VALUES (@uid, @pid, GETDATE())"; using (SqlCommand insCmd = new SqlCommand(insertQuery, con)) { insCmd.Parameters.AddWithValue("@uid", userId); insCmd.Parameters.AddWithValue("@pid", postId); insCmd.ExecuteNonQuery(); } liked = true; } } // Send notification if it's a new like if (liked) { // Get the post owner's user_id string getPostOwner = "SELECT user_id FROM Posts WHERE post_id = @pid"; using (SqlCommand cmd = new SqlCommand(getPostOwner, con)) { cmd.Parameters.AddWithValue("@pid", postId); object result = cmd.ExecuteScalar(); if (result != null) { int receiverId = Convert.ToInt32(result); // Don’t notify yourself if (receiverId != userId) { string message = "liked your post."; DatabaseHelper.AddNotification(userId, receiverId, "like", message); } } } } con.Close(); } return Json(new { success = true }); } // Get likers for a post [HttpGet] public JsonResult GetLikers(int postId) { List likers = new List(); string topLiker = "someone"; int count = 0; using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); string query = @" SELECT u.username, u.profile_picture FROM Likes l JOIN users u ON l.user_id = u.user_id WHERE l.post_id = @pid ORDER BY l.liked_at DESC"; using (SqlCommand cmd = new SqlCommand(query, con)) { cmd.Parameters.AddWithValue("@pid", postId); using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { string username = reader["username"].ToString(); string pic = reader["profile_picture"].ToString(); pic = string.IsNullOrEmpty(pic) ? "/Content/images/default.jpg" : pic; likers.Add(new { username = username, profilePicture = Url.Content(pic) }); if (topLiker == "someone") topLiker = username; count++; } } } con.Close(); } return Json(new { likers, topLiker, likeCount = count }, JsonRequestBehavior.AllowGet); } private bool HasUserLikedPost(int userId, int postId) { using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM Likes WHERE user_id=@uid AND post_id=@pid", con); cmd.Parameters.AddWithValue("@uid", userId); cmd.Parameters.AddWithValue("@pid", postId); int count = (int)cmd.ExecuteScalar(); return count > 0; } } private int GetLikeCount(int postId) { int count = 0; using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM Likes WHERE post_id = @postId", con); cmd.Parameters.AddWithValue("@postId", postId); count = (int)cmd.ExecuteScalar(); } return count; } private string GetTopLiker(int postId) { string username = "someone"; using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); SqlCommand cmd = new SqlCommand(@" SELECT TOP 1 u.username FROM Likes l JOIN users u ON l.user_id = u.user_id WHERE l.post_id = @postId ORDER BY l.liked_at DESC", con); cmd.Parameters.AddWithValue("@postId", postId); var result = cmd.ExecuteScalar(); if (result != null) username = result.ToString(); } return username; } private bool IsLiked(int postId, int userId) { using (SqlConnection con = new SqlConnection(connectionString)) { string query = "SELECT COUNT(*) FROM Likes WHERE post_id = @postId AND user_id = @userId"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@postId", postId); cmd.Parameters.AddWithValue("@userId", userId); con.Open(); int count = (int)cmd.ExecuteScalar(); return count > 0; } } // ================== COMMENTS ================== public JsonResult GetComments(int postId) { List comments = new List(); using (SqlConnection con = new SqlConnection(connectionString)) { string query = @"SELECT c.comment_text, u.username FROM Comments c INNER JOIN Users u ON c.user_id = u.user_id WHERE c.post_id = @PostId ORDER BY c.created_at DESC"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@PostId", postId); con.Open(); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { comments.Add(new { Username = reader["username"].ToString(), Text = reader["comment_text"].ToString() }); } con.Close(); } return Json(comments, JsonRequestBehavior.AllowGet); } // Post comment [HttpPost] public JsonResult PostComment(int postId, string text) { int userId = Convert.ToInt32(Session["UserId"]); using (SqlConnection con = new SqlConnection(connectionString)) { string insertQuery = @"INSERT INTO Comments (post_id, user_id, comment_text, created_at) VALUES (@PostId, @UserId, @Text, GETDATE())"; SqlCommand cmd = new SqlCommand(insertQuery, con); cmd.Parameters.AddWithValue("@PostId", postId); cmd.Parameters.AddWithValue("@UserId", userId); cmd.Parameters.AddWithValue("@Text", text); con.Open(); cmd.ExecuteNonQuery(); // Send notification to post owner string getPostOwner = "SELECT user_id FROM Posts WHERE post_id = @pid"; using (SqlCommand ownerCmd = new SqlCommand(getPostOwner, con)) { ownerCmd.Parameters.AddWithValue("@pid", postId); int receiverId = (int)ownerCmd.ExecuteScalar(); if (receiverId != userId) { string message = $"commented: \"{text}\""; DatabaseHelper.AddNotification(userId, receiverId, "comment", message); } } con.Close(); } return Json(new { success = true }); } private User GetCurrentUser() { string currentUsername = Session["Username"]?.ToString(); string fullName = Session["FullName"]?.ToString(); int userId = (int)(Session["UserId"] ?? 0); if (string.IsNullOrEmpty(currentUsername)) return null; using (SqlConnection con = new SqlConnection(connectionString)) { string query = "SELECT username, profile_picture FROM users WHERE username = @username"; using (SqlCommand cmd = new SqlCommand(query, con)) { cmd.Parameters.AddWithValue("@username", currentUsername); con.Open(); using (SqlDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) { string profilePicture = reader["profile_picture"]?.ToString(); profilePicture = string.IsNullOrEmpty(profilePicture) ? "~/Content/images/default.jpg" : profilePicture; return new User { UserId = userId, FullName = fullName, Username = currentUsername, ProfilePicture = profilePicture }; } } } } return null; } public ActionResult GetNewMessageCount() { int currentUserId = Convert.ToInt32(Session["UserId"]); int newMessageCount = 0; using (SqlConnection con = new SqlConnection(connectionString)) { string query = "SELECT COUNT(*) FROM Messages WHERE receiver_id = @userId AND is_read = 0"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@userId", currentUserId); con.Open(); newMessageCount = (int)cmd.ExecuteScalar(); } return Json(new { count = newMessageCount }, JsonRequestBehavior.AllowGet); } public static void AddNotification(int senderId, int receiverId, string type, string message) { using (SqlConnection con = new SqlConnection(connectionString)) { string query = @"INSERT INTO Notifications (sender_user_id, receiver_user_id, type, message, is_read, created_at) VALUES (@sender, @receiver, @type, @message, 0, GETDATE())"; SqlCommand cmd = new SqlCommand(query, con); cmd.Parameters.AddWithValue("@sender", senderId); cmd.Parameters.AddWithValue("@receiver", receiverId); cmd.Parameters.AddWithValue("@type", type); cmd.Parameters.AddWithValue("@message", message); con.Open(); cmd.ExecuteNonQuery(); } } } }