package com.example.bdkipoc;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.HashMap;
import java.util.Map;

public class QrisResultActivity extends AppCompatActivity {
    // Main UI Components
    private ImageView qrImageView;
    private TextView amountTextView;
    private TextView timerTextView;
    private Button cancelButton;
    private TextView qrisLogo;
    private CardView mainCard;
    private View headerBackground;
    private View backNavigation;
    
    // Hidden components for functionality
    private TextView referenceTextView;
    private TextView statusTextView;
    private TextView qrStatusTextView;
    private ProgressBar progressBar;
    private Button downloadQrisButton;
    private Button checkStatusButton;
    private Button returnMainButton;
    
    // QR Refresh Components
    private Handler qrRefreshHandler;
    private Runnable qrRefreshRunnable;
    private int countdownSeconds = 60;
    private boolean isQrRefreshActive = true;
    
    // Success screen views
    private View successScreen;
    private ImageView successIcon;
    private TextView successMessage;
    
    private String orderId;
    private String grossAmount;
    private String referenceId;
    private String transactionId;
    private String transactionTime;
    private String acquirer;
    private String merchantId;
    private String currentQrImageUrl;
    private int originalAmount;
    
    // ✅ ADD: QR String untuk validasi QRIS
    private String currentQrString = "";
    private String qrStringFromMidtrans = "";
    
    // ✅ FIXED: Store actual issuer/acquirer from Midtrans response
    private String actualIssuerFromMidtrans = "";
    private String actualAcquirerFromMidtrans = "";
    
    // ✅ ADD: Track QR refresh transaction for payment monitoring
    private String currentQrTransactionId = "";
    private boolean isMonitoringQrRefreshTransaction = false;
    
    private String backendBase = "https://be-edc.msvc.app";
    private String webhookUrl = "https://be-edc.msvc.app/webhooks/midtrans";
    
    // Server key for signature generation
    private static final String MIDTRANS_AUTH = "Basic U0ItTWlkLXNlcnZlci1JM2RJWXdIRzVuamVMeHJCMVZ5endWMUM=";
    private static final String MIDTRANS_CHARGE_URL = "https://api.sandbox.midtrans.com/v2/charge";

    // ✅ ADD: Mapping dari technical issuer ke display name
    private static final Map<String, String> ISSUER_DISPLAY_MAP = new HashMap<String, String>() {{
        put("airpay shopee", "ShopeePay");
        put("shopeepay", "ShopeePay");
        put("shopee", "ShopeePay");
        put("linkaja", "LinkAja");
        put("link aja", "LinkAja");
        put("dana", "DANA");
        put("ovo", "OVO");
        put("gopay", "GoPay");
        put("jenius", "Jenius");
        put("sakuku", "Sakuku");
        put("bni", "BNI");
        put("bca", "BCA");
        put("mandiri", "Mandiri");
        put("bri", "BRI");
        put("cimb", "CIMB Niaga");
        put("permata", "Permata");
        put("maybank", "Maybank");
        put("qris", "QRIS");
    }};

