package io;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.channels.FileChannel;
import java.util.Map;

public class ReadAndUpload {

    private static String token;
    private static String uploadId = "ZmFmNTNmOWEtMDBlYy00NThhLTlhNTMtMjRmZjg2OTYzOTg3LmVhNjJiZTg1LTdiYWYtNDMxYi04ODNhLTZkMDg0MGQwMWM5NngxNzQxNDk0Njk2NzY4Mjc3Mzk3";
    private static String identifier = "bbec8f8a1d848bb75d7cc98c05dcbb88";

    //read file from local
    public static void readFile() {
        String path = "/home/admin/Downloads/MemoryAnalyzer-1.16.1.20250109-linux.gtk.x86_64.zip";
        int chunkSize = 5 * 1024 * 1024;

        //read file as 5mb chunk
        try (FileInputStream fis = new FileInputStream(path);
             BufferedInputStream bis = new BufferedInputStream(fis);
             FileChannel fc = fis.getChannel()) {

            byte[] buffer = new byte[chunkSize];
            int bytesRead;

            int chunkNumber = 0;
            while((bytesRead = bis.read(buffer)) != -1) {
                chunkNumber++;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //upload file to server
    public static void uploadFile(byte[] content, int chunkNumber) {
        String url = getUploadUrl(chunkNumber);
    }

    public static String login() {
        try (HttpClient httpClient = HttpClient.newBuilder().build()) {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create("http://localhost:8080/api/account/v1/login"))
                    .POST(HttpRequest.BodyPublishers.ofString("{\"phone\": \"13112345678\", \"password\": \"1234\"}"))
                    .header("Content-Type", "application/json")
                    .build();
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            String payload =response.body();
            System.out.println(payload);
            Map<String,Object> map = parseData(payload);
            return (String) map.get("data");
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    
    public static String getUploadId() {
        try (HttpClient httpClient = HttpClient.newBuilder().build()) {
            FileChunkInitReq req = new FileChunkInitReq(
                    "MemoryAnalyzer-1.16.1.20250109-linux.gtk.x86_64.zip",
                    identifier,
                    95754511L,
                    19L

            );
            String payload = dataToJson(req);
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create("http://localhost:8080/api/file/v1/init_file_chunk_task"))
                    .header("token", token)
                    .header("Content-Type", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(payload))
                    .build();

            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            String resultBody =response.body();
            if (response.statusCode() != 200 || parseData(resultBody).get("data") == null) {
                return null;
            }

            System.out.println(resultBody);
            return parseData(resultBody).get("data").toString();
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private static String getUploadUrl(int number) {
        try (HttpClient httpClient = HttpClient.newBuilder().build()) {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(STR."http://localhost:8080/api/file/v1/get_file_chunk_upload_url/\{identifier}/\{number}"))
                    .header("token", token)
                    .GET()
                    .build();
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            String resultBody =response.body();
            if (response.statusCode() != 200 || parseData(resultBody).get("data") == null) {
                return null;
            }
            System.out.println(resultBody);
            return parseData(resultBody).get("data").toString();
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

    private static Map<String,Object> parseData(String json) {
        Gson gson = new Gson();
        Type type = new TypeToken<Map<String, Object>>() {}.getType();
        return gson.fromJson(json, type);
    }

    private static<T> String dataToJson(T data) {
        Gson gson = new Gson();
        return gson.toJson(data);
    }

    public static void main(String[] args) {
        token = login();
        String tmpId = getUploadId();
        uploadId = tmpId == null? uploadId: tmpId;
        //getUploadUrl(0);

    }
}
