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 entity.UserPT;

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) {
                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 {
            // 解析 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();

            // 参数验证
            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);
            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
    ) {
        try {
            Seed[] seeds = db1.SearchSeed(query);
            if (seeds == null || seeds.length == 0) {
                return new ResponseEntity<>("[]", errorHeaders, HttpStatus.NOT_FOUND); // 返回 404 表示未找到种子
            }
            
            // 过滤掉与前端要求tag不同的种子
            java.util.List<Seed> filteredSeeds = new java.util.ArrayList<>();
            for (Seed seed : seeds) {
                if (seed.seedtag != null && seed.seedtag.equals(tag)) {
                    filteredSeeds.add(seed);
                }
            }
            
            // 如果过滤后没有匹配的种子，返回空数组
            if (filteredSeeds.isEmpty()) {
                return new ResponseEntity<>("[]", errorHeaders, HttpStatus.NOT_FOUND);
            }
            
            Seed[] filteredSeedsArray = filteredSeeds.toArray(new Seed[0]);
            String json = mapper.writeValueAsString(filteredSeedsArray);
            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);
        }
    }

    @Override
    public ResponseEntity<String> searchPosts(
        @RequestParam("keyword") String query
    ) {
        try {
            Post[] posts = db1.SearchPost(query);
            if (posts == null || posts.length == 0) {
                return new ResponseEntity<>("[]", errorHeaders, HttpStatus.NOT_FOUND); // 返回 404 表示未找到帖子
            }
            String json = mapper.writeValueAsString(posts);
            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);
        }
    }

    @Override
    public ResponseEntity<String> getUserPT(
        @RequestParam("userid") String userid
    ) {
        try {
            UserPT userPT = db1.GetInformationPT(userid);
            if (userPT == null) {
                return new ResponseEntity<>("", errorHeaders, HttpStatus.NOT_FOUND); // 返回 404 表示未找到用户PT信息
            }
            String json = mapper.writeValueAsString(userPT);
            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);
        }
    }
}