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 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
    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);
        }
    }
}