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 com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import database.Database1;
import entity.Seed;
import tracker.Tracker;


@RestController
public class ApiController implements ApiInterface {

    private static Database1 db1;
    private static Tracker tracker;
    private static ObjectMapper mapper;

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

    @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 = "exampleSeedId"; // 示例种子ID
            seed.seeduserid = userid; // 示例用户ID
            seed.title = title; // 示例标题
            seed.seedsize = "1GB"; // 示例种子大小
            seed.seedtag = tag; // 示例标签
            seed.url = "http://example.com/torrent"; // 示例URL

            int ret = db1.RegisterSeed(seed);
            // System.out.println("RegisterSeed ret: " + ret);
            // System.out.println(seed.seedid + " " + seed.seeduserid + " " + seed.title + " " + seed.seedsize + " " + seed.seedtag + " " + seed.url);

            // Convert MultipartFile to File
            File tempFile = File.createTempFile(seed.seedid, file.getOriginalFilename());
            file.transferTo(tempFile);

            tracker.SaveTorrent(seed.seedid, tempFile);

            // Optionally, delete the temp file after saving if not needed
            // tempFile.delete();

            // 创建带有 CORS 响应头的 ResponseEntity
            HttpHeaders headers = new HttpHeaders();
            headers.add("Access-Control-Allow-Origin", "*"); // 允许所有域名访问，可以根据需要调整为特定域名
            headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); // 允许的 HTTP 方法
            headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization"); // 允许的请求头

            return new ResponseEntity<>(0, headers, HttpStatus.OK); // 返回 0 表示成功
        } catch (Exception e) {
            e.printStackTrace();

            // 创建带有 CORS 响应头的错误 ResponseEntity
            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<>(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);
            String json = mapper.writeValueAsString(seeds);
            // System.out.println("getSeedListByTag: " + json);
            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);
        } 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
    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);
        }
    }
}