package com.dittomart.meatsbhavan.Service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;

import com.dittomart.meatsbhavan.R;
import com.dittomart.meatsbhavan.api.Api;
import com.dittomart.meatsbhavan.network.RetrofitInstance;
import com.dittomart.meatsbhavan.ui.MainActivity;
import com.dittomart.meatsbhavan.util.Constant;
import com.dittomart.meatsbhavan.util.SharePref;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Random;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class FirebaseMessageService extends FirebaseMessagingService {
    private static final String TAG = "FirebaseMessageService";

    private String channelId = "fcm_default_channel";

    /**
     * CRITICAL: Handle token refresh
     * This is called when Firebase generates a new token
     * Tokens refresh 2-4 times per year for security
     */
    @Override
    public void onNewToken(@NonNull String token) {
        super.onNewToken(token);
        Log.d(TAG, "New FCM Token Generated: " + token);
        
        // Save token locally
        SharePref.setDataPref(Constant.FCM_TOKEN, token);
        
        // Send to server
        sendTokenToServer(token);
    }



    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            sendNotification(remoteMessage);

    }

    //Notification Payload
    private void sendNotification(String title, String body, RemoteMessage remoteMessage) {

        Intent intent;
        intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(title)
                .setContentText(body)
                .setPriority(Notification.PRIORITY_MAX)
                .setDefaults(Notification.DEFAULT_SOUND)
                .setDefaults(Notification.DEFAULT_VIBRATE)
                .setDefaults(Notification.DEFAULT_ALL)
                .setAutoCancel(true)

                .setContentIntent(pendingIntent);


        String imageUrl = remoteMessage.getData().get("image");
        Log.d(TAG, "ImageUrl: " + imageUrl);

        if (imageUrl != null) {
            Bitmap largeIcon = giveImageFromUrl(Constant.BASE_URL + imageUrl);
            notificationBuilder.setLargeIcon(largeIcon)
                    .setStyle(new NotificationCompat.BigPictureStyle().bigLargeIcon((Bitmap) largeIcon));
        }


        notificationManager.notify(1, notificationBuilder.build());
    }

    //Data Payload
    private void sendNotification(RemoteMessage remoteMessage) {
        SharePref sharePref = new SharePref(this);
        String intentUrl = remoteMessage.getData().get("click_action") != null ? remoteMessage.getData().get("click_action") : SharePref.getDataFromPref(Constant.ANLIVER_BASE_URL);


        Log.d(TAG, "IntentUrl: " + intentUrl);

        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(channel);
        }
        Random random = new Random();

        if (intentUrl != null) {
            intent.putExtra("URL", intentUrl);
        }

        PendingIntent pendingIntent;
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            pendingIntent = PendingIntent.getActivity(this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
        }else{
            pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        }

        NotificationCompat.Builder notificationBuilder;
        notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.ic_stat)
                        .setContentTitle(remoteMessage.getData().get("title"))
                        .setContentText(remoteMessage.getData().get("message"))
                        .setPriority(Notification.PRIORITY_MAX)
                        .setDefaults(Notification.DEFAULT_SOUND)
                        .setDefaults(Notification.DEFAULT_VIBRATE)
                        .setDefaults(Notification.DEFAULT_ALL)
                        .setAutoCancel(true)
                        .setStyle(new NotificationCompat.BigTextStyle().bigText(remoteMessage.getData().get("message")))
                        .setContentIntent(pendingIntent);

        if (remoteMessage.getData().get("image") != null ) {
            String baseurl = SharePref.getDataFromPref(Constant.ANLIVER_BASE_URL);
            Bitmap bitmap = giveImageFromUrl(baseurl.substring(0, baseurl.length() - 1) + remoteMessage.getData().get("image"));
            Log.d(TAG, "Image: " + bitmap);
            notificationBuilder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(bitmap).bigLargeIcon((Bitmap) null)).setLargeIcon(bitmap);
        }else {
            if(remoteMessage.getData().get("badge") != null){
                String baseurl = SharePref.getDataFromPref(Constant.ANLIVER_BASE_URL);
                Bitmap bitmap = giveImageFromUrl(baseurl.substring(0, baseurl.length() - 1) + remoteMessage.getData().get("badge"));
                notificationBuilder.setLargeIcon(bitmap);
            }
        }


        //making random id for each notification
        int m = random.nextInt(9999 - 1000) + 1000;

        notificationManager.notify(m, notificationBuilder.build());
    }

    private Bitmap giveImageFromUrl(String url) {
        Log.d(TAG, "Url: " + url);
        try {
            URL url1 = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            return BitmapFactory.decodeStream(input);
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
            return null;
        }

    }

    /**
     * Send FCM token to server
     * When token is refreshed by Firebase, this sends it to backend
     * Note: After user logs in via WebView, WebAppInterface.registerFcm() handles
     * associating the token with the user_id
     */
    private void sendTokenToServer(String token) {
        try {
            // Create API service
            Api apiService = RetrofitInstance.getRetrofitIntance().create(Api.class);
            
            // Send as guest token initially
            // After login, WebAppInterface.registerFcm() will update it with user_id
            Log.d(TAG, "Sending refreshed token to server (guest mode)");
            Call<String> call = apiService.sendToken(token);
            call.enqueue(new Callback<String>() {
                @Override
                public void onResponse(Call<String> call, Response<String> response) {
                    if (response.isSuccessful()) {
                        Log.d(TAG, "✅ Token successfully sent to server");
                    } else {
                        Log.e(TAG, "❌ Failed to send token: " + response.code());
                    }
                }

                @Override
                public void onFailure(Call<String> call, Throwable t) {
                    Log.e(TAG, "❌ Error sending token to server: " + t.getMessage());
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "❌ Exception in sendTokenToServer: " + e.getMessage());
        }
    }

}
