package api;

import java.io.File;

import javax.annotation.PostConstruct;

import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PostMapping;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import database.Database1;
import tracker.Tracker;

import entity.Seed;
import entity.User;
import entity.Post;
import entity.PostReply;

import java.util.UUID;

@RestController
public class ApiController implements ApiInterface {

    private static Database1 db1;
    private static Tracker tracker;
    private static ObjectMapper mapper;
    private static HttpHeaders headers;
    private static HttpHeaders errorHeaders;

    @PostConstruct
    public void init() {
        db1 = new Database1();
        tracker = new Tracker();
        mapper = new ObjectMapper();
        mapper.configure(com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        headers = new HttpHeaders();
        headers.add("Access-Control-Allow-Origin", "*");
        headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
        errorHeaders = new HttpHeaders();
        errorHeaders.add("Access-Control-Allow-Origin", "*");
        errorHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        errorHeaders.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
    }

    @Override
    public ResponseEntity<Integer> saveTorrent(
        @RequestParam("userid") String userid,
        @RequestParam("title") String title,
        @RequestParam("tag") String tag,
        @RequestParam("file") MultipartFile file
    ) {
        try {
            Seed seed = new Seed();
            seed.seedid = UUID.randomUUID().toString(); // 生成唯一的种子ID
            seed.seeduserid = userid;
            seed.title = title;
            seed.seedsize = "1GB";
            seed.seedtag = tag;
            seed.url = "http://example.com/torrent"; // 示例URL
            System.out.println("seed is null? " + (seed == null));
            int ret = db1.RegisterSeed(seed);
            if (ret != 0) {
                // 如果注册种子失败，返回错误状态
                return new ResponseEntity<>(ret, headers, HttpStatus.INTERNAL_SERVER_ERROR);
            }
            File tempFile = File.createTempFile(seed.seedid, file.getOriginalFilename());
            file.transferTo(tempFile);
            tracker.SaveTorrent(seed.seedid, tempFile);
            return new ResponseEntity<>(0, headers, HttpStatus.OK); // 返回 0 表示成功
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(1, errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 1 表示失败
        }
    }

    @Override
    @CrossOrigin(origins = "*", allowedHeaders = "*") // 允许所有来源和头部
    public ResponseEntity<Resource> getTorrent(
        @RequestParam("torrentId") String seedid,
        @RequestParam("userId") String userid
    ) {
        File file = tracker.GetTTorent(seedid, userid);
        if (file != null) {
            FileSystemResource resource = new FileSystemResource(file);
            return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"")
                .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION) // 关键：允许前端访问Content-Disposition
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(resource);
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    @Override
    public ResponseEntity<String> getSeedListByTag(
        @RequestParam("tag") String tag
    ) {
        try {
            Seed[] seeds = db1.GetSeedListByTag(tag);
            if (seeds == null || seeds.length == 0) {
                return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 404 表示未找到种子
            }
            String json = mapper.writeValueAsString(seeds);
            return new ResponseEntity<>(json, headers, HttpStatus.OK);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    public ResponseEntity<String> getUserProfile(
        @RequestParam("userid") String userid
    ) {
        try {
            User user = db1.GetInformation(userid);
            if (user == null) {
                return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
            }
            String json = mapper.writeValueAsString(user);
            return new ResponseEntity<>(json, headers, HttpStatus.OK);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    @CrossOrigin(origins = "*", allowedHeaders = "*")
    public ResponseEntity<Integer> changeProfile(
        @RequestBody String requestBody
    ) {
        try {
            // 解析 JSON 数据
            com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
            
            // 安全地获取 userid 字段
            com.fasterxml.jackson.databind.JsonNode useridNode = jsonNode.get("userid");
            if (useridNode == null) {
                return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
            }
            String userid = useridNode.asText();
            
            // 添加参数验证
            if (userid == null || userid.trim().isEmpty()) {
                return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
            }
            
            // 手动映射前端字段到 User 对象，处理类型转换
            User user = new User();
            user.userid = userid;
            
            // 安全地获取其他字段并进行类型转换
            if (jsonNode.has("username") && !jsonNode.get("username").isNull()) {
                user.username = jsonNode.get("username").asText();
            }
            if (jsonNode.has("school") && !jsonNode.get("school").isNull()) {
                user.school = jsonNode.get("school").asText();
            }
            if (jsonNode.has("gender") && !jsonNode.get("gender").isNull()) {
                user.sex = jsonNode.get("gender").asText();
            }
            if (jsonNode.has("avatar_url") && !jsonNode.get("avatar_url").isNull()) {
                user.pictureurl = jsonNode.get("avatar_url").asText();
            }
            
            // 处理 account_status 的类型转换（字符串/数字 -> 布尔值）
            if (jsonNode.has("account_status") && !jsonNode.get("account_status").isNull()) {
                com.fasterxml.jackson.databind.JsonNode statusNode = jsonNode.get("account_status");
                if (statusNode.isTextual()) {
                    String statusStr = statusNode.asText();
                    user.accountstate = "1".equals(statusStr) || "封禁".equals(statusStr);
                } else if (statusNode.isNumber()) {
                    user.accountstate = statusNode.asInt() == 1;
                } else if (statusNode.isBoolean()) {
                    user.accountstate = statusNode.asBoolean();
                }
            }
            
            // 处理 invite_left 的类型转换（字符串 -> 整数）
            if (jsonNode.has("invite_left") && !jsonNode.get("invite_left").isNull()) {
                com.fasterxml.jackson.databind.JsonNode inviteNode = jsonNode.get("invite_left");
                if (inviteNode.isTextual()) {
                    try {
                        user.invitetimes = Integer.parseInt(inviteNode.asText());
                    } catch (NumberFormatException e) {
                        user.invitetimes = 0; // 默认值
                    }
                } else if (inviteNode.isNumber()) {
                    user.invitetimes = inviteNode.asInt();
                }
            }
            
            int ret = db1.UpdateInformation(user);
            if (ret == 0) {
                return new ResponseEntity<>(0, HttpStatus.OK); // 返回 0 表示成功
            } else {
                return new ResponseEntity<>(ret, HttpStatus.INTERNAL_SERVER_ERROR); // 返回其他状态表示失败
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 1 表示处理失败
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    public ResponseEntity<String> getUserSeeds(
        @RequestParam("userid") String userid
    ) {
        try {
            Seed[] seeds = db1.GetSeedListByUser(userid);
            if (seeds == null || seeds.length == 0) {
                return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 404 表示未找到种子
            }
            String json = mapper.writeValueAsString(seeds);
            return new ResponseEntity<>(json, headers, HttpStatus.OK);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    @CrossOrigin(origins = "*", allowedHeaders = "*")
    public ResponseEntity<Integer> deleteSeed(
        @RequestBody String requestBody
    ) {
        try {
            // 解析 JSON 数据
            com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
            com.fasterxml.jackson.databind.JsonNode seedidNode = jsonNode.get("seedid");
            if (seedidNode == null) {
                return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
            }
            String seedid = seedidNode.asText();
            
            // 添加参数验证
            if (seedid == null || seedid.trim().isEmpty()) {
                return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
            }
            
            int ret = db1.DeleteSeed(seedid);
            if (ret == 0) {
                return new ResponseEntity<>(0, HttpStatus.OK);
            } else {
                return new ResponseEntity<>(ret, HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    public ResponseEntity<String> getUserStat(
        @RequestParam("userid") String userid
    ) {
        try {
            User user = db1.GetInformation(userid);
            if (user == null) {
                return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
            }
            String json = mapper.writeValueAsString(user);
            return new ResponseEntity<>(json, headers, HttpStatus.OK);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return new ResponseEntity<>("", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    public ResponseEntity<String> getTorrentDetail(
        @RequestParam("id") String seedid
    ) {
        try {
            Seed seed = db1.GetSeedInformation(seedid);
            if (seed != null) {
                String json = mapper.writeValueAsString(seed);
                HttpHeaders headers = new HttpHeaders();
                headers.add("Access-Control-Allow-Origin", "*");
                headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
                return new ResponseEntity<>(json, headers, HttpStatus.OK);
            } else {
                return ResponseEntity.notFound().build(); // 返回 404 表示种子未找到
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            HttpHeaders errorHeaders = new HttpHeaders();
            errorHeaders.add("Access-Control-Allow-Origin", "*");
            errorHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            errorHeaders.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
            return new ResponseEntity<>("{}", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    @CrossOrigin(origins = "*", allowedHeaders = "*")
    public ResponseEntity<String> loginUser(
        @RequestBody String requestBody
    ) {
        try {
            // 解析前端发送的JSON数据 {email: xxx, password: xxx}
            com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
            
            // 获取email和password字段
            com.fasterxml.jackson.databind.JsonNode emailNode = jsonNode.get("email");
            com.fasterxml.jackson.databind.JsonNode passwordNode = jsonNode.get("password");

            if (emailNode == null || passwordNode == null) {
                com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
                errorJson.put("message", "缺少必要参数");
                String jsonError = mapper.writeValueAsString(errorJson);
                return new ResponseEntity<>(jsonError, HttpStatus.BAD_REQUEST);
            }
            
            String email = emailNode.asText();
            String password = passwordNode.asText();

            // 参数验证
            if (email == null || email.trim().isEmpty() || 
                password == null || password.trim().isEmpty()) {
                com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
                errorJson.put("message", "邮箱和密码不能为空");
                String jsonError = mapper.writeValueAsString(errorJson);
                return new ResponseEntity<>(jsonError, HttpStatus.BAD_REQUEST);
            }
            
            // 创建User对象进行登录验证
            User user = new User();
            user.email = email.trim();
            user.password = password;
            
            String userid = db1.LoginUser(user);
            if (userid != null) {
                com.fasterxml.jackson.databind.node.ObjectNode responseJson = mapper.createObjectNode();
                responseJson.put("userId", userid);
                responseJson.put("userid", userid);
                responseJson.put("message", "登录成功");
                String jsonResponse = mapper.writeValueAsString(responseJson);
                return new ResponseEntity<>(jsonResponse, HttpStatus.OK);
            } else {
                // 返回JSON格式的错误信息
                com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
                errorJson.put("message", "登录失败，请检查账号密码");
                String jsonError = mapper.writeValueAsString(errorJson);
                return new ResponseEntity<>(jsonError, HttpStatus.UNAUTHORIZED);
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
            try {
                errorJson.put("message", "服务器内部错误");
                String jsonError = mapper.writeValueAsString(errorJson);
                return new ResponseEntity<>(jsonError, HttpStatus.INTERNAL_SERVER_ERROR);
            } catch (JsonProcessingException ex) {
                return new ResponseEntity<>("{\"message\":\"服务器内部错误\"}", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            com.fasterxml.jackson.databind.node.ObjectNode errorJson = mapper.createObjectNode();
            try {
                errorJson.put("message", "服务器内部错误");
                String jsonError = mapper.writeValueAsString(errorJson);
                return new ResponseEntity<>(jsonError, HttpStatus.INTERNAL_SERVER_ERROR);
            } catch (JsonProcessingException ex) {
                return new ResponseEntity<>("{\"message\":\"服务器内部错误\"}", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
    }

    @Override
    @CrossOrigin(origins = "*", allowedHeaders = "*")
    public ResponseEntity<Integer> registerUser(
        @RequestBody String requestBody
    ) {
        try {
            System.out.println("Register request body: " + requestBody);
            // 解析 JSON 数据
            com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
            
            // 安全地获取字段
            com.fasterxml.jackson.databind.JsonNode usernameNode = jsonNode.get("username");
            com.fasterxml.jackson.databind.JsonNode passwordNode = jsonNode.get("password");
            com.fasterxml.jackson.databind.JsonNode inviteEmailNode = jsonNode.get("invite_email");
            
            if (usernameNode == null || passwordNode == null || inviteEmailNode == null) {
                return new ResponseEntity<>(2, HttpStatus.BAD_REQUEST); // 参数不完整
            }
            
            String username = usernameNode.asText();
            String password = passwordNode.asText();
            String inviteEmail = inviteEmailNode.asText();
            
            // 参数验证
            if (username == null || username.trim().isEmpty() || 
                password == null || password.trim().isEmpty() ||
                inviteEmail == null || inviteEmail.trim().isEmpty()) {
                return new ResponseEntity<>(2, HttpStatus.BAD_REQUEST);
            }
            
            // 创建 User 对象
            User user = new User();
            user.userid = java.util.UUID.randomUUID().toString(); // 生成唯一用户ID
            user.username = username.trim();
            user.password = password;
            user.email = inviteEmail.trim(); // 使用邀请邮箱作为用户邮箱
            
            // 设置默认值
            user.sex = "m"; // 默认性别
            user.school = ""; // 默认学校
            user.pictureurl = ""; // 默认头像URL
            user.profile = ""; // 默认个人简介
            user.accountstate = false; // 默认账号状态为正常
            user.invitetimes = 5; // 默认邀请次数
            
            // 设置时间字段
            user.lastDetectedTime = new java.util.Date();
            user.fakeLastDetectedTime = new java.util.Date();
            
            // 调用数据库注册方法
            int ret = db1.RegisterUser(user);
            System.out.println("Register result: " + ret);
            
            // // 如果注册成功，还需要创建对应的 UserPT 记录
            // if (ret == 0) {
            //     try {
            //         entity.UserPT userPT = new entity.UserPT();
            //         userPT.userid = user.userid;
            //         userPT.magic = 100; // 初始魔力值
            //         userPT.upload = 0L; // 初始上传量
            //         userPT.download = 0L; // 初始下载量
            //         userPT.share = 0.0; // 初始分享率
            //         userPT.farmurl = ""; // 默认做种路径
            //         userPT.viptime = 0; // 初始VIP次数
            //         userPT.user = user; // 设置关联
                    
            //         int ptRet = db1.RegisterUserPT(userPT);
            //         if (ptRet != 0) {
            //             // 如果 UserPT 创建失败，记录日志但不影响主要注册流程
            //             System.err.println("Warning: Failed to create UserPT for user " + user.userid);
            //         }
            //     } catch (Exception e) {
            //         System.err.println("Warning: Exception creating UserPT: " + e.getMessage());
            //     }
            // }
            
            if (ret == 0) {
                return new ResponseEntity<>(0, HttpStatus.OK); // 返回 0 表示注册成功
            } else if (ret == 1) {
                return new ResponseEntity<>(1, HttpStatus.CONFLICT); // 返回 1 表示邮箱重复
            } else {
                return new ResponseEntity<>(ret, HttpStatus.BAD_REQUEST); // 返回 2 表示未被邀请或其他错误
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return new ResponseEntity<>(2, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 2 表示处理失败
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(2, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    @CrossOrigin(origins = "*", allowedHeaders = "*")
    public ResponseEntity<String> getForum() {
        try {
            Post[] posts = db1.GetPostList();
            if (posts == null || posts.length == 0) {
                return new ResponseEntity<>("[]", HttpStatus.OK); // 返回空数组表示没有帖子
            }
            String json = mapper.writeValueAsString(posts);
            return new ResponseEntity<>(json, HttpStatus.OK);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return new ResponseEntity<>("[]", HttpStatus.INTERNAL_SERVER_ERROR);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>("[]", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    @CrossOrigin(origins = "*", allowedHeaders = "*")
    public ResponseEntity<String> getPostById(
        @RequestParam("postid") String postid
    ) {
        try {
            Post post = db1.GetPost(postid);
            PostReply[] replies = db1.GetPostReplyList(postid);
            if (post == null) {
                return new ResponseEntity<>("", HttpStatus.NOT_FOUND); // 返回 404 表示帖子未找到
            }
            
            // 创建合并的 JSON 对象
            com.fasterxml.jackson.databind.node.ObjectNode resultJson = mapper.createObjectNode();
            
            // 添加 post 的所有字段
            resultJson.put("postid", post.postid);
            resultJson.put("posttitle", post.posttitle);
            resultJson.put("postcontent", post.postcontent);
            resultJson.put("postuserid", post.postuserid);
            resultJson.put("replytime", post.replytime);
            resultJson.put("readtime", post.readtime);
            
            if (post.posttime != null) {
                resultJson.put("posttime", post.posttime.getTime());
            }
            
            // 添加作者信息
            if (post.author != null) {
                com.fasterxml.jackson.databind.node.ObjectNode authorJson = mapper.createObjectNode();
                authorJson.put("userid", post.author.userid);
                authorJson.put("username", post.author.username);
                authorJson.put("email", post.author.email);
                authorJson.put("sex", post.author.sex);
                authorJson.put("school", post.author.school);
                authorJson.put("pictureurl", post.author.pictureurl);
                authorJson.put("profile", post.author.profile);
                authorJson.put("accountstate", post.author.accountstate);
                authorJson.put("invitetimes", post.author.invitetimes);
                if (post.author.lastDetectedTime != null) {
                    authorJson.put("lastDetectedTime", post.author.lastDetectedTime.getTime());
                }
                if (post.author.fakeLastDetectedTime != null) {
                    authorJson.put("fakeLastDetectedTime", post.author.fakeLastDetectedTime.getTime());
                }
                resultJson.set("author", authorJson);
            }
            
            // 添加 replies 数组
            com.fasterxml.jackson.databind.node.ArrayNode repliesArray = mapper.createArrayNode();
            if (replies != null) {
                System.out.println("Replies count: " + replies.length);
                for (PostReply reply : replies) {
                    com.fasterxml.jackson.databind.node.ObjectNode replyJson = mapper.createObjectNode();
                    replyJson.put("replyid", reply.replyid);
                    replyJson.put("postid", reply.postid);
                    replyJson.put("authorid", reply.authorid);
                    replyJson.put("content", reply.content);
                    if (reply.createdAt != null) {
                        replyJson.put("createdAt", reply.createdAt.getTime());
                    }
                    
                    // 添加回复作者信息
                    if (reply.author != null) {
                        com.fasterxml.jackson.databind.node.ObjectNode replyAuthorJson = mapper.createObjectNode();
                        replyAuthorJson.put("userid", reply.author.userid);
                        replyAuthorJson.put("username", reply.author.username);
                        replyAuthorJson.put("email", reply.author.email);
                        replyAuthorJson.put("sex", reply.author.sex);
                        replyAuthorJson.put("school", reply.author.school);
                        replyAuthorJson.put("pictureurl", reply.author.pictureurl);
                        replyAuthorJson.put("profile", reply.author.profile);
                        replyAuthorJson.put("accountstate", reply.author.accountstate);
                        replyAuthorJson.put("invitetimes", reply.author.invitetimes);
                        if (reply.author.lastDetectedTime != null) {
                            replyAuthorJson.put("lastDetectedTime", reply.author.lastDetectedTime.getTime());
                        }
                        if (reply.author.fakeLastDetectedTime != null) {
                            replyAuthorJson.put("fakeLastDetectedTime", reply.author.fakeLastDetectedTime.getTime());
                        }
                        replyJson.set("author", replyAuthorJson);
                    }
                    
                    repliesArray.add(replyJson);
                }
            }
            resultJson.set("replies", repliesArray);
            
            String json = mapper.writeValueAsString(resultJson);
            return new ResponseEntity<>(json, HttpStatus.OK);
        } catch (JsonProcessingException e) {
            // e.printStackTrace();
            return new ResponseEntity<>("", HttpStatus.INTERNAL_SERVER_ERROR);
        } catch (Exception e) {
            // e.printStackTrace();
            return new ResponseEntity<>("", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    @CrossOrigin(origins = "*", allowedHeaders = "*")
    public ResponseEntity<Integer> addPostReply(
        @RequestBody String requestBody
    ) {
        try {
            System.out.println("Add reply request body: " + requestBody);
            // 解析 JSON 数据
            com.fasterxml.jackson.databind.JsonNode jsonNode = mapper.readTree(requestBody);
            com.fasterxml.jackson.databind.JsonNode postidNode = jsonNode.get("postid");
            com.fasterxml.jackson.databind.JsonNode authoridNode = jsonNode.get("replyuserid");
            com.fasterxml.jackson.databind.JsonNode contentNode = jsonNode.get("replycontent");

            if (postidNode == null || authoridNode == null || contentNode == null) {
                return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST); // 参数不完整
            }

            String postid = postidNode.asText();
            String authorid = authoridNode.asText();
            String content = contentNode.asText();

            System.out.println("Post ID: " + postid);
            System.out.println("Author ID: " + authorid);
            System.out.println("Content: " + content);

            // 参数验证
            if (postid == null || postid.trim().isEmpty() || 
                authorid == null || authorid.trim().isEmpty() || 
                content == null || content.trim().isEmpty()) {
                return new ResponseEntity<>(1, HttpStatus.BAD_REQUEST);
            }
            
            int ret = db1.AddComment(postid, authorid, content);
            System.out.println("Add comment result: " + ret);
            if (ret == 0) {
                return new ResponseEntity<>(0, HttpStatus.OK); // 返回 0 表示成功
            } else {
                return new ResponseEntity<>(ret, HttpStatus.INTERNAL_SERVER_ERROR); // 返回其他状态表示失败
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 1 表示处理失败
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(1, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    public ResponseEntity<String> searchSeeds(
        @RequestParam("tag") String tag,
        @RequestParam("keyword") String query
    ) {
        return null;
    //     try {
    //         Seed[] seeds = db1.SearchSeeds(query);
    //         if (seeds == null || seeds.length == 0) {
    //             return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR); // 返回 404 表示未找到种子
    //         }
    //         String json = mapper.writeValueAsString(seeds);
    //         return new ResponseEntity<>(json, headers, HttpStatus.OK);
    //     } catch (JsonProcessingException e) {
    //         e.printStackTrace();
    //         return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
    //     } catch (Exception e) {
    //         e.printStackTrace();
    //         return new ResponseEntity<>("[]", errorHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
    //     }
    }
}