package com.tomer.alwayson.helpers;

import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Handler;

import com.tomer.alwayson.Globals;

import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class CurrentAppResolver {

    public static int GOOGLE_NOW = 301;
    public static int CAMERA = 302;

    private Context context;
    private ActivityManager activityManager;
    private Handler handler;
    private boolean active;
    private boolean firstLaunch = true;
    private ArrayList<String> appsPNs;

    public CurrentAppResolver(Context context, int[] apps) {
        this.context = context;
        this.active = true;
        this.handler = new Handler();
        this.activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (apps.length > 0) {
            appsPNs = new ArrayList<>();
            for (int app : apps) {
                if (app == GOOGLE_NOW)
                    appsPNs.add("com.google.android.googlequicksearchbox");
                if (app == CAMERA)
                    appsPNs.addAll(getCameraPackageName());
            }
            Utils.logDebug("Apps to stop for", appsPNs.toString());
            Utils.logInfo(CurrentAppResolver.class.getSimpleName(), "Started");
        }
    }

    private ArrayList<String> getCameraPackageName() {
        Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        List<ResolveInfo> listCam = context.getPackageManager().queryIntentActivities(intent, 0);
        ArrayList<String> PNs = new ArrayList<>();
        if (listCam == null || listCam.isEmpty()) return null;
        for (ResolveInfo res : listCam) {
            PNs.add(res.activityInfo.packageName);
        }
        return PNs;
    }

    private String getActivePackagesCompat() {
        List<ActivityManager.RunningTaskInfo> taskInfo = activityManager.getRunningTasks(1);
        ComponentName componentName = taskInfo.get(0).topActivity;
        return componentName.getPackageName();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
    private String getActivePackages() {
        UsageStatsManager usm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
        long time = System.currentTimeMillis();
        List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 200 * 200, time);
        if (appList != null && appList.size() > 0) {
            SortedMap<Long, UsageStats> mySortedMap = new TreeMap<>();
            for (UsageStats usageStats : appList) {
                mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
            }
            return mySortedMap.get(mySortedMap.lastKey()).getPackageName();
        }
        return context.getPackageName();
    }

    public void executeForCurrentApp(final Runnable action) {
        if (!appsPNs.isEmpty()) {
            ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
            executor.scheduleWithFixedDelay(() -> {
                if (active) {
                    final String activePackage = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getActivePackages() : getActivePackagesCompat();
                    if (activePackage != null) {
                        for (final String appPackageName : appsPNs) {
                            if (activePackage.equals(appPackageName)) {
                                if (!firstLaunch)
                                    action.run();
                            }
                            if (firstLaunch) {
                                if (activePackage.equals(appPackageName)) {
                                    Utils.logError(CurrentAppResolver.class.getSimpleName(), "App was already open when service started.");
                                    Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    context.startActivity(intent);
                                }
                                handler.postDelayed(() -> {
                                    if (activePackage.equals(appPackageName)) {
                                        Utils.logError(CurrentAppResolver.class.getSimpleName(), "App couldn't be closed, stopping the listener");
                                        appsPNs.remove(appPackageName);
                                    }
                                    firstLaunch = false;
                                }, 1000);
                            }
                        }
                    }
                } else {
                    Globals.waitingForApp = false;
                    executor.shutdown();
                }
            }, 0L, 300, TimeUnit.MILLISECONDS);
        }
    }

    public void destroy() {
        active = false;
    }
}