package com.axis.innovators.box.network;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Instant;

public class NetworkFileManagement {
    private static final String BASE_URL = NetworkUserManagement.BASE_URL;
    private static final int TIMESTAMP_THRESHOLD = 300;

    /**
     * 上传文件
     * @param user 上传用户
     * @param file 要上传的文件
     * @return 文件id
     * @throws IOException 上传失败抛出异常
     */
    public int uploadFile(Users user, File file) throws IOException {
        validateTimestamp(user);
        String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
        HttpURLConnection connection = (HttpURLConnection) new URL(BASE_URL + "/upload").openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Authorization", "Bearer " + user.getToken());
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        connection.setDoOutput(true);

        try (OutputStream output = connection.getOutputStream();
             PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8))) {

            // Timestamp part
            writer.append("--").append(boundary).append("\r\n");
            writer.append("Content-Disposition: form-data; name=\"timestamp\"\r\n\r\n");
            writer.append(String.valueOf(user.getTimestamp())).append("\r\n").flush();

            // File part
            writer.append("--").append(boundary).append("\r\n");
            writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"").append(file.getName()).append("\"\r\n");
            writer.append("Content-Type: application/octet-stream\r\n\r\n").flush();

            try (FileInputStream input = new FileInputStream(file)) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = input.read(buffer)) != -1) {
                    output.write(buffer, 0, bytesRead);
                }
                output.flush();
            }

            writer.append("\r\n--").append(boundary).append("--\r\n").flush();
        }

        String response = handleResponse(connection);
        return extractFileId(response);
    }


    /**
     * 从JSON响应中提取file_id字段
     */
    private int extractFileId(String jsonResponse) {
        String[] parts = jsonResponse.split("\"file_id\":");
        if (parts.length < 2) {
            throw new RuntimeException("Invalid response format: " + jsonResponse);
        }
        return Integer.parseInt(parts[1].replaceAll("[^0-9]", ""));
    }

    /**
     * 下载文件
     * @param user 下载用户
     * @param fileId 文件ID
     * @param savePath 保存路径
     * @return 文件
     * @throws IOException 下载失败抛出异常
     */
    public File downloadFile(Users user, int fileId, String savePath) throws IOException {
        validateTimestamp(user);
        String query = String.format("file_id=%d&timestamp=%d", fileId, user.getTimestamp());
        HttpURLConnection connection = (HttpURLConnection) new URL(BASE_URL + "/download?" + query).openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Authorization", "Bearer " + user.getToken());

        int status = connection.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            String fileName = "downloaded_file";
            try (InputStream input = connection.getInputStream();
                 FileOutputStream output = new FileOutputStream(savePath + File.separator + fileName)) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = input.read(buffer)) != -1) {
                    output.write(buffer, 0, bytesRead);
                }
            }
            return new File(savePath + File.separator + fileName);
        } else {
            handleErrorResponse(connection);
            return null;
        }
    }

    private void validateTimestamp(Users user) {
        long currentTimestamp = Instant.now().getEpochSecond();
        if (Math.abs(currentTimestamp - user.getTimestamp()) > TIMESTAMP_THRESHOLD) {
            throw new SecurityException("Timestamp validation failed");
        }
    }

    private String handleResponse(HttpURLConnection connection) throws IOException {
        int status = connection.getResponseCode();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(
                status >= 400 ? connection.getErrorStream() : connection.getInputStream()
        ))) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            if (status >= 400) {
                throw new RuntimeException("HTTP Error " + status + ": " + response);
            }
            return response.toString();
        }
    }

    private void handleErrorResponse(HttpURLConnection connection) throws IOException {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            throw new RuntimeException("HTTP Error " + connection.getResponseCode() + ": " + response);
        }
    }
}