package com.m2sdl.undercooked.services;

import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;

import com.squareup.picasso.OkHttp3Downloader;
import com.squareup.picasso.Picasso;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;

public class UndercookedService {
    private final String URL = "https://db.nath-roset.master-sdl.ovh/";
    private final String PASSWORD = "je-me-complique-la-vie";

    public UndercookedService() {}

    public void uploadImageToServer(File file, OnImageUploaded callback) {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor(
                message -> Log.d("HTTP", message)
        );
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(logging)
                .build();

        RequestBody fileBody = RequestBody.create(
                file,
                MediaType.parse("image/jpeg")
        );

        Request request = new Request.Builder()
                .url(URL + file.getName())
                .addHeader("PW", PASSWORD)
                .put(fileBody)
                .build();

        client.newCall(request).enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(@NonNull okhttp3.Call call, @NonNull java.io.IOException e) {
                callback.onError(e);
            }

            @Override
            public void onResponse(@NonNull okhttp3.Call call, @NonNull okhttp3.Response response) {
                if (!response.isSuccessful()) {
                    callback.onError(new Exception("HTTP " + response.code()));
                    return;
                }

                String imageUrl =
                        URL + file.getName();

                callback.onUploaded(imageUrl);
            }
        });
    }

    public interface OnImageUploaded {
        void onUploaded(String url);
        void onError(Exception e);
    }

    public void downloadFileFromServer(String remotePath, File destination, OnFileDownloaded callback) {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url(URL + remotePath)
                .addHeader("PW", PASSWORD)
                .build();

        client.newCall(request).enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(@NonNull okhttp3.Call call, @NonNull java.io.IOException e) {
                callback.onError(e);
            }

            @Override
            public void onResponse(@NonNull okhttp3.Call call, @NonNull okhttp3.Response response) {
                if (!response.isSuccessful()) {
                    callback.onError(new Exception("HTTP " + response.code()));
                    return;
                }

                try {
                    ResponseBody body = response.body();
                    if (body == null) {
                        callback.onError(new Exception("Empty body"));
                        return;
                    }

                    long totalBytes = body.contentLength();
                    long downloadedBytes = 0;

                    InputStream input = body.byteStream();
                    FileOutputStream output = new FileOutputStream(destination);

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

                    while ((bytesRead = input.read(buffer)) != -1) {

                        downloadedBytes += bytesRead;
                        output.write(buffer, 0, bytesRead);

                        if (totalBytes > 0) {
                            int percent = (int) ((downloadedBytes * 100) / totalBytes);
                            callback.onProgress(percent);
                        }
                    }

                    output.flush();
                    output.close();
                    input.close();

                    callback.onDownloaded();
                } catch (Exception e) {
                    callback.onError(e);
                }
            }
        });
    }

    public interface OnFileDownloaded {
        void onProgress(int percent);
        void onDownloaded();
        void onError(Exception e);
    }

    public Picasso getPicassoWithAuth(Context context) {
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() {
                    @NonNull
                    @Override
                    public Response intercept(@NonNull Chain chain) throws IOException {
                        Request original = chain.request();
                        Request requestWithHeader = original.newBuilder()
                                .header("PW", PASSWORD)
                                .build();
                        return chain.proceed(requestWithHeader);
                    }
                })
                .build();

        return new Picasso.Builder(context)
                .downloader(new OkHttp3Downloader(client))
                .build();
    }
}
