package com.foxx.androidcast.crash;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;

import com.foxx.androidcast.CastActiveState;
import com.foxx.androidcast.stats.SessionStatsContext;
import com.foxx.androidcast.stats.SessionStatsRecorder;
import com.foxx.androidcast.stats.SessionStatsStore;

import org.json.JSONObject;

import java.io.File;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

/**
 * App-wide runtime snapshot for crash reports (cast idle, UI foreground, last session file).
 * Updated from {@link AndroidCastApplication} lifecycle and cast services.
 */
public final class CrashRuntimeContext {
    private static final AtomicLong APP_STARTED_MS = new AtomicLong(0L);
    private static final AtomicReference<String> LAST_ACTIVITY = new AtomicReference<>("");
    private CrashRuntimeContext() {}

    public static void init(Application app) {
        APP_STARTED_MS.compareAndSet(0L, System.currentTimeMillis());
        app.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
            @Override
            public void onActivityResumed(Activity activity) {
                LAST_ACTIVITY.set(activity.getClass().getSimpleName());
            }

            @Override
            public void onActivityCreated(Activity a, Bundle b) {}

            @Override
            public void onActivityStarted(Activity a) {}

            @Override
            public void onActivityPaused(Activity a) {}

            @Override
            public void onActivityStopped(Activity a) {}

            @Override
            public void onActivitySaveInstanceState(Activity a, Bundle b) {}

            @Override
            public void onActivityDestroyed(Activity a) {}
        });
    }

    public static boolean isCastSessionActive() {
        return CastActiveState.isSenderCasting() || CastActiveState.isReceiverListening();
    }

    /** JSON attached to every crash report (with or without an active cast stats recorder). */
    public static JSONObject snapshot(Context context) {
        JSONObject runtime = new JSONObject();
        try {
            long started = APP_STARTED_MS.get();
            if (started <= 0L) {
                started = System.currentTimeMillis();
            }
            runtime.put("app_started_epoch_ms", started);
            runtime.put("last_activity", LAST_ACTIVITY.get());
            runtime.put("sender_cast_active", CastActiveState.isSenderCasting());
            runtime.put("receiver_cast_active", CastActiveState.isReceiverListening());
            runtime.put("cast_active", isCastSessionActive());

            SessionStatsRecorder active = SessionStatsContext.get();
            runtime.put("session_stats_active", active != null);
            if (active != null) {
                runtime.put("session_direction", active.getDirection());
            }

            String lastSession = lastSessionFileName(context);
            if (!lastSession.isEmpty()) {
                runtime.put("last_session_file", lastSession);
            }
        } catch (Exception ignored) {
        }
        return runtime;
    }

    public static String scenarioLabel() {
        String proc = CrashReporter.currentProcessName();
        if (proc != null && proc.endsWith(":vpn")) {
            return "vpn_service";
        }
        if (proc != null && proc.endsWith(":netselftest")) {
            return "net_selftest";
        }
        if (SessionStatsContext.get() != null || isCastSessionActive()) {
            return "cast_session";
        }
        return "app_runtime";
    }

    private static String lastSessionFileName(Context context) {
        try {
            List<File> files = SessionStatsStore.listSessionFiles(context);
            if (files.isEmpty()) {
                return "";
            }
            return files.get(0).getName();
        } catch (Exception e) {
            return "";
        }
    }
}
