use crate::core::shared::state::AppState; use crate::docs::storage::{get_current_user_id, load_document_from_drive, save_document}; use crate::docs::types::{ AddCommentRequest, DeleteCommentRequest, DocumentComment, ListCommentsResponse, ReplyCommentRequest, ResolveCommentRequest, }; use axum::{ extract::{Query, State}, http::StatusCode, Json, }; use chrono::Utc; use std::collections::HashMap; use std::sync::Arc; pub async fn handle_add_comment( State(state): State>, Json(req): Json, ) -> Result, (StatusCode, Json)> { let user_id = get_current_user_id(); let mut doc = match load_document_from_drive(&state, &user_id, &req.doc_id).await { Ok(Some(d)) => d, Ok(None) => { return Err(( StatusCode::NOT_FOUND, Json(serde_json::json!({ "error": "Document not found" })), )) } Err(e) => { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(serde_json::json!({ "error": e })), )) } }; let comment = DocumentComment { id: uuid::Uuid::new_v4().to_string(), author_id: user_id.clone(), author_name: "User".to_string(), content: req.content, position: req.position, length: req.length, created_at: Utc::now(), updated_at: Utc::now(), replies: vec![], resolved: false, }; let comments = doc.comments.get_or_insert_with(Vec::new); comments.push(comment.clone()); doc.updated_at = Utc::now(); if let Err(e) = save_document(&state, &user_id, &doc).await { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(serde_json::json!({ "error": e })), )); } Ok(Json(serde_json::json!({ "success": true, "comment": comment }))) } pub async fn handle_reply_comment( State(state): State>, Json(req): Json, ) -> Result, (StatusCode, Json)> { let user_id = get_current_user_id(); let mut doc = match load_document_from_drive(&state, &user_id, &req.doc_id).await { Ok(Some(d)) => d, Ok(None) => { return Err(( StatusCode::NOT_FOUND, Json(serde_json::json!({ "error": "Document not found" })), )) } Err(e) => { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(serde_json::json!({ "error": e })), )) } }; if let Some(comments) = &mut doc.comments { for comment in comments.iter_mut() { if comment.id == req.comment_id { let reply = crate::docs::types::CommentReply { id: uuid::Uuid::new_v4().to_string(), author_id: user_id.clone(), author_name: "User".to_string(), content: req.content.clone(), created_at: Utc::now(), }; comment.replies.push(reply); comment.updated_at = Utc::now(); break; } } } doc.updated_at = Utc::now(); if let Err(e) = save_document(&state, &user_id, &doc).await { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(serde_json::json!({ "error": e })), )); } Ok(Json(serde_json::json!({ "success": true }))) } pub async fn handle_resolve_comment( State(state): State>, Json(req): Json, ) -> Result, (StatusCode, Json)> { let user_id = get_current_user_id(); let mut doc = match load_document_from_drive(&state, &user_id, &req.doc_id).await { Ok(Some(d)) => d, Ok(None) => { return Err(( StatusCode::NOT_FOUND, Json(serde_json::json!({ "error": "Document not found" })), )) } Err(e) => { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(serde_json::json!({ "error": e })), )) } }; if let Some(comments) = &mut doc.comments { for comment in comments.iter_mut() { if comment.id == req.comment_id { comment.resolved = req.resolved; comment.updated_at = Utc::now(); break; } } } doc.updated_at = Utc::now(); if let Err(e) = save_document(&state, &user_id, &doc).await { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(serde_json::json!({ "error": e })), )); } Ok(Json(serde_json::json!({ "success": true }))) } pub async fn handle_delete_comment( State(state): State>, Json(req): Json, ) -> Result, (StatusCode, Json)> { let user_id = get_current_user_id(); let mut doc = match load_document_from_drive(&state, &user_id, &req.doc_id).await { Ok(Some(d)) => d, Ok(None) => { return Err(( StatusCode::NOT_FOUND, Json(serde_json::json!({ "error": "Document not found" })), )) } Err(e) => { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(serde_json::json!({ "error": e })), )) } }; if let Some(comments) = &mut doc.comments { comments.retain(|c| c.id != req.comment_id); } doc.updated_at = Utc::now(); if let Err(e) = save_document(&state, &user_id, &doc).await { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(serde_json::json!({ "error": e })), )); } Ok(Json(serde_json::json!({ "success": true }))) } pub async fn handle_list_comments( State(state): State>, Query(params): Query>, ) -> Result, (StatusCode, Json)> { let doc_id = params.get("doc_id").cloned().unwrap_or_default(); let user_id = get_current_user_id(); let doc = match load_document_from_drive(&state, &user_id, &doc_id).await { Ok(Some(d)) => d, Ok(None) => { return Err(( StatusCode::NOT_FOUND, Json(serde_json::json!({ "error": "Document not found" })), )) } Err(e) => { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(serde_json::json!({ "error": e })), )) } }; let comments = doc.comments.unwrap_or_default(); Ok(Json(ListCommentsResponse { comments })) }