package com.example.petstoremobile.utils;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.MediaStore;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * Helper class to handle image picking from camera or gallery.
 */
public class ImagePickerHelper {

    /**
     * Listener interface to handle the results of image picking.
     */
    public interface ImagePickerListener {
        /**
         * Called when an image has been successfully selected or captured.
         */
        void onImagePicked(Uri uri);
        /**
         * Called when the user chooses to remove the existing image.
         */
        void onImageRemoved();
    }

    private final Fragment fragment;
    private final ImagePickerListener listener;
    private final ActivityResultLauncher<Intent> galleryLauncher;
    private final ActivityResultLauncher<Uri> cameraLauncher;
    private final ActivityResultLauncher<String> permissionLauncher;
    private Uri photoUri;
    private final String tempFileName;

    /**
     * Constructor for ImagePickerHelper.
     * Registers activity launchers for gallery, camera, and permissions.
     */
    public ImagePickerHelper(Fragment fragment, String tempFileName, ImagePickerListener listener) {
        this.fragment = fragment;
        this.tempFileName = tempFileName;
        this.listener = listener;

        // Launcher to open gallery to select image
        galleryLauncher = fragment.registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
                        Uri selectedImage = result.getData().getData();
                        if (selectedImage != null) {
                            listener.onImagePicked(selectedImage);
                        }
                    }
                }
        );

        // Launcher for camera to open and capture image
        cameraLauncher = fragment.registerForActivityResult(
                new ActivityResultContracts.TakePicture(),
                success -> {
                    if (success && photoUri != null) {
                        listener.onImagePicked(photoUri);
                    }
                }
        );

        // Launcher to request camera permission
        permissionLauncher = fragment.registerForActivityResult(
                new ActivityResultContracts.RequestPermission(),
                granted -> {
                    if (granted) {
                        launchCamera();
                    } else {
                        showPermissionDeniedDialog();
                    }
                }
        );
    }

    /**
     * Shows a dialog to choose between camera, gallery, and optionally remove photo.
     */
    public void showImagePickerDialog(String title, boolean hasImage) {
        List<String> options = new ArrayList<>();
        options.add("Take Photo");
        options.add("Choose from Gallery");
        if (hasImage) {
            options.add("Remove Photo");
        }

        new AlertDialog.Builder(fragment.requireContext())
                .setTitle(title)
                .setItems(options.toArray(new String[0]), (dialog, which) -> {
                    String selected = options.get(which);
                    if (selected.equals("Take Photo")) {
                        checkCameraPermission();
                    } else if (selected.equals("Choose from Gallery")) {
                        launchGallery();
                    } else if (selected.equals("Remove Photo")) {
                        listener.onImageRemoved();
                    }
                })
                .show();
    }

    /**
     * Checks if camera permission is granted and launches camera or requests permission.
     */
    private void checkCameraPermission() {
        if (ContextCompat.checkSelfPermission(fragment.requireContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            launchCamera();
        } else {
            permissionLauncher.launch(Manifest.permission.CAMERA);
        }
    }

    /**
     * Prepares a temporary file and launches the camera app.
     */
    private void launchCamera() {
        try {
            File photoFile = new File(fragment.requireContext().getCacheDir(), tempFileName);
            if (!photoFile.exists()) photoFile.createNewFile();
            photoUri = FileProvider.getUriForFile(fragment.requireContext(),
                    fragment.requireContext().getPackageName() + ".fileprovider", photoFile);
            cameraLauncher.launch(photoUri);
        } catch (Exception e) {
            android.widget.Toast.makeText(fragment.requireContext(),
                    "Could not prepare camera", android.widget.Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * Launches the gallery app to select an existing image.
     */
    private void launchGallery() {
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        galleryLauncher.launch(intent);
    }

    /**
     * Shows a dialog explaining why camera permission is needed when denied.
     */
    private void showPermissionDeniedDialog() {
        new AlertDialog.Builder(fragment.requireContext())
                .setTitle("Permission Required")
                .setMessage("Please grant camera permission to use this feature")
                .setPositiveButton("Open Settings", (dialog, which) -> {
                    Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    intent.setData(Uri.fromParts("package", fragment.requireContext().getPackageName(), null));
                    fragment.startActivity(intent);
                })
                .setNegativeButton("Cancel", null)
                .show();
    }
}