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