package com.ardrawing.ardrawingspace.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.ardrawing.ardrawingspace.room.SpaceEntity;
import com.ardrawing.ardrawingspace.viewmodel.SpaceViewModel;

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

public class UploadUtil {
    private static final Handler mainHandler = new Handler(Looper.getMainLooper());

    private static final boolean IS_DEBUG = false;

    public static void saveImageByPath(Uri imageUri, List<String> imagePaths, SpaceViewModel viewModel, Context context) {
        if (isInvalidInput(imageUri, imagePaths, viewModel, context)) return;

        try (InputStream inputStream = context.getContentResolver().openInputStream(imageUri)) {
            Bitmap bitmap = decodeBitmapFromStream(inputStream);
            if (bitmap == null) {
                displayToast(context, "Unable to load image");
                return;
            }

            File imageFile = createImageFile(context, generateUniqueImageName());
            saveBitmapToFile(bitmap, imageFile);

            String savedImagePath = imageFile.getAbsolutePath();
            executeImageSavingAsync(savedImagePath, imagePaths, viewModel, context, imageFile);
        } catch (IOException e) {
            displayToast(context, "Failed to save picture");
        }
    }

    public static void deleteImageByPath(SpaceEntity spaceEntity, SpaceViewModel viewModel, Context context) {
        if (isInvalidEntity(spaceEntity, viewModel, context)) return;

        File imageFile = new File(spaceEntity.getImagePath());
        if (!imageFile.exists()) {
            displayToast(context, "Image does not exist");
            return;
        }

        if (imageFile.delete()) {
            viewModel.delete(spaceEntity);
            displayToast(context, "Image deleted successfully");
        } else {
            displayToast(context, "Failed to delete image");
        }
    }

    private static void executeImageSavingAsync(String savedImagePath, List<String> imagePaths, SpaceViewModel viewModel, Context context, File imageFile) {
        new Thread(() -> {
            if (checkImageDuplicate(savedImagePath, imagePaths, viewModel)) {
                imageFile.delete();
                displayToast(context, "The image already exists");
                return;
            }

            imagePaths.add(savedImagePath);
            viewModel.insert(new SpaceEntity(savedImagePath, true, false));
        }).start();
    }

    private static boolean checkImageDuplicate(String imagePath, List<String> imagePaths, SpaceViewModel viewModel) {
        File newImageFile = new File(imagePath);
        if (!newImageFile.exists()) return false;

        for (String path : imagePaths) {
            File existingFile = new File(path);
            if (compareFilesBySize(existingFile, newImageFile)) {
                return true;
            }
        }

        List<SpaceEntity> spaceEntityList = viewModel.getImport();
        for (SpaceEntity data : spaceEntityList) {
            File existingFile = new File(data.getImagePath());
            if (compareFilesBySize(existingFile, newImageFile)) {
                return true;
            }
        }
        return false;
    }

    private static boolean compareFilesBySize(File file1, File file2) {
        return file1.exists() && file2.exists() && file1.length() == file2.length();
    }

    private static Bitmap decodeBitmapFromStream(InputStream inputStream) {
        return BitmapFactory.decodeStream(inputStream);
    }

    private static File createImageFile(Context context, String fileName) {
        return new File(context.getFilesDir(), fileName + ".jpg");
    }

    private static void saveBitmapToFile(Bitmap bitmap, File file) throws IOException {
        try (FileOutputStream outputStream = new FileOutputStream(file)) {
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        }
    }

    private static void displayToast(Context context, String message) {
        if (isInvalidToastInput(context, message)) return;
        mainHandler.post(() -> Toast.makeText(context, message, Toast.LENGTH_SHORT).show());
    }

    private static boolean isInvalidToastInput(Context context, String message) {
        if (IS_DEBUG) {
            Log.d("UploadUtil", "Checking toast input");
        }
        return context == null || message == null;
    }

    private static boolean isInvalidInput(Uri imageUri, List<String> imagePaths, SpaceViewModel viewModel, Context context) {
        return imageUri == null || imagePaths == null || viewModel == null || context == null;
    }

    private static boolean isInvalidEntity(SpaceEntity spaceEntity, SpaceViewModel viewModel, Context context) {
        return spaceEntity == null || spaceEntity.getImagePath() == null || viewModel == null || context == null;
    }

    private static String generateUniqueImageName() {
        return String.valueOf(System.currentTimeMillis());
    }

    public static boolean isImageSizeValid(Uri imageUri, Context context) {
        if (isInvalidSizeCheck(imageUri, context)) return false;

        try (InputStream inputStream = context.getContentResolver().openInputStream(imageUri)) {
            if (inputStream == null) return false;
            long imageSize = inputStream.available();
            long maxSize = 10 * 1024 * 1024; // 10MB
            return imageSize <= maxSize;
        } catch (IOException e) {
            return false;
        }
    }

    private static boolean isInvalidSizeCheck(Uri imageUri, Context context) {
        return imageUri == null || context == null;
    }
}

