package com.lemenzo.messenger.sms;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsManager;
import android.telephony.SubscriptionManager;
import com.lemenzo.messenger.SettingsActivity;
import com.lemenzo.messenger.data.PendingMessageStore;
import java.util.ArrayList;
import java.util.UUID;

public final class SmsSender {
    private SmsSender() {}

    /** Normal one-to-one SMS. */
    public static boolean send(
            Context context,
            String destination,
            String text,
            int subscriptionId) {
        return sendInternal(
                context, destination, text, subscriptionId,
                null, null, null);
    }

    /** Existing external request-id path used by legacy/integration callers. */
    public static boolean send(
            Context context,
            String destination,
            String text,
            int subscriptionId,
            String externalRequestId) {
        return sendInternal(
                context, destination, text, subscriptionId,
                externalRequestId, null, null);
    }

    /** Private local broadcast recipient, compatible with older v5.5 callers. */
    public static boolean sendBroadcastRecipient(
            Context context,
            String destination,
            String text,
            int subscriptionId,
            String broadcastId) {
        return sendInternal(
                context, destination, text, subscriptionId,
                null, broadcastId, null);
    }

    /** Private reusable broadcast recipient tied to one message in that conversation. */
    public static boolean sendBroadcastRecipient(
            Context context,
            String destination,
            String text,
            int subscriptionId,
            String broadcastId,
            String broadcastMessageId) {
        return sendInternal(
                context, destination, text, subscriptionId,
                null, broadcastId, broadcastMessageId);
    }

    /** Multi SMS compatibility overload without a message id. */
    public static boolean sendExternalBroadcastRecipient(
            Context context,
            String destination,
            String text,
            int subscriptionId,
            String externalRequestId,
            String broadcastId) {
        return sendInternal(
                context, destination, text, subscriptionId,
                externalRequestId, broadcastId, null);
    }

    /** Multi SMS path: request status + local broadcast conversation + message history. */
    public static boolean sendExternalBroadcastRecipient(
            Context context,
            String destination,
            String text,
            int subscriptionId,
            String externalRequestId,
            String broadcastId,
            String broadcastMessageId) {
        return sendInternal(
                context, destination, text, subscriptionId,
                externalRequestId, broadcastId, broadcastMessageId);
    }

    private static boolean sendInternal(
            Context context,
            String destination,
            String text,
            int subscriptionId,
            String externalRequestId,
            String broadcastId,
            String broadcastMessageId) {
        if (destination == null || destination.trim().isEmpty()
                || text == null || text.isEmpty()) {
            return false;
        }

        SmsManager base = context.getSystemService(SmsManager.class);
        if (base == null) return false;

        final SmsManager manager =
                subscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
                        ? base.createForSubscriptionId(subscriptionId)
                        : base;

        ArrayList<String> parts = manager.divideMessage(text);
        if (parts == null || parts.isEmpty()) return false;

        String token = UUID.randomUUID().toString();
        boolean requestDelivery = context
                .getSharedPreferences(SettingsActivity.PREFS, Context.MODE_PRIVATE)
                .getBoolean(SettingsActivity.PREF_DELIVERY_REPORTS, false);

        new PendingMessageStore(context).add(
                token,
                destination,
                text,
                System.currentTimeMillis(),
                subscriptionId);

        if (externalRequestId == null
                && broadcastId == null
                && broadcastMessageId == null) {
            MultipartSendTracker.begin(context, token, destination, text, parts.size(), subscriptionId);
        } else {
            MultipartSendTracker.begin(
                    context,
                    token,
                    destination,
                    text,
                    parts.size(),
                    subscriptionId,
                    externalRequestId,
                    broadcastId,
                    broadcastMessageId);
        }

        ArrayList<PendingIntent> sentIntents = new ArrayList<>();
        ArrayList<PendingIntent> deliveryIntents =
                requestDelivery ? new ArrayList<>() : null;

        for (int i = 0; i < parts.size(); i++) {
            Intent sent = new Intent(context, SendStatusReceiver.class)
                    .setAction(SendStatusReceiver.ACTION_SENT)
                    .putExtra("token", token)
                    .putExtra("part", i);

            sentIntents.add(PendingIntent.getBroadcast(
                    context,
                    (token + ":sent:" + i).hashCode(),
                    sent,
                    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));

            if (requestDelivery) {
                Intent delivered = new Intent(context, SendStatusReceiver.class)
                        .setAction(SendStatusReceiver.ACTION_DELIVERED)
                        .putExtra("token", token)
                        .putExtra("part", i);

                deliveryIntents.add(PendingIntent.getBroadcast(
                        context,
                        (token + ":delivered:" + i).hashCode(),
                        delivered,
                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));
            }
        }

        try {
            manager.sendMultipartTextMessage(
                    destination,
                    null,
                    parts,
                    sentIntents,
                    deliveryIntents);
            return true;
        } catch (RuntimeException e) {
            MultipartSendTracker.cancel(context, token);
            new PendingMessageStore(context).markFailed(token);
            return false;
        }
    }
}
