package com.foxx.androidcast.ota;

/*********************************************************************
 * OtaUpdateCoordinator.java
 * Created at: Wed 20 May 2026 14:31:55 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class OtaUpdateCoordinator
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (2 commits, 137 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	04de2b9dd7b10206c7b2bcc26b2362fea30a7050a691b639920ac061c082b4ae
**********************************************************************/
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.ResultReceiver;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;

import com.foxx.androidcast.AppPreferences;
import com.foxx.androidcast.BuildConfig;
import com.foxx.androidcast.R;

import java.util.concurrent.atomic.AtomicBoolean;

/** Starts {@link OtaUpdateService} and hosts update prompts for visible activities. */
public final class OtaUpdateCoordinator {
    private static final AtomicBoolean sUpdateDialogOpen = new AtomicBoolean(false);

    private OtaUpdateCoordinator() {}

    public static String resolveEntryUrl(Context context) {
        String url = AppPreferences.getOtaChannelUrl(context);
        if (url.isEmpty()) {
            url = BuildConfig.OTA_CHANNEL_URL_DEFAULT != null
                    ? BuildConfig.OTA_CHANNEL_URL_DEFAULT.trim() : "";
        }
        if (url.isEmpty() && BuildConfig.OTA_MANIFEST_URL_DEFAULT != null) {
            url = BuildConfig.OTA_MANIFEST_URL_DEFAULT.trim();
        }
        return url;
    }

    public static void requestCheckOnLaunch(Context context) {
        OtaUpdateService.enqueueCheckOnLaunch(context.getApplicationContext());
    }

    public static void requestManualCheck(Activity activity) {
        ResultReceiver receiver = new ResultReceiver(new Handler(Looper.getMainLooper())) {
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                if (activity.isFinishing()) {
                    return;
                }
                if (resultCode == OtaUpdateService.RESULT_ERROR) {
                    String err = resultData != null
                            ? resultData.getString(OtaUpdateService.EXTRA_ERROR, "?") : "?";
                    Toast.makeText(activity, activity.getString(R.string.ota_check_failed, err),
                            Toast.LENGTH_LONG).show();
                    return;
                }
                if (resultCode == OtaUpdateService.RESULT_UP_TO_DATE) {
                    String name = resultData != null
                            ? resultData.getString(OtaUpdateService.EXTRA_INSTALLED_VERSION_NAME, "") : "";
                    int code = resultData != null
                            ? resultData.getInt(OtaUpdateService.EXTRA_INSTALLED_VERSION_CODE, 0) : 0;
                    Toast.makeText(activity,
                            activity.getString(R.string.ota_up_to_date, name, code),
                            Toast.LENGTH_LONG).show();
                    return;
                }
                if (resultCode == OtaUpdateService.RESULT_DISMISSED) {
                    Toast.makeText(activity, R.string.ota_dismissed_hint, Toast.LENGTH_SHORT).show();
                    return;
                }
                if (resultCode == OtaUpdateService.RESULT_UPDATE_AVAILABLE) {
                    String json = resultData != null
                            ? resultData.getString(OtaUpdateService.EXTRA_MANIFEST_JSON) : null;
                    OtaManifest manifest = OtaManifest.fromJsonString(json);
                    String sourceUrl = resultData != null
                            ? resultData.getString(OtaUpdateService.EXTRA_SOURCE_URL, "") : "";
                    boolean trustedSource = resultData != null
                            && resultData.getBoolean(OtaUpdateService.EXTRA_TRUSTED_SOURCE, false);
                    if (manifest != null) {
                        presentUpdateDialog(activity, manifest, sourceUrl, trustedSource);
                    }
                }
            }
        };
        OtaUpdateService.enqueueCheckManual(activity, receiver);
    }

    /**
     * Shows the update dialog (used from {@link com.foxx.androidcast.MainActivity} when the
     * service posts {@link OtaUpdateService#ACTION_UPDATE_AVAILABLE}).
     */
    public static void presentUpdateDialog(Activity activity, OtaManifest manifest) {
        presentUpdateDialog(activity, manifest, "", false);
    }

    public static void presentUpdateDialog(Activity activity, OtaManifest manifest,
            String sourceUrl, boolean trustedSource) {
        if (manifest == null || activity == null || activity.isFinishing()) {
            return;
        }
        if (!sUpdateDialogOpen.compareAndSet(false, true)) {
            return;
        }
        String notes = manifest.releaseNotes.isEmpty()
                ? activity.getString(R.string.ota_no_release_notes)
                : manifest.releaseNotes;
        String currentVersion = OtaUpdateChecker.installedVersionName(activity)
                + " (" + OtaUpdateChecker.installedVersionCode(activity) + ")";
        double sizeMb = manifest.downloadSizeBytes() > 0
                ? (manifest.downloadSizeBytes() / (1024.0 * 1024.0)) : 0.0;
        String sizeText = sizeMb > 0 ? String.format(java.util.Locale.US, "%.2f", sizeMb) : "?";
        String message = activity.getString(R.string.ota_update_message,
                manifest.displayVersion(),
                currentVersion,
                sizeText,
                notes);
        AlertDialog.Builder builder = new AlertDialog.Builder(activity)
                .setTitle(R.string.ota_update_title)
                .setMessage(message)
                .setCancelable(!manifest.mandatory)
                .setPositiveButton(R.string.ota_download_install, (d, w) ->
                        OtaUpdateService.enqueueDownload(activity, manifest, trustedSource, sourceUrl));
        if (!manifest.mandatory) {
            builder.setNegativeButton(R.string.ota_later, (d, w) ->
                    AppPreferences.setOtaDismissedVersionCode(activity,
                            manifest.effectiveVersionCode()));
        }
        AlertDialog dialog = builder.create();
        dialog.setOnDismissListener(d -> sUpdateDialogOpen.set(false));
        dialog.show();
    }
}