    // Animation handler
    private Handler animationHandler = new Handler(Looper.getMainLooper());

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qris_result);

        // Initialize views
        initializeViews();
        
        // Get intent data
        getIntentData();

        // ✅ Initialize parent transaction tracking
        currentQrTransactionId = transactionId; // Initially monitor parent transaction
        isMonitoringQrRefreshTransaction = false;
        Log.d("QrisResultFlow", "🆔 Initial monitoring - parent transaction ID: " + transactionId);
        Log.d("QrisResultFlow", "🆔 Parent order ID: " + orderId);
        
        // Setup UI
        setupUI();
        
        // Setup success screen
        setupSuccessScreen();
        
        // Start QR refresh timer
        startQrRefreshTimer();
        
        // Start polling for pending payment log
        pollPendingPaymentLog(orderId);

        // Set up click listeners
        setupClickListeners();
        
        // Start continuous payment monitoring
        startContinuousPaymentMonitoring();
    }

    private void initializeViews() {
        // Main visible components
        qrImageView = findViewById(R.id.qrImageView);
        amountTextView = findViewById(R.id.amountTextView);
        timerTextView = findViewById(R.id.timerTextView);
        cancelButton = findViewById(R.id.cancel_button);
        qrisLogo = findViewById(R.id.qris_logo);
        mainCard = findViewById(R.id.main_card);
        headerBackground = findViewById(R.id.header_background);
        backNavigation = findViewById(R.id.back_navigation);
        
        // Hidden components for functionality
        referenceTextView = findViewById(R.id.referenceTextView);
        statusTextView = findViewById(R.id.statusTextView);
        qrStatusTextView = findViewById(R.id.qrStatusTextView);
        progressBar = findViewById(R.id.progressBar);
        downloadQrisButton = findViewById(R.id.downloadQrisButton);
        checkStatusButton = findViewById(R.id.checkStatusButton);
        returnMainButton = findViewById(R.id.returnMainButton);
        
        // Success screen views
        successScreen = findViewById(R.id.success_screen);
        successIcon = findViewById(R.id.success_icon);
        successMessage = findViewById(R.id.success_message);
        
        // Initialize handler for QR refresh
        qrRefreshHandler = new Handler(Looper.getMainLooper());
    }

    private void setupSuccessScreen() {
        // Initially hide success screen
        if (successScreen != null) {
            successScreen.setVisibility(View.GONE);
        }
    }

    private void getIntentData() {
        Intent intent = getIntent();
        currentQrImageUrl = intent.getStringExtra("qrImageUrl");
        originalAmount = intent.getIntExtra("amount", 0);
        referenceId = intent.getStringExtra("referenceId");
        orderId = intent.getStringExtra("orderId");
        grossAmount = intent.getStringExtra("grossAmount");
        transactionId = intent.getStringExtra("transactionId");
        transactionTime = intent.getStringExtra("transactionTime");
        acquirer = intent.getStringExtra("acquirer");
        merchantId = intent.getStringExtra("merchantId");
        
        // ✅ GET QR STRING from intent if available
        qrStringFromMidtrans = intent.getStringExtra("qrString");
        if (qrStringFromMidtrans != null) {
            currentQrString = qrStringFromMidtrans;
        }

        // Enhanced logging for debugging
        Log.d("QrisResultFlow", "=== QRIS RESULT ACTIVITY STARTED ===");
        Log.d("QrisResultFlow", "QR Image URL: " + currentQrImageUrl);
        Log.d("QrisResultFlow", "QR String: " + (currentQrString.length() > 50 ? currentQrString.substring(0, 50) + "..." : currentQrString));
        Log.d("QrisResultFlow", "Amount (int): " + originalAmount);
        Log.d("QrisResultFlow", "Gross Amount (string): " + grossAmount);
        Log.d("QrisResultFlow", "Reference ID: " + referenceId);
        Log.d("QrisResultFlow", "Order ID: " + orderId);
        Log.d("QrisResultFlow", "Transaction ID: " + transactionId);
        Log.d("QrisResultFlow", "======================================");
    }

    private void setupUI() {
        // Validate required data
        if (orderId == null || transactionId == null) {
            Log.e("QrisResultFlow", "Critical error: orderId or transactionId is null!");
            Toast.makeText(this, "Missing transaction details! Cannot proceed.", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        // Display formatted amount in rupiah format
        String formattedAmount = formatRupiahAmount(grossAmount != null ? grossAmount : String.valueOf(originalAmount));
        amountTextView.setText(formattedAmount);
        
        // Set reference data to hidden field
        if (referenceTextView != null) {
            referenceTextView.setText("Reference ID: " + referenceId);
        }

        // Load initial QR image
        loadQrImage(currentQrImageUrl);

        // Initialize timer display
        timerTextView.setText("60");
        
        // Set initial status in hidden field
        if (statusTextView != null) {
            statusTextView.setText("Waiting for payment...");
        }
        
        // Enable simulate payment functionality
        if (checkStatusButton != null) {
            checkStatusButton.setEnabled(false);
        }
        
        // ✅ VALIDATE QR STRING
        validateQrString(currentQrString);
    }

    private String formatRupiahAmount(String amount) {
        try {
            // Remove any existing currency symbols and formatting
            String cleanAmount = amount.replaceAll("[^0-9]", "");
            long amountLong = Long.parseLong(cleanAmount);
            
            // Format with dots as thousand separators
            return "RP." + String.format("%,d", amountLong).replace(',', '.');
        } catch (NumberFormatException e) {
            Log.w("QrisResultFlow", "Error formatting rupiah amount: " + e.getMessage());
            return "RP." + amount;
        }
    }

    // ✅ NEW: Validate QR String format
    private void validateQrString(String qrString) {
        if (qrString == null || qrString.isEmpty()) {
            Log.w("QrisResultFlow", "⚠️ QR String is empty - QR might be unparsable");
            return;
        }
        
        Log.d("QrisResultFlow", "🔍 Validating QR String...");
        Log.d("QrisResultFlow", "QR String length: " + qrString.length());
        Log.d("QrisResultFlow", "QR String preview: " + (qrString.length() > 100 ? qrString.substring(0, 100) + "..." : qrString));
        
        // ✅ BASIC QRIS FORMAT VALIDATION
        if (qrString.startsWith("00020101") || qrString.startsWith("00020102")) {
            Log.d("QrisResultFlow", "✅ QR String has valid QRIS header");
        } else {
            Log.w("QrisResultFlow", "⚠️ QR String might not be valid QRIS format - missing standard header");
        }
        
        // ✅ CHECK FOR REQUIRED FIELDS
        if (qrString.contains("ID.CO.QRIS.WWW")) {
            Log.d("QrisResultFlow", "✅ QR String contains QRIS Indonesia identifier");
        } else {
            Log.w("QrisResultFlow", "⚠️ QR String missing Indonesia QRIS identifier");
        }
        
        // ✅ CHECK FOR AMOUNT
        if (qrString.contains("54")) { // Field 54 is transaction amount
            Log.d("QrisResultFlow", "✅ QR String contains amount field");
        } else {
            Log.w("QrisResultFlow", "⚠️ QR String missing amount field");
        }
    }

    private void startQrRefreshTimer() {
        countdownSeconds = 60;
        isQrRefreshActive = true;
        
        qrRefreshRunnable = new Runnable() {
            @Override
            public void run() {
                if (!isQrRefreshActive) {
                    return;
                }
                
                if (countdownSeconds > 0) {
                    // Update countdown display
                    timerTextView.setText(String.valueOf(countdownSeconds));
                    countdownSeconds--;
                    
                    // Schedule next update in 1 second
                    qrRefreshHandler.postDelayed(this, 1000);
                } else {
                    // ✅ Time to refresh QR code - CREATE NEW QR TRANSACTION
                    Log.d("QrisResultFlow", "🔄 QR Code refresh time reached - creating new QR transaction");
                    refreshQrCode();
                }
            }
        };
        
        qrRefreshHandler.post(qrRefreshRunnable);
        Log.d("QrisResultFlow", "🕒 QR refresh timer started - 60 seconds countdown");
    }

    private void refreshQrCode() {
        if (!isQrRefreshActive) {
            return;
        }
        
        Log.d("QrisResultFlow", "🔄 Starting QR code refresh...");
        
        // Show loading state
        timerTextView.setText("...");
        
        // Generate new QR code in background
        new Thread(() -> {
            try {
                QrRefreshResult result = generateNewQrCode();
                
                runOnUiThread(() -> {
                    if (result != null && result.qrUrl != null && !result.qrUrl.isEmpty()) {
                        // ✅ Successfully refreshed QR
                        currentQrImageUrl = result.qrUrl;
                        currentQrString = result.qrString; // ✅ UPDATE QR STRING
                        loadQrImage(result.qrUrl);
                        
                        // ✅ VALIDATE NEW QR STRING
                        validateQrString(currentQrString);
                        
                        // ✅ IMPORTANT: Now monitoring QR refresh transaction for payment
                        Log.d("QrisResultFlow", "🔄 QR refreshed - now monitoring new QR transaction");
                        Log.d("QrisResultFlow", "🔄 Parent transaction ID: " + transactionId + " (reference only)");
                        Log.d("QrisResultFlow", "🔄 Monitoring QR transaction ID: " + currentQrTransactionId);
                        
                        // Restart timer
                        countdownSeconds = 60;
                        Log.d("QrisResultFlow", "✅ QR code refreshed successfully");
                        Toast.makeText(QrisResultActivity.this, "QR Code refreshed with valid format", Toast.LENGTH_SHORT).show();
                    } else {
                        // Failed to generate new QR
                        Log.e("QrisResultFlow", "❌ Failed to refresh QR code");
                        countdownSeconds = 30;
                        Toast.makeText(QrisResultActivity.this, "QR refresh failed, retrying...", Toast.LENGTH_SHORT).show();
                    }
                    
                    // Continue timer
                    qrRefreshHandler.postDelayed(qrRefreshRunnable, 1000);
                });
                
            } catch (Exception e) {
                Log.e("QrisResultFlow", "❌ QR refresh error: " + e.getMessage(), e);
                
                runOnUiThread(() -> {
                    countdownSeconds = 30;
                    qrRefreshHandler.postDelayed(qrRefreshRunnable, 1000);
                    Toast.makeText(QrisResultActivity.this, "QR refresh error", Toast.LENGTH_SHORT).show();
                });
            }
        }).start();
    }

    // ✅ NEW: QR Refresh Result class
    private static class QrRefreshResult {
        String qrUrl;
        String qrString;
        String transactionId;
        
        QrRefreshResult(String qrUrl, String qrString, String transactionId) {
            this.qrUrl = qrUrl;
            this.qrString = qrString;
            this.transactionId = transactionId;
        }
    }

    // ✅ FIXED: Return both QR URL and QR String
    private QrRefreshResult generateNewQrCode() {
        try {
            Log.d("QrisResultFlow", "🔧 Refreshing QR code for existing transaction");
            Log.d("QrisResultFlow", "🔄 Parent Transaction ID: " + transactionId);
            Log.d("QrisResultFlow", "🔄 Parent Order ID: " + orderId);
            
            // ✅ GENERATE SHORT ORDER ID to avoid 50 character limit
            String shortTimestamp = String.valueOf(System.currentTimeMillis()).substring(7);
            String newOrderId = orderId.substring(0, Math.min(orderId.length(), 43)) + "-q" + shortTimestamp;
            
            Log.d("QrisResultFlow", "🆕 New QR Order ID: " + newOrderId + " (Length: " + newOrderId.length() + ")");
            
            // ✅ VALIDATE ORDER ID LENGTH
            if (newOrderId.length() > 50) {
                newOrderId = orderId.substring(0, 36) + "-q" + shortTimestamp.substring(0, Math.min(shortTimestamp.length(), 7));
                Log.w("QrisResultFlow", "⚠️ Order ID too long, using fallback: " + newOrderId + " (Length: " + newOrderId.length() + ")");
            }
            
            // ✅ CREATE LINK TO PARENT TRANSACTION
            JSONObject customField1 = new JSONObject();
            customField1.put("parent_transaction_id", transactionId);
            customField1.put("parent_order_id", orderId);
            customField1.put("parent_reference_id", referenceId);
            customField1.put("qr_refresh_time", new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new java.util.Date()));
            customField1.put("qr_refresh_count", System.currentTimeMillis());
            customField1.put("is_qr_refresh", true);
            
            // ✅ CREATE QRIS PAYLOAD WITH NEW ORDER ID
            JSONObject payload = new JSONObject();
            payload.put("payment_type", "qris");
            
            JSONObject transactionDetails = new JSONObject();
            transactionDetails.put("order_id", newOrderId);
            transactionDetails.put("gross_amount", originalAmount);
            payload.put("transaction_details", transactionDetails);
            
            JSONObject customerDetails = new JSONObject();
            customerDetails.put("first_name", "Test");
            customerDetails.put("last_name", "Customer");
            customerDetails.put("email", "test@example.com");
            customerDetails.put("phone", "081234567890");
            payload.put("customer_details", customerDetails);
            
            JSONArray itemDetails = new JSONArray();
            JSONObject item = new JSONObject();
            item.put("id", "item1_qr_refresh_" + System.currentTimeMillis());
            item.put("price", originalAmount);
            item.put("quantity", 1);
            item.put("name", "QRIS Payment QR Refresh - " + new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date()) + 
                    " (Parent Ref: " + referenceId + ")");
            itemDetails.put(item);
            payload.put("item_details", itemDetails);
            
            payload.put("custom_field1", customField1.toString());
            
            JSONObject qrisDetails = new JSONObject();
            qrisDetails.put("acquirer", "gopay");
            qrisDetails.put("qr_refresh", true);
            qrisDetails.put("parent_transaction_id", transactionId);
            qrisDetails.put("refresh_timestamp", System.currentTimeMillis());
            payload.put("qris", qrisDetails);
            
            Log.d("QrisResultFlow", "📤 QR Refresh payload: " + payload.toString());
            
            // ✅ MAKE API CALL TO MIDTRANS
            URL url = new URI(MIDTRANS_CHARGE_URL).toURL();
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", MIDTRANS_AUTH);
            conn.setRequestProperty("X-Override-Notification", webhookUrl);
            conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0 QR-Refresh");
            conn.setRequestProperty("X-QR-Refresh", "true");
            conn.setRequestProperty("X-Parent-Transaction", transactionId);
            conn.setDoOutput(true);
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            
            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = payload.toString().getBytes("utf-8");
                os.write(input, 0, input.length);
            }
            
            int responseCode = conn.getResponseCode();
            Log.d("QrisResultFlow", "📥 QR refresh response code: " + responseCode);
            
            if (responseCode == 200 || responseCode == 201) {
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
                StringBuilder response = new StringBuilder();
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                
                // ✅ LOG FULL RESPONSE FOR DEBUGGING
                Log.d("QrisResultFlow", "📋 Full QR Refresh Response: " + response.toString());
                
                JSONObject jsonResponse = new JSONObject(response.toString());
                
                if (jsonResponse.has("status_code")) {
                    String statusCode = jsonResponse.getString("status_code");
                    if (!statusCode.equals("201")) {
                        String statusMessage = jsonResponse.optString("status_message", "Unknown error");
                        Log.e("QrisResultFlow", "❌ QR refresh failed with status: " + statusCode + " - " + statusMessage);
                        return null;
                    }
                }
                
                // ✅ EXTRACT QR URL AND QR STRING
                String newQrUrl = null;
                String newQrString = null;
                String newTransactionId = jsonResponse.optString("transaction_id", "");
                
                // Get QR URL from actions
                if (jsonResponse.has("actions")) {
                    JSONArray actionsArray = jsonResponse.getJSONArray("actions");
                    if (actionsArray.length() > 0) {
                        JSONObject actions = actionsArray.getJSONObject(0);
                        newQrUrl = actions.getString("url");
                    }
                }
                
                // ✅ GET QR STRING (CRITICAL FOR QRIS VALIDATION)
                if (jsonResponse.has("qr_string")) {
                    newQrString = jsonResponse.getString("qr_string");
                    Log.d("QrisResultFlow", "✅ Found QR String in response: " + (newQrString.length() > 50 ? newQrString.substring(0, 50) + "..." : newQrString));
                } else {
                    Log.w("QrisResultFlow", "⚠️ No QR String found in response - QR might be unparsable");
                }
                
                if (!newTransactionId.isEmpty()) {
                    currentQrTransactionId = newTransactionId;
                    isMonitoringQrRefreshTransaction = true;
                    Log.d("QrisResultFlow", "🔄 Now monitoring QR refresh transaction: " + newTransactionId);
                }
                
                Log.d("QrisResultFlow", "✅ QR refresh successful!");
                Log.d("QrisResultFlow", "🆕 New QR URL: " + newQrUrl);
                Log.d("QrisResultFlow", "🆕 New QR String Length: " + (newQrString != null ? newQrString.length() : "null"));
                Log.d("QrisResultFlow", "🆕 New QR Transaction ID: " + newTransactionId);
                
                return new QrRefreshResult(newQrUrl, newQrString, newTransactionId);
                
            } else {
                InputStream errorStream = conn.getErrorStream();
                String errorResponse = "";
                
                if (errorStream != null) {
                    BufferedReader br = new BufferedReader(new InputStreamReader(errorStream, "utf-8"));
                    StringBuilder errorBuilder = new StringBuilder();
                    String responseLine;
                    while ((responseLine = br.readLine()) != null) {
                        errorBuilder.append(responseLine.trim());
                    }
                    errorResponse = errorBuilder.toString();
                }
                
                Log.e("QrisResultFlow", "❌ QR refresh HTTP error " + responseCode + ": " + errorResponse);
                return null;
            }
            
        } catch (Exception e) {
            Log.e("QrisResultFlow", "❌ QR refresh exception: " + e.getMessage(), e);
            return null;
        }
    }

    // ✅ ENHANCED: Load QR image with better error handling
    private void loadQrImage(String qrImageUrl) {
        if (qrImageUrl != null && !qrImageUrl.isEmpty()) {
            Log.d("QrisResultFlow", "🖼️ Loading QR image from: " + qrImageUrl);
            
            // ✅ VALIDATE URL FORMAT
            if (!qrImageUrl.startsWith("http")) {
                Log.e("QrisResultFlow", "❌ Invalid QR URL format: " + qrImageUrl);
                qrImageView.setVisibility(View.GONE);
                Toast.makeText(this, "Invalid QR code URL format", Toast.LENGTH_SHORT).show();
                return;
            }
            
            new EnhancedDownloadImageTask(qrImageView).execute(qrImageUrl);
        } else {
            Log.w("QrisResultFlow", "⚠️ QR image URL is not available");
            qrImageView.setVisibility(View.GONE);
            Toast.makeText(this, "QR code URL not available", Toast.LENGTH_SHORT).show();
        }
    }

    private void stopQrRefresh() {
        isQrRefreshActive = false;
        if (qrRefreshHandler != null && qrRefreshRunnable != null) {
            qrRefreshHandler.removeCallbacks(qrRefreshRunnable);
        }
        
        Log.d("QrisResultFlow", "🛑 QR refresh timer stopped");
    }

    private void setupClickListeners() {
        // Cancel button
        cancelButton.setOnClickListener(v -> {
            addClickAnimation(v);
            stopQrRefresh();
            finish();
        });

        // Back navigation
        if (backNavigation != null) {
            backNavigation.setOnClickListener(v -> {
                addClickAnimation(v);
                stopQrRefresh();
                finish();
            });
        }

        // Hidden check status button for testing
        if (checkStatusButton != null) {
            checkStatusButton.setOnClickListener(v -> {
                Log.d("QrisResultFlow", "Check status button clicked");
                stopQrRefresh();
                simulateWebhook();
            });
        }

        // Hidden return main button
        if (returnMainButton != null) {
            returnMainButton.setOnClickListener(v -> {
                stopQrRefresh();
                Intent intent = new Intent(QrisResultActivity.this, com.example.bdkipoc.MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                finishAffinity();
            });
        }

        // Enable testing via double tap on QR logo
        qrisLogo.setOnClickListener(new View.OnClickListener() {
            private int clickCount = 0;
            private Handler handler = new Handler();
            private final int DOUBLE_TAP_TIMEOUT = 300;
            
            @Override
            public void onClick(View v) {
                clickCount++;
                if (clickCount == 1) {
                    handler.postDelayed(() -> clickCount = 0, DOUBLE_TAP_TIMEOUT);
                } else if (clickCount == 2) {
                    // Double tap detected - simulate payment
                    clickCount = 0;
                    Log.d("QrisResultFlow", "Double tap detected - simulating payment");
                    stopQrRefresh();
                    simulateWebhook();
                }
            }
        });
    }

    // Animation methods
    private void addClickAnimation(View view) {
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.95f, 1f);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.95f, 1f);
        
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(scaleX, scaleY);
        animatorSet.setDuration(150);
        animatorSet.start();
    }

    // ✅ ENHANCED: Download Image Task with better validation
    private static class EnhancedDownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        private ImageView bmImage;
        private String errorMessage;
        
        EnhancedDownloadImageTask(ImageView bmImage) {
            this.bmImage = bmImage;
        }
        
        @Override
        protected Bitmap doInBackground(String... urls) {
            String urlDisplay = urls[0];
            Bitmap bitmap = null;
            
            try {
                // ✅ VALIDATE URL
                if (urlDisplay == null || urlDisplay.isEmpty()) {
                    Log.e("QrisResultFlow", "❌ Empty QR URL provided");
                    errorMessage = "QR URL is empty";
                    return null;
                }
                
                if (!urlDisplay.startsWith("http")) {
                    Log.e("QrisResultFlow", "❌ Invalid QR URL format: " + urlDisplay);
                    errorMessage = "Invalid QR URL format";
                    return null;
                }
                
                Log.d("QrisResultFlow", "📥 Downloading image from: " + urlDisplay);
                
                URL url = new URI(urlDisplay).toURL();
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.setConnectTimeout(15000); // Increase timeout
                connection.setReadTimeout(15000);
                connection.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
                connection.setRequestProperty("Accept", "image/*");
                
                // ✅ ADD AUTHORIZATION if needed for Midtrans QR
                if (urlDisplay.contains("midtrans.com")) {
                    connection.setRequestProperty("Authorization", MIDTRANS_AUTH);
                }
                
                connection.connect();
                
                int responseCode = connection.getResponseCode();
                Log.d("QrisResultFlow", "📥 Image download response code: " + responseCode);
                
                if (responseCode == 200) {
                    InputStream input = connection.getInputStream();
                    bitmap = BitmapFactory.decodeStream(input);
                    
                    if (bitmap != null) {
                        Log.d("QrisResultFlow", "✅ Image downloaded successfully. Size: " + 
                              bitmap.getWidth() + "x" + bitmap.getHeight());
                    } else {
                        Log.e("QrisResultFlow", "❌ Failed to decode bitmap from stream");
                        errorMessage = "Failed to decode QR code image";
                    }
                } else {
                    Log.e("QrisResultFlow", "❌ Failed to download image. HTTP code: " + responseCode);
                    
                    // ✅ READ ERROR RESPONSE
                    InputStream errorStream = connection.getErrorStream();
                    if (errorStream != null) {
                        BufferedReader br = new BufferedReader(new InputStreamReader(errorStream));
                        StringBuilder errorResponse = new StringBuilder();
                        String line;
                        while ((line = br.readLine()) != null) {
                            errorResponse.append(line);
                        }
                        Log.e("QrisResultFlow", "❌ Error response: " + errorResponse.toString());
                    }
                    
                    errorMessage = "Failed to download QR code (HTTP " + responseCode + ")";
                }
                
            } catch (Exception e) {
                Log.e("QrisResultFlow", "❌ Exception downloading image: " + e.getMessage(), e);
                errorMessage = "Error downloading QR code: " + e.getMessage();
            }
            
            return bitmap;
        }
        
        @Override
        protected void onPostExecute(Bitmap result) {
            if (result != null) {
                bmImage.setImageBitmap(result);
                Log.d("QrisResultFlow", "✅ QR code image displayed successfully");
            } else {
                Log.e("QrisResultFlow", "❌ Failed to display QR code image");
                bmImage.setImageResource(android.R.drawable.ic_menu_report_image);
                if (errorMessage != null && bmImage.getContext() != null) {
                    Toast.makeText(bmImage.getContext(), "QR Error: " + errorMessage, Toast.LENGTH_LONG).show();
                }
            }
        }
    }

    // ✅ HELPER: Convert technical issuer name ke display name
    private String getDisplayName(String technicalName) {
        if (technicalName == null || technicalName.isEmpty()) {
            return "QRIS";
        }
        
        String lowerTechnicalName = technicalName.toLowerCase().trim();
        String displayName = ISSUER_DISPLAY_MAP.get(lowerTechnicalName);
        
        if (displayName != null) {
            Log.d("QrisResultFlow", "🏷️ Mapped '" + technicalName + "' -> '" + displayName + "'");
            return displayName;
        }
        
        // Fallback: capitalize first letter of each word
        String[] words = technicalName.split("\\s+");
        StringBuilder result = new StringBuilder();
        for (String word : words) {
            if (word.length() > 0) {
                result.append(Character.toUpperCase(word.charAt(0)))
                      .append(word.substring(1).toLowerCase())
                      .append(" ");
            }
        }
        String fallbackName = result.toString().trim();
        Log.d("QrisResultFlow", "🏷️ No mapping found for '" + technicalName + "', using fallback: '" + fallbackName + "'");
        return fallbackName;
    }

    // ✅ COMPLETELY FIXED: Use actual issuer from Midtrans response
    private void syncTransactionStatusToBackend(String finalStatus) {
        Log.d("QrisResultFlow", "🔄 Syncing status '" + finalStatus + "' to backend for reference: " + referenceId);
        
        new Thread(() -> {
            try {
                // ✅ GET FINAL ISSUER AND ACQUIRER VALUES
                String finalIssuer = actualIssuerFromMidtrans;
                String finalAcquirer = actualAcquirerFromMidtrans;
                
                // ✅ FALLBACK IF NOT SET
                if (finalIssuer.isEmpty()) {
                    finalIssuer = acquirer != null ? acquirer : "qris";
                }
                if (finalAcquirer.isEmpty()) {
                    finalAcquirer = acquirer != null ? acquirer : "gopay";
                }
                
                // ✅ USE MONITORING TRANSACTION FOR WEBHOOK (could be parent or QR refresh)
                String webhookTransactionId = !currentQrTransactionId.isEmpty() ? currentQrTransactionId : transactionId;
                String transactionType = isMonitoringQrRefreshTransaction ? "QR refresh transaction" : "parent transaction";
                
                Log.d("QrisResultFlow", "🏷️ Final webhook values:");
                Log.d("QrisResultFlow", "   Transaction ID: '" + webhookTransactionId + "' (" + transactionType + ")");
                Log.d("QrisResultFlow", "   Order ID: '" + orderId + "'");
                Log.d("QrisResultFlow", "   Issuer: '" + finalIssuer + "'");
                Log.d("QrisResultFlow", "   Acquirer: '" + finalAcquirer + "'");
                
                // ✅ FORMAT WEBHOOK MIDTRANS STANDARD
                JSONObject payload = new JSONObject();
                payload.put("status_code", "200");
                payload.put("status_message", "Success, transaction is found");
                payload.put("transaction_id", webhookTransactionId);
                payload.put("order_id", orderId);
                payload.put("merchant_id", merchantId != null ? merchantId : "G900255786");
                payload.put("gross_amount", grossAmount != null ? grossAmount : String.valueOf(originalAmount));
                payload.put("currency", "IDR");
                payload.put("payment_type", "qris");
                payload.put("transaction_time", transactionTime != null ? transactionTime : getCurrentDateTime());
                payload.put("transaction_status", finalStatus.equals("PAID") ? "settlement" : finalStatus.toLowerCase());
                payload.put("fraud_status", "accept");
                payload.put("acquirer", finalAcquirer);
                payload.put("issuer", finalIssuer);
                payload.put("settlement_time", getCurrentISOTime());
                payload.put("reference_id", referenceId);
                payload.put("shopeepay_reference_number", "");
                
                // ✅ ADD QR STRING if available
                if (!currentQrString.isEmpty()) {
                    payload.put("qr_string", currentQrString);
                    Log.d("QrisResultFlow", "📋 Added QR String to webhook payload");
                }
                
                // ✅ SIGNATURE untuk validasi
                String serverKey = getServerKey();
                String signature = generateSignature(orderId, "200", 
                    grossAmount != null ? grossAmount : String.valueOf(originalAmount), serverKey);
                payload.put("signature_key", signature);
                
                Log.d("QrisResultFlow", "📤 Webhook payload: " + payload.toString());
                
                // ✅ KIRIM KE WEBHOOK ENDPOINT
                String webhookUrl = backendBase + "/webhooks/midtrans";
                URL url = new URI(webhookUrl).toURL();
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setRequestProperty("Accept", "application/json");
                conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
                conn.setDoOutput(true);
                conn.setConnectTimeout(15000);
                conn.setReadTimeout(15000);
                
                try (OutputStream os = conn.getOutputStream()) {
                    byte[] input = payload.toString().getBytes("utf-8");
                    os.write(input, 0, input.length);
                }
                
                int responseCode = conn.getResponseCode();
                Log.d("QrisResultFlow", "📥 Webhook response: " + responseCode);
                
                if (responseCode == 200 || responseCode == 201) {
                    BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        response.append(line);
                    }
                    Log.d("QrisResultFlow", "✅ Webhook successful: " + response.toString());
                } else {
                    InputStream errorStream = conn.getErrorStream();
                    if (errorStream != null) {
                        BufferedReader br = new BufferedReader(new InputStreamReader(errorStream));
                        StringBuilder errorResponse = new StringBuilder();
                        String line;
                        while ((line = br.readLine()) != null) {
                            errorResponse.append(line);
                        }
                        Log.e("QrisResultFlow", "❌ Webhook failed: " + responseCode + " - " + errorResponse.toString());
                    }
                }
                
            } catch (Exception e) {
                Log.e("QrisResultFlow", "❌ Webhook error: " + e.getMessage(), e);
            }
        }).start();
    }

    private String getCurrentISOTime() {
        return new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
            .format(new java.util.Date());
    }

    // ✅ MODIFIED: Show full screen success instead of simple text display
    private void showPaymentSuccess() {
        Log.d("QrisResultFlow", "Showing payment success screen");
        
        stopQrRefresh();
        
        // ✅ SYNC STATUS KE BACKEND
        syncTransactionStatusToBackend("PAID");
        
        // Show full screen success
        showSuccessScreen();
        
        // Navigate to receipt after delay
        animationHandler.postDelayed(() -> {
            launchReceiptActivity();
        }, 2500);
        
        Toast.makeText(this, "Payment simulation completed successfully!", Toast.LENGTH_LONG).show();
    }

    // ✅ NEW: Show full screen success overlay with animations
    private void showSuccessScreen() {
        if (successScreen != null) {
            // Hide all main UI components first
            hideMainUIComponents();
            
            // Set success message
            if (successMessage != null) {
                successMessage.setText("Pembayaran Berhasil");
            }
            
            // Show success screen with fade in animation
            successScreen.setVisibility(View.VISIBLE);
            successScreen.setAlpha(0f);
            
            // Fade in the background
            ObjectAnimator backgroundFadeIn = ObjectAnimator.ofFloat(successScreen, "alpha", 0f, 1f);
            backgroundFadeIn.setDuration(500);
            backgroundFadeIn.start();
            
            // Add scale and bounce animation to success icon
            if (successIcon != null) {
                // Start with invisible icon
                successIcon.setScaleX(0f);
                successIcon.setScaleY(0f);
                successIcon.setAlpha(0f);
                
                // Scale animation with bounce effect
                ObjectAnimator scaleX = ObjectAnimator.ofFloat(successIcon, "scaleX", 0f, 1.2f, 1f);
                ObjectAnimator scaleY = ObjectAnimator.ofFloat(successIcon, "scaleY", 0f, 1.2f, 1f);
                ObjectAnimator iconFadeIn = ObjectAnimator.ofFloat(successIcon, "alpha", 0f, 1f);
                
                AnimatorSet iconAnimation = new AnimatorSet();
                iconAnimation.playTogether(scaleX, scaleY, iconFadeIn);
                iconAnimation.setDuration(800);
                iconAnimation.setStartDelay(300);
                iconAnimation.setInterpolator(new android.view.animation.OvershootInterpolator(1.2f));
                iconAnimation.start();
            }
            
            // Add slide up animation to success message
            if (successMessage != null) {
                successMessage.setAlpha(0f);
                successMessage.setTranslationY(50f);
                
                ObjectAnimator messageSlideUp = ObjectAnimator.ofFloat(successMessage, "translationY", 50f, 0f);
                ObjectAnimator messageFadeIn = ObjectAnimator.ofFloat(successMessage, "alpha", 0f, 1f);
                
                AnimatorSet messageAnimation = new AnimatorSet();
                messageAnimation.playTogether(messageSlideUp, messageFadeIn);
                messageAnimation.setDuration(600);
                messageAnimation.setStartDelay(600);
                messageAnimation.setInterpolator(new android.view.animation.DecelerateInterpolator());
                messageAnimation.start();
            }
        }
    }

    // ✅ NEW: Hide main UI components for clean success screen
    private void hideMainUIComponents() {
        // Hide main content
        if (mainCard != null) {
            mainCard.setVisibility(View.GONE);
        }
        
        // Hide header elements
        if (headerBackground != null) {
            headerBackground.setVisibility(View.GONE);
        }
        if (backNavigation != null) {
            backNavigation.setVisibility(View.GONE);
        }
        
        // Hide cancel button
        if (cancelButton != null) {
            cancelButton.setVisibility(View.GONE);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopQrRefresh();
        if (animationHandler != null) {
            animationHandler.removeCallbacksAndMessages(null);
        }
    }

    @Override
    public void onBackPressed() {
        // Prevent back press when success screen is showing
        if (successScreen != null && successScreen.getVisibility() == View.VISIBLE) {
            return;
        }
        
        stopQrRefresh();
        finish();
        super.onBackPressed();
    }

    private void pollPendingPaymentLog(final String orderId) {
        Log.d("QrisResultFlow", "Starting polling for orderId: " + orderId);
        
        new Thread(() -> {
            int maxAttempts = 12;
            int intervalMs = 2000;
            int attempt = 0;
            boolean found = false;
            
            while (attempt < maxAttempts && !found) {
                try {
                    String currentOrderId = this.orderId;
                    String urlStr = backendBase + "/api-logs?request_body_search_strict={\"order_id\":\"" + currentOrderId + "\"}";
                    Log.d("QrisResultFlow", "Polling attempt " + (attempt + 1) + "/" + maxAttempts + " for parent order: " + currentOrderId);
                    
                    URL url = new URL(urlStr);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    conn.setRequestProperty("Accept", "application/json");
                    conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
                    conn.setConnectTimeout(5000);
                    conn.setReadTimeout(5000);
                    
                    int responseCode = conn.getResponseCode();
                    
                    if (responseCode == 200) {
                        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                        StringBuilder response = new StringBuilder();
                        String line;
                        while ((line = br.readLine()) != null) {
                            response.append(line);
                        }
                        
                        JSONObject json = new JSONObject(response.toString());
                        JSONArray results = json.optJSONArray("results");
                        
                        if (results != null && results.length() > 0) {
                            Log.d("QrisResultFlow", "Found " + results.length() + " log entries");
                            
                            for (int i = 0; i < results.length(); i++) {
                                JSONObject log = results.getJSONObject(i);
                                JSONObject reqBody = log.optJSONObject("request_body");
                                
                                if (reqBody != null) {
                                    String transactionStatus = reqBody.optString("transaction_status");
                                    String logOrderId = reqBody.optString("order_id");
                                    
                                    Log.d("QrisResultFlow", "Log entry " + i + ": order_id=" + logOrderId + 
                                        ", transaction_status=" + transactionStatus);
                                    
                                    if (currentOrderId.equals(logOrderId) && 
                                    (transactionStatus.equals("pending") || 
                                        transactionStatus.equals("settlement") || 
                                        transactionStatus.equals("capture") ||
                                        transactionStatus.equals("success"))) {
                                        found = true;
                                        
                                        if (transactionStatus.equals("settlement") || 
                                            transactionStatus.equals("capture") ||
                                            transactionStatus.equals("success")) {
                                            
                                            Log.d("QrisResultFlow", "🎉 Payment already completed with status: " + transactionStatus);
                                            
                                            new Handler(Looper.getMainLooper()).post(() -> {
                                                stopQrRefresh();
                                                showPaymentSuccess();
                                                Toast.makeText(QrisResultActivity.this, "Payment completed!", Toast.LENGTH_LONG).show();
                                            });
                                            return;
                                        }
                                        
                                        Log.d("QrisResultFlow", "Found matching payment log with status: " + transactionStatus);
                                        break;
                                    }
                                }
                            }
                        }
                    } else {
                        Log.w("QrisResultFlow", "Polling failed with HTTP code: " + responseCode);
                    }
                } catch (Exception e) {
                    Log.e("QrisResultFlow", "Polling error on attempt " + (attempt + 1) + ": " + e.getMessage());
                }
                
                if (!found) {
                    attempt++;
                    if (attempt < maxAttempts) {
                        try { 
                            Thread.sleep(intervalMs); 
                        } catch (InterruptedException ignored) {
                            break;
                        }
                    }
                }
            }
            
            final boolean logFound = found;
            new Handler(Looper.getMainLooper()).post(() -> {
                if (logFound && checkStatusButton != null) {
                    checkStatusButton.setEnabled(true);
                    Toast.makeText(QrisResultActivity.this, "Payment log found!", Toast.LENGTH_SHORT).show();
                } else if (checkStatusButton != null) {
                    Toast.makeText(QrisResultActivity.this, "Payment log not found. Manual simulation available.", Toast.LENGTH_LONG).show();
                    checkStatusButton.setEnabled(true);
                }
            });
        }).start();
    }

    private String getServerKey() {
        try {
            String base64 = MIDTRANS_AUTH.replace("Basic ", "");
            byte[] decoded = android.util.Base64.decode(base64, android.util.Base64.DEFAULT);
            String decodedString = new String(decoded);
            return decodedString.replace(":", "");
        } catch (Exception e) {
            Log.e("QrisResultFlow", "Error decoding server key: " + e.getMessage());
            return "";
        }
    }

    private String generateSignature(String orderId, String statusCode, String grossAmount, String serverKey) {
        String input = orderId + statusCode + grossAmount + serverKey;
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-512");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (java.security.NoSuchAlgorithmException e) {
            Log.e("QrisResultFlow", "Error generating signature: " + e.getMessage());
            return "dummy_signature";
        }
    }

    private void startContinuousPaymentMonitoring() {
        Log.d("QrisResultFlow", "🔍 Starting continuous payment monitoring");
        
        Handler paymentMonitorHandler = new Handler(Looper.getMainLooper());
        
        Runnable paymentMonitorRunnable = new Runnable() {
            @Override
            public void run() {
                checkCurrentPaymentStatus();
                
                if (!isFinishing() && isQrRefreshActive) {
                    paymentMonitorHandler.postDelayed(this, 5000);
                }
            }
        };
        
        paymentMonitorHandler.post(paymentMonitorRunnable);
    }

    private void checkCurrentPaymentStatus() {
        new Thread(() -> {
            try {
                // ✅ CRITICAL: Monitor current QR transaction (could be parent or QR refresh)
                String monitoringTransactionId = !currentQrTransactionId.isEmpty() ? currentQrTransactionId : transactionId;
                String statusUrl = "https://api.sandbox.midtrans.com/v2/" + monitoringTransactionId + "/status";
                
                String transactionType = isMonitoringQrRefreshTransaction ? "QR refresh transaction" : "parent transaction";
                Log.d("QrisResultFlow", "🔍 Checking payment status for " + transactionType + ": " + monitoringTransactionId);
                
                URL url = new URI(statusUrl).toURL();
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Accept", "application/json");
                conn.setRequestProperty("Authorization", MIDTRANS_AUTH);
                conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
                conn.setConnectTimeout(10000);
                conn.setReadTimeout(10000);
                
                int responseCode = conn.getResponseCode();
                
                if (responseCode == 200) {
                    BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        response.append(line);
                    }
                    
                    JSONObject statusResponse = new JSONObject(response.toString());
                    String transactionStatus = statusResponse.optString("transaction_status", "");
                    String paymentType = statusResponse.optString("payment_type", "");
                    String grossAmount = statusResponse.optString("gross_amount", "");
                    
                    // ✅ PROPERLY EXTRACT AND STORE ACTUAL ISSUER/ACQUIRER
                    String actualIssuer = statusResponse.optString("issuer", "");
                    String actualAcquirer = statusResponse.optString("acquirer", "");
                    
                    // ✅ UPDATE QR STRING if available in status response
                    String qrStringFromStatus = statusResponse.optString("qr_string", "");
                    if (!qrStringFromStatus.isEmpty()) {
                        currentQrString = qrStringFromStatus;
                        Log.d("QrisResultFlow", "🔄 Updated QR String from status check");
                    }
                    
                    Log.d("QrisResultFlow", "💳 Payment status check result (" + transactionType + "):");
                    Log.d("QrisResultFlow", "   Status: " + transactionStatus);
                    Log.d("QrisResultFlow", "   Payment Type: " + paymentType);
                    Log.d("QrisResultFlow", "   Amount: " + grossAmount);
                    Log.d("QrisResultFlow", "   Actual Issuer: " + actualIssuer);
                    Log.d("QrisResultFlow", "   Actual Acquirer: " + actualAcquirer);
                    Log.d("QrisResultFlow", "   QR String Available: " + !qrStringFromStatus.isEmpty());
                    
                    // ✅ CRITICAL FIX: Store the actual values from Midtrans
                    if (!actualIssuer.isEmpty() && !actualIssuer.equalsIgnoreCase("qris")) {
                        actualIssuerFromMidtrans = actualIssuer;
                        Log.d("QrisResultFlow", "✅ Updated issuer from Midtrans: " + actualIssuer);
                    }
                    
                    if (!actualAcquirer.isEmpty() && !actualAcquirer.equalsIgnoreCase("qris")) {
                        actualAcquirerFromMidtrans = actualAcquirer;
                        Log.d("QrisResultFlow", "✅ Updated acquirer from Midtrans: " + actualAcquirer);
                    }
                    
                    // Update backward compatibility variable
                    if (!actualIssuer.isEmpty()) {
                        acquirer = actualIssuer;
                    }
                    
                    if (transactionStatus.equals("settlement") || 
                        transactionStatus.equals("capture") ||
                        transactionStatus.equals("success")) {
                        
                        Log.d("QrisResultFlow", "🎉 Payment detected as PAID! Status: " + transactionStatus + " (" + transactionType + ")");
                        
                        runOnUiThread(() -> {
                            stopQrRefresh();
                            syncTransactionStatusToBackend("PAID");
                            showPaymentSuccess();
                            Toast.makeText(QrisResultActivity.this, "Payment Successful! 🎉", Toast.LENGTH_LONG).show();
                        });
                        
                    } else if (transactionStatus.equals("pending")) {
                        Log.d("QrisResultFlow", "⏳ Payment still pending (" + transactionType + ")");
                    } else if (transactionStatus.equals("expire") || transactionStatus.equals("cancel")) {
                        Log.w("QrisResultFlow", "⚠️ Payment expired or cancelled: " + transactionStatus + " (" + transactionType + ")");
                        syncTransactionStatusToBackend("FAILED");
                    } else {
                        Log.d("QrisResultFlow", "📊 Payment status: " + transactionStatus + " (" + transactionType + ")");
                    }
                    
                } else {
                    Log.w("QrisResultFlow", "⚠️ Payment status check failed: HTTP " + responseCode + " (" + transactionType + ")");
                }
                
            } catch (Exception e) {
                Log.e("QrisResultFlow", "❌ Payment status check error: " + e.getMessage(), e);
            }
        }).start();
    }

    private void simulateWebhook() {
        Log.d("QrisResultFlow", "🚀 Starting webhook simulation");
        
        stopQrRefresh();
        
        new Thread(() -> {
            try {
                String serverKey = getServerKey();
                
                // ✅ USE MONITORING TRANSACTION FOR SIMULATION
                String currentOrderId = this.orderId;
                String currentTransactionId = !this.currentQrTransactionId.isEmpty() ? this.currentQrTransactionId : this.transactionId;
                String currentGrossAmount = this.grossAmount;
                String transactionType = isMonitoringQrRefreshTransaction ? "QR refresh transaction" : "parent transaction";
                
                Log.d("QrisResultFlow", "🚀 Simulating webhook for " + transactionType + ": " + currentTransactionId);
                
                String signatureKey = generateSignature(currentOrderId, "200", currentGrossAmount, serverKey);
                
                // ✅ GET ACTUAL ISSUER AND ACQUIRER
                String finalIssuer = actualIssuerFromMidtrans.isEmpty() ? 
                    (acquirer != null ? acquirer : "qris") : actualIssuerFromMidtrans;
                String finalAcquirer = actualAcquirerFromMidtrans.isEmpty() ? 
                    (acquirer != null ? acquirer : "gopay") : actualAcquirerFromMidtrans;
                
                JSONObject payload = new JSONObject();
                payload.put("transaction_type", "on-us");
                payload.put("transaction_time", transactionTime != null ? transactionTime : "2025-04-16T06:00:00Z");
                payload.put("transaction_status", "settlement");
                payload.put("transaction_id", currentTransactionId);
                payload.put("status_message", "midtrans payment notification");
                payload.put("status_code", "200");
                payload.put("signature_key", signatureKey);
                payload.put("settlement_time", transactionTime != null ? transactionTime : "2025-04-16T06:00:00Z");
                payload.put("payment_type", "qris");
                payload.put("order_id", currentOrderId);
                payload.put("merchant_id", merchantId != null ? merchantId : "G900255786");
                payload.put("issuer", finalIssuer);
                payload.put("gross_amount", currentGrossAmount);
                payload.put("fraud_status", "accept");
                payload.put("currency", "IDR");
                payload.put("acquirer", finalAcquirer);
                payload.put("shopeepay_reference_number", "");
                payload.put("reference_id", referenceId != null ? referenceId : "DUMMY_REFERENCE_ID");
                
                // ✅ ADD QR STRING to webhook if available
                if (!currentQrString.isEmpty()) {
                    payload.put("qr_string", currentQrString);
                    Log.d("QrisResultFlow", "📋 Added QR String to webhook simulation");
                }

                URL url = new URL(webhookUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
                conn.setDoOutput(true);
                conn.setConnectTimeout(15000);
                conn.setReadTimeout(15000);
                
                OutputStream os = conn.getOutputStream();
                os.write(payload.toString().getBytes());
                os.flush();
                os.close();
                
                int responseCode = conn.getResponseCode();
                Log.d("QrisResultFlow", "📥 Webhook response code: " + responseCode);
                
                BufferedReader br = new BufferedReader(new InputStreamReader(
                        responseCode < 400 ? conn.getInputStream() : conn.getErrorStream()));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    response.append(line);
                }
                
                Log.d("QrisResultFlow", "📥 Webhook response: " + 
                    (response.length() > 200 ? response.substring(0, 200) + "..." : response.toString()));
                
                Thread.sleep(2000);
                
            } catch (Exception e) {
                Log.e("QrisResultFlow", "❌ Webhook simulation error: " + e.getMessage(), e);
            }
            
            new Handler(Looper.getMainLooper()).post(() -> {
                showPaymentSuccess();
            });
        }).start();
    }

    private void launchReceiptActivity() {
        Intent intent = new Intent(this, ReceiptActivity.class);
        
        intent.putExtra("calling_activity", "QrisResultActivity");
        
        // ✅ GET FINAL ISSUER FOR RECEIPT
        String finalIssuer = actualIssuerFromMidtrans.isEmpty() ? 
            (acquirer != null ? acquirer : "qris") : actualIssuerFromMidtrans;
        
        String displayCardType = getDisplayName(finalIssuer);
        
        Log.d("QrisResultFlow", "Launching receipt with data:");
        Log.d("QrisResultFlow", "  Reference ID: " + referenceId);
        Log.d("QrisResultFlow", "  Transaction ID: " + transactionId);
        Log.d("QrisResultFlow", "  Amount: " + originalAmount);
        Log.d("QrisResultFlow", "  Actual Issuer: " + finalIssuer);
        Log.d("QrisResultFlow", "  Display Card Type: " + displayCardType);
        Log.d("QrisResultFlow", "  QR String Available: " + !currentQrString.isEmpty());
        
        intent.putExtra("transaction_id", transactionId);
        intent.putExtra("reference_id", referenceId);
        intent.putExtra("order_id", orderId);
        intent.putExtra("transaction_amount", String.valueOf(originalAmount));
        intent.putExtra("gross_amount", grossAmount != null ? grossAmount : String.valueOf(originalAmount));
        intent.putExtra("created_at", getReceiptDateTime());
        intent.putExtra("transaction_date", getReceiptDateTime());
        intent.putExtra("payment_method", "QRIS");
        intent.putExtra("channel_code", "QRIS");
        intent.putExtra("channel_category", "RETAIL_OUTLET");
        intent.putExtra("card_type", displayCardType);
        intent.putExtra("merchant_name", "Marcel Panjaitan");
        intent.putExtra("merchant_location", "Jakarta, Indonesia");
        intent.putExtra("acquirer", finalIssuer);
        intent.putExtra("mid", "71000026521");
        intent.putExtra("tid", "73001500");
        
        // ✅ ADD QR STRING to receipt if available
        if (!currentQrString.isEmpty()) {
            intent.putExtra("qr_string", currentQrString);
        }
        
        startActivity(intent);
    }

    private String getCurrentDateTime() {
        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("d/M/y H:m:s", new java.util.Locale("id", "ID"));
        return sdf.format(new java.util.Date());
    }

    private String getReceiptDateTime() {
        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("d/M/y H:m:s", new java.util.Locale("id", "ID"));
        return sdf.format(new java.util.Date());
    }
}