package com.ar.arsketch.fragment;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.GridLayoutManager;

import com.ar.arsketch.adapter.ImageAdapter;
import com.ar.arsketch.databinding.FragmentImportBinding;
import com.ar.arsketch.room.AppDatabase;
import com.ar.arsketch.room.ImageEntry;
import com.ar.arsketch.room.ImageEntryDao;
import com.ar.arsketch.utils.ItemDecoration;

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


public class ImportFragment extends Fragment {

    private FragmentImportBinding binding;

    private static final int PICK_IMAGE_REQUEST_CODE = 202;

    private ImageAdapter adapter;
    private final List<String> imagePaths = new ArrayList<>();
    private ImageEntryDao imageEntryDao;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        binding = FragmentImportBinding.inflate(inflater, container, false);

        initData();
        initEvent();

        return binding.getRoot();
    }

    private void initData() {

        AppDatabase appDatabase = AppDatabase.getInstance(requireContext());
        imageEntryDao = appDatabase.imageEntryDao();

        binding.recyclerview.setLayoutManager(new GridLayoutManager(getContext(), 2));
        ItemDecoration itemDecoration = new ItemDecoration(16, 19, 10);
        binding.recyclerview.addItemDecoration(itemDecoration);
        adapter = new ImageAdapter(requireContext(), new ArrayList<>(), requireActivity());
        binding.recyclerview.setAdapter(adapter);

    }

    private void initEvent() {

        binding.add.setOnClickListener(v -> openImagePicker());
        loadImages();

    }

    private void loadImages() {
        AppDatabase.getInstance(requireContext())
                .imageEntryDao()
                .getAllImportImageLive()
                .observe(getViewLifecycleOwner(), new Observer<List<ImageEntry>>() {
                    @Override
                    public void onChanged(List<ImageEntry> imageEntries) {
                        if (imageEntries.isEmpty()) {
                            binding.backgroundImage.setVisibility(View.VISIBLE);
                            binding.backgroundText.setVisibility(View.VISIBLE);
                        } else {
                            binding.backgroundImage.setVisibility(View.GONE);
                            binding.backgroundText.setVisibility(View.GONE);
                        }
                        adapter.updateData(imageEntries);
                    }
                });
    }

    private void openImagePicker() {
        Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_IMAGE_REQUEST_CODE && resultCode == getActivity().RESULT_OK && data != null) {
            Uri selectedImageUri = data.getData();
            if (selectedImageUri != null) {
                try {
                    if (isImageSizeAcceptable(selectedImageUri)) {
                        saveImageToInternalStorage(selectedImageUri);
                    } else {
                        Toast.makeText(getContext(), "The image size is out of limit", Toast.LENGTH_SHORT).show();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(getContext(), "Could not get image size: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    private boolean isImageSizeAcceptable(Uri uri) throws IOException {
        InputStream inputStream = requireContext().getContentResolver().openInputStream(uri);
        if (inputStream == null) {
            return false;
        }

        long fileSize = inputStream.available();
        inputStream.close();
        long maxFileSize = 10 * 1024 * 1024;

        return fileSize <= maxFileSize;
    }

    private void saveImageToInternalStorage(Uri uri) {
        try {
            InputStream inputStream = requireContext().getContentResolver().openInputStream(uri);
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

            if (bitmap == null) {
                Toast.makeText(getContext(), "Unable to load image", Toast.LENGTH_SHORT).show();
                return;
            }

            File internalStorageDir = requireContext().getFilesDir();
            File imageFile = new File(internalStorageDir, System.currentTimeMillis() + ".jpg");
            FileOutputStream outputStream = new FileOutputStream(imageFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            outputStream.close();
            inputStream.close();

            String imagePath = imageFile.getAbsolutePath();

            new Thread(() -> {
                if (isImageAlreadyExists(imagePath)) {
                    requireActivity().runOnUiThread(() -> Toast.makeText(getContext(), "The image already exists", Toast.LENGTH_SHORT).show());
                    imageFile.delete();
                    return;
                }
                imagePaths.add(imagePath);

                imageEntryDao.insert(new ImageEntry(false, true, imagePath));

            }).start();

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "Failed to save picture: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    private boolean isImageAlreadyExists(String imagePath) {
        File newImageFile = new File(imagePath);

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

        List<ImageEntry> imageEntries = imageEntryDao.getAllImportImage();
        for (ImageEntry imageEntry : imageEntries) {
            File existingFile = new File(imageEntry.getImagePath());
            if (filesAreIdentical(existingFile, newImageFile)) {
                return true;
            }
        }

        return false;
    }

    private boolean filesAreIdentical(File file1, File file2) {
        return file1.length() == file2.length();
    }


}