package com.example.piliplus;

import android.app.Activity;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.app.RemoteAction;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.provider.Settings;
import android.util.Rational;
import android.view.WindowManager;

import androidx.annotation.DrawableRes;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.github.dart_lang.jni_flutter.JniFlutterPlugin;

import java.util.ArrayList;
import java.util.Objects;

@Keep
public final class AndroidHelper {
    public static final boolean isFoldable;

    public static final boolean isPipAvailable;

    public static volatile boolean isPipMode = false;

    static {
        PackageManager pm = getContext().getPackageManager();
        isFoldable = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE);
        isPipAvailable = pm.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
    }

    private AndroidHelper() {
    }

    private static Context getContext() {
        return JniFlutterPlugin.getApplicationContext();
    }

    public static int sdkInt() {
        return Build.VERSION.SDK_INT;
    }

    public static void back() {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getContext().startActivity(intent);
    }

    public static void biliSendCommAntifraud(
            int action, long oid, int type, long rpId, long root, long parent, long ctime, @NonNull String commentText,
            String pictures, @NonNull String sourceId, long uid, @NonNull String cookie
    ) {
        Intent intent = new Intent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setComponent(new ComponentName(
                "icu.freedomIntrovert.biliSendCommAntifraud",
                "icu.freedomIntrovert.biliSendCommAntifraud.ByXposedLaunchedActivity"
        ));
        intent.putExtra("action", action);
        intent.putExtra("oid", oid);
        intent.putExtra("type", type);
        intent.putExtra("rpid", rpId);
        intent.putExtra("root", root);
        intent.putExtra("parent", parent);
        intent.putExtra("ctime", ctime);
        intent.putExtra("comment_text", commentText);
        if (pictures != null) {
            intent.putExtra("pictures", pictures);
        }
        intent.putExtra("source_id", sourceId);
        intent.putExtra("uid", uid);
        ArrayList<String> cookiesList = new ArrayList<>(1);
        cookiesList.add(cookie);
        intent.putStringArrayListExtra("cookies", cookiesList);
        getContext().startActivity(intent);
    }

    public static void openLinkVerifySettings() {
        Context context = getContext();
        Uri uri = Uri.parse("package:" + context.getPackageName());
        try {
            Intent intent;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS, uri);
            } else {
                intent = new Intent(Intent.ACTION_MAIN, uri);
                intent.setClassName(
                        "com.android.settings",
                        "com.android.settings.applications.InstalledAppOpenByDefaultActivity"
                );
            }
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        } catch (Exception ignored) {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, uri);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        }
    }

    public static boolean openMusic(@NonNull String title, String artist, String album) {
        Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_SEARCH);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(SearchManager.QUERY, title);
        intent.putExtra(MediaStore.EXTRA_MEDIA_TITLE, title);
        if (artist != null) {
            intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
        }
        if (album != null) {
            intent.putExtra(MediaStore.EXTRA_MEDIA_ALBUM, album);
        }
        intent.addCategory(Intent.CATEGORY_DEFAULT);

        Context context = getContext();
        PackageManager pm = context.getPackageManager();

        try {
            if (pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
                context.startActivity(intent);
                return true;
            }
        } catch (Exception ignored) {
        }

        try {
            intent.setAction(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
            if (pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
                context.startActivity(intent);
                return true;
            }
        } catch (Exception ignored) {
        }

        return false;
    }

    public static void enterPip(long engineId, int width, int height, boolean autoEnter, boolean isLive, boolean isPlaying) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Activity activity = JniFlutterPlugin.getActivity(engineId);
            assert activity != null;
            PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder()
                    .setAspectRatio(new Rational(width, height));
            setPipActions(activity, builder, isLive, isPlaying);
            if (autoEnter) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                    builder.setAutoEnterEnabled(true);
                    activity.setPictureInPictureParams(builder.build());
                }
            } else {
                activity.enterPictureInPictureMode(builder.build());
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    public static void updatePipActions(long engineId, boolean isLive, boolean isPlaying) {
        Activity activity = JniFlutterPlugin.getActivity(engineId);
        assert activity != null;
        PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder();
        setPipActions(activity, builder, isLive, isPlaying);
        activity.setPictureInPictureParams(builder.build());
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private static void setPipActions(Activity activity, PictureInPictureParams.Builder builder, boolean isLive, boolean isPlaying) {
        ComponentName mbrComponent = MediaHelper.getMediaButtonReceiverComponent(activity);
        if (mbrComponent == null) return;
        ArrayList<RemoteAction> actionList = new ArrayList<>(3);
        if (!isLive) {
            actionList.add(getRemoteAction(mbrComponent, activity, R.drawable.ic_player_rewind_10s, "ACTION_REWIND", (int) PlaybackState.ACTION_REWIND));
        }
        if (isPlaying) {
            actionList.add(getRemoteAction(mbrComponent, activity, R.drawable.ic_player_pause, "ACTION_PAUSE", (int) PlaybackState.ACTION_PAUSE));
        } else {
            actionList.add(getRemoteAction(mbrComponent, activity, R.drawable.ic_player_play, "ACTION_PLAY", (int) PlaybackState.ACTION_PLAY));
        }
        if (!isLive) {
            actionList.add(getRemoteAction(mbrComponent, activity, R.drawable.ic_player_fast_forward_10s, "ACTION_FAST_FORWARD", (int) PlaybackState.ACTION_FAST_FORWARD));
        }
        builder.setActions(actionList);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private static RemoteAction getRemoteAction(@NonNull ComponentName mbrComponent, Activity activity, @DrawableRes int resId, String title, int action) {
        return new RemoteAction(
                Icon.createWithResource(activity, resId),
                title,
                title,
                Objects.requireNonNull(MediaHelper.buildMediaButtonPendingIntent(activity, mbrComponent, action))
        );
    }

    public static void disableAutoEnterPip(long engineId) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            Activity activity = JniFlutterPlugin.getActivity(engineId);
            if (activity != null) {
                activity.setPictureInPictureParams(new PictureInPictureParams.Builder()
                        .setAutoEnterEnabled(false)
                        .build()
                );
            }
        }
    }

    public static int[] maxScreenSize() {
        Context context = getContext();
        WindowManager wm = context.getSystemService(WindowManager.class);
        try {
            float density = context.getResources().getDisplayMetrics().density;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                Rect maxBounds = wm.getMaximumWindowMetrics().getBounds();
                return new int[]{Math.round(maxBounds.width() / density), Math.round(maxBounds.height() / density)};
            } else {
                Point realSize = new Point();
                wm.getDefaultDisplay().getRealSize(realSize);
                return new int[]{Math.round(realSize.x / density), Math.round(realSize.y / density)};
            }
        } catch (Exception ignored) {
            return null;
        }
    }

    public static void createShortcut(@NonNull String id, @NonNull String uri, @NonNull String label, @NonNull String icon) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Context context = getContext();
            ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
            if (shortcutManager != null && shortcutManager.isRequestPinShortcutSupported()) {
                Bitmap bitmap = BitmapFactory.decodeFile(icon);
                ShortcutInfo shortcut = new ShortcutInfo.Builder(context, id)
                        .setShortLabel(label)
                        .setIcon(Icon.createWithAdaptiveBitmap(bitmap))
                        .setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(uri)))
                        .build();
                // TODO: WorkerThread
                Intent pinIntent = shortcutManager.createShortcutResultIntent(shortcut);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(
                        context, 0, pinIntent, PendingIntent.FLAG_IMMUTABLE
                );
                shortcutManager.requestPinShortcut(shortcut, pendingIntent.getIntentSender());
            }
        }
    }

    @Keep
    public static final class ToDart {
        public static volatile Runnable onUserLeaveHint;
        public static Runnable onConfigurationChanged;

        private ToDart() {
        }
    }
}
