package awais.instagrabber.utils;

import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.res.Resources;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;

import awais.instagrabber.BuildConfig;
import awais.instagrabber.R;
import awais.instagrabber.databinding.DialogUpdateBinding;

import static awais.instagrabber.utils.Utils.settingsHelper;

public final class FlavorTown {
    private static final String TAG = "FlavorTown";
    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
    private static AlertDialog dialog;

    public static void updateCheck(@NonNull final AppCompatActivity context) {
        updateCheck(context, false);
    }

    @SuppressLint("PackageManagerGetSignatures")
    public static void updateCheck(@NonNull final AppCompatActivity context, final boolean force) {
        boolean isInstalledFromFdroid = false;
        final PackageInfo packageInfo;
        try {
            packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
            for (Signature signature : packageInfo.signatures) {
                final X509Certificate cert = X509Certificate.getInstance(signature.toByteArray());
                final String fingerprint = bytesToHex(MessageDigest.getInstance("SHA-1").digest(cert.getEncoded()));
                isInstalledFromFdroid = fingerprint.equals(Constants.FDROID_SHA1_FINGERPRINT);
                // Log.d(TAG, "fingerprint:" + fingerprint);
            }
        } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException | CertificateException e) {
            Log.e(TAG, "Error", e);
        }
        if (isInstalledFromFdroid) return;
        final DialogUpdateBinding binding = DialogUpdateBinding.inflate(context.getLayoutInflater(), null, false);
        binding.skipUpdate.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (dialog == null) return;
            dialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(!isChecked);
        });
        Resources res = context.getResources();
        new UpdateChecker(version -> {
            if (force && version.equals(BuildConfig.VERSION_NAME)) {
                Toast.makeText(context, "You're already on the latest version", Toast.LENGTH_SHORT).show();
                return;
            }
            final String skippedVersion = settingsHelper.getString(Constants.SKIPPED_VERSION);
            final boolean shouldShowDialog = force || (!version.equals(BuildConfig.VERSION_NAME) && !BuildConfig.DEBUG && !skippedVersion
                    .equals(version));
            if (!shouldShowDialog) return;
            dialog = new AlertDialog.Builder(context)
                    .setTitle(res.getString(R.string.update_available, version))
                    .setView(binding.getRoot())
                    .setNeutralButton(R.string.cancel, (dialog, which) -> {
                        if (binding.skipUpdate.isChecked()) {
                            settingsHelper.putString(Constants.SKIPPED_VERSION, version);
                        }
                        dialog.dismiss();
                    })
                    .setPositiveButton(R.string.action_github, (dialog1, which) -> {
                        try {
                            context.startActivity(new Intent(Intent.ACTION_VIEW).setData(
                                    Uri.parse("https://github.com/austinhuang0131/instagrabber/releases/latest")));
                        } catch (final ActivityNotFoundException e) {
                            // do nothing
                        }
                    })
                    // if we don't show dialog for fdroid users, is the below required?
                    .setNegativeButton(R.string.action_fdroid, (dialog, which) -> {
                        try {
                            context.startActivity(new Intent(Intent.ACTION_VIEW).setData(
                                    Uri.parse("https://f-droid.org/packages/me.austinhuang.instagrabber/")));
                        } catch (final ActivityNotFoundException e) {
                            // do nothing
                        }
                    })
                    .show();
        }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public static void changelogCheck(@NonNull final Context context) {
        if (settingsHelper.getInteger(Constants.PREV_INSTALL_VERSION) < BuildConfig.VERSION_CODE) {
            Toast.makeText(context, R.string.updated, Toast.LENGTH_SHORT).show();
            settingsHelper.putInteger(Constants.PREV_INSTALL_VERSION, BuildConfig.VERSION_CODE);
        }
    }

    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }
}