package legion.muyue.best2048;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

/**
 * Classe utilitaire pour aider à la création et à l'affichage des notifications Android
 * pour l'application Best2048.
 * Gère la création du canal de notification requis à partir d'Android 8 (Oreo)
 * et fournit une méthode standardisée pour afficher les notifications,
 * en incluant la vérification des permissions pour Android 13+ et la configuration
 * d'un {@link PendingIntent} pour ouvrir l'application.
 *
 * <p>Il est recommandé d'appeler {@link #createNotificationChannel(Context)} une fois
 * au démarrage de l'application (par exemple, dans la méthode {@code onCreate} de la classe Application)
 * pour s'assurer que le canal est disponible avant d'envoyer des notifications sur les appareils
 * Android 8.0+.</p>
 */
public class NotificationHelper {

    /**
     * Identifiant unique et constant pour le canal de notification de l'application.
     * Requis pour Android 8.0 (API niveau 26) et supérieur.
     */
    public static final String CHANNEL_ID = "BEST_2048_CHANNEL";

    /**
     * Constructeur privé pour empêcher l'instanciation de cette classe utilitaire.
     */
    private NotificationHelper() {
        // Classe utilitaire, ne doit pas être instanciée.
    }

    /**
     * Crée le canal de notification nécessaire pour afficher des notifications sur
     * Android 8.0 (Oreo, API niveau 26) et supérieur.
     * Si l'application cible une version d'Android inférieure ou si le canal existe déjà,
     * cette méthode n'a aucun effet ou n'est pas nécessaire.
     * Doit être appelée avant de tenter d'afficher une notification sur les appareils concernés.
     * Utilise des ressources string ({@code R.string}) pour le nom et la description du canal.
     *
     * @param context Le contexte de l'application, nécessaire pour accéder aux services système
     * et aux ressources. Ne doit pas être null.
     */
    public static void createNotificationChannel(@NonNull Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = context.getString(R.string.notification_channel_name);
            String description = context.getString(R.string.notification_channel_description);
            // Définit l'importance du canal (affecte comment la notification est présentée)
            int importance = NotificationManager.IMPORTANCE_DEFAULT; // Ou IMPORTANCE_HIGH, etc.

            // Crée l'objet NotificationChannel
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);

            // Récupère le NotificationManager système
            NotificationManager notificationManager = context.getSystemService(NotificationManager.class);

            // Enregistre le canal auprès du système. Si le canal existe déjà, aucune opération n'est effectuée.
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(channel);
            } else {
            }
        }
    }

    /**
     * Construit et affiche une notification standard pour l'application.
     * Gère la vérification de la permission {@code POST_NOTIFICATIONS} pour Android 13+ (Tiramisu).
     * Configure un {@link PendingIntent} pour ouvrir {@link MainActivity} lorsque l'utilisateur
     * appuie sur la notification.
     * Utilise {@link NotificationCompat} pour la compatibilité avec les anciennes versions d'Android.
     *
     * @param context        Le contexte de l'application. Ne doit pas être null.
     * @param title          Le titre de la notification. Ne doit pas être null.
     * @param message        Le message principal (corps) de la notification. Ne doit pas être null.
     * @param notificationId Un identifiant entier unique pour cette notification. Si une notification
     * avec le même ID existe déjà, elle sera mise à jour.
     */
    public static void showNotification(@NonNull Context context, @NonNull String title, @NonNull String message, int notificationId) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Vérifie si la permission d'envoyer des notifications est accordée
            if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
                // Si la permission n'est pas accordée, on ne peut pas afficher la notification.
                // L'application devrait demander la permission à l'utilisateur à un moment approprié.
                return; // Arrête l'exécution de la méthode
            }
        }

        // Crée un Intent pour ouvrir MainActivity lorsque la notification est cliquée
        Intent intent = new Intent(context, MainActivity.class);
        // Flags pour gérer le comportement de la pile d'activités
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

        // Crée un PendingIntent qui enveloppe l'Intent
        int pendingIntentFlags = PendingIntent.FLAG_UPDATE_CURRENT;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            pendingIntentFlags |= PendingIntent.FLAG_IMMUTABLE;
        }
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, pendingIntentFlags);

        // Construit la notification en utilisant NotificationCompat.Builder pour la compatibilité
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_stat_notification_2048) // Icône obligatoire
                .setContentTitle(title)              // Titre de la notification
                .setContentText(message)             // Corps du message
                .setPriority(NotificationCompat.PRIORITY_DEFAULT) // Priorité (affecte l'affichage)
                .setContentIntent(pendingIntent)     // Action lorsque l'utilisateur clique sur la notification
                .setAutoCancel(true)                 // Ferme la notification après le clic
                .setDefaults(NotificationCompat.DEFAULT_SOUND | NotificationCompat.DEFAULT_VIBRATE) // Son et vibration par défaut
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); // Visible sur l'écran de verrouillage

        // Récupère NotificationManagerCompat pour envoyer la notification
        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);

        try {
            notificationManager.notify(notificationId, builder.build());
        } catch (SecurityException e){
        } catch (Exception ex) {
        }
    }
}