package com.wallpaper.perfectwallpaper.activity;

import static com.wallpaper.perfectwallpaper.utils.GallerySaver.REQUEST_CODE_WRITE_EXTERNAL_STORAGE;

import android.app.WallpaperManager;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.wallpaper.perfectwallpaper.R;
import com.wallpaper.perfectwallpaper.databinding.ActivityImageBinding;
import com.wallpaper.perfectwallpaper.room.ImageEntry;
import com.wallpaper.perfectwallpaper.utils.DatabaseUtils;
import com.wallpaper.perfectwallpaper.utils.GallerySaver;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class ImageActivity extends AppCompatActivity {

    private ActivityImageBinding binding;
    private String imagePath;
    private DatabaseUtils databaseUtils;
    private Bitmap bitmap;
    private ImageEntry imageEntry;
    private Boolean isFavorite = false;
    private final Executor executor = Executors.newSingleThreadExecutor();
    private GallerySaver gallerySaver;
    private WallpaperManager wallpaperManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        EdgeToEdge.enable(this);
        binding = ActivityImageBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        initData();
        initEvent();

    }

    private void initData() {

        gallerySaver = new GallerySaver(this, binding.progressBar, binding.view);
        wallpaperManager = WallpaperManager.getInstance(this);
        imagePath = getIntent().getStringExtra("imagePath");
        if (imagePath == null) {
            Toast.makeText(this, "The picture does not exist", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

        databaseUtils = new DatabaseUtils(this);
        executor.execute(() -> {
            imageEntry = databaseUtils.getImageEntry(imagePath);
            isFavorite = imageEntry.getLike();
            setFavoriteButton();
        });

    }

    private void initEvent() {

        showProgress();

        binding.back.setOnClickListener(v -> finish());
        binding.favorite.setOnClickListener(v -> {
            isFavorite = !isFavorite;
            setFavoriteButton();
        });
        binding.setWallpaper.setOnClickListener(v -> showCustomBottomSheetDialog());
        binding.download.setOnClickListener(v -> {

            showProgress();
            ImageActivity activity = (ImageActivity) v.getContext();
            gallerySaver.saveToGallery(activity, imagePath);

        });

        loadImage();

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_WRITE_EXTERNAL_STORAGE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                gallerySaver.saveToGallery(this, imagePath);
            } else {
                Toast.makeText(this, "Description The write permission to the external storage is denied", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void loadImage() {
        Glide.with(this)
                .asBitmap()
                .load(imagePath)
                .error(R.mipmap.placeholder)
                .into(new CustomTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                        binding.image.setImageBitmap(resource);
                        bitmap = resource;
                        hideProgress();

                    }

                    @Override
                    public void onLoadCleared(@Nullable Drawable placeholder) {

                        Toast.makeText(ImageActivity.this, "Loading failed, please check the network and try again", Toast.LENGTH_SHORT).show();

                    }
                });
    }

    private void showCustomBottomSheetDialog() {
        BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);
        View dialogView = LayoutInflater.from(this).inflate(R.layout.set_dialog, null);

        bottomSheetDialog.setCanceledOnTouchOutside(false);

        dialogView.findViewById(R.id.both).setOnClickListener(v -> {
            showProgress();
            setWallpaperBoth(bitmap);
            bottomSheetDialog.dismiss();
        });

        dialogView.findViewById(R.id.lock).setOnClickListener(v -> {
            showProgress();
            setWallpaperLock(bitmap);
            bottomSheetDialog.dismiss();
        });

        dialogView.findViewById(R.id.desktop).setOnClickListener(v -> {
            showProgress();
            setWallpaperDeskTop(bitmap);
            bottomSheetDialog.dismiss();
        });

        bottomSheetDialog.setContentView(dialogView);
        bottomSheetDialog.show();
    }

    private void setWallpaperBoth(Bitmap bitmap) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    binding.image.setDrawingCacheEnabled(true);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        wallpaperManager.setBitmap(bitmap, null, true, WallpaperManager.FLAG_SYSTEM);
                        wallpaperManager.setBitmap(bitmap, null, true, WallpaperManager.FLAG_LOCK);
                    } else {
                        wallpaperManager.setBitmap(bitmap);
                    }

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            hideProgress();
                            binding.setWallpaper.setEnabled(true);
                            Toast.makeText(getApplicationContext(), "Wallpaper setting is successful", Toast.LENGTH_SHORT).show();
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            hideProgress();
                            Toast.makeText(getApplicationContext(), "Failed to set wallpaper", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        }).start();
    }

    private void setWallpaperLock(Bitmap bitmap) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    binding.image.setDrawingCacheEnabled(true);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        wallpaperManager.setBitmap(bitmap, null, true, WallpaperManager.FLAG_LOCK);
                    } else {
                        wallpaperManager.setBitmap(bitmap);
                    }

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            hideProgress();
                            binding.setWallpaper.setEnabled(true);
                            Toast.makeText(getApplicationContext(), "Wallpaper setting is successful", Toast.LENGTH_SHORT).show();
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            hideProgress();
                            Toast.makeText(getApplicationContext(), "Failed to set wallpaper", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        }).start();
    }

    private void setWallpaperDeskTop(Bitmap bitmap) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    binding.image.setDrawingCacheEnabled(true);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        wallpaperManager.setBitmap(bitmap, null, true, WallpaperManager.FLAG_SYSTEM);
                    } else {
                        wallpaperManager.setBitmap(bitmap);
                    }
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            hideProgress();
                            binding.setWallpaper.setEnabled(true);
                            Toast.makeText(getApplicationContext(), "Wallpaper setting is successful", Toast.LENGTH_SHORT).show();
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            hideProgress();
                            Toast.makeText(getApplicationContext(), "Failed to set wallpaper", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        }).start();
    }

    private void setFavoriteButton() {
        binding.favorite.setImageResource(isFavorite
                ? R.drawable.like
                : R.drawable.un_like);
    }

    private void hideProgress() {
        binding.progressBar.setVisibility(View.GONE);
        binding.view.setVisibility(View.GONE);
    }

    private void showProgress() {
        binding.progressBar.setVisibility(View.VISIBLE);
        binding.view.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onPause() {
        super.onPause();
        executor.execute(() -> {
            imageEntry.setLike(isFavorite);
            databaseUtils.update(imageEntry);
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        binding = null;
    }
}