package com.tt.honeyDue.analytics

import android.app.Application
import android.util.Log
import com.posthog.PostHog
import com.posthog.android.PostHogAndroid
import com.posthog.android.PostHogAndroidConfig

/**
 * Android implementation of PostHog Analytics.
 */
actual object PostHogAnalytics {
    // TODO: Replace with your actual PostHog API key
    private const val API_KEY = "YOUR_POSTHOG_API_KEY"
    private const val HOST = "https://us.i.posthog.com"

    private const val TAG = "PostHogAnalytics"

    private var isInitialized = false
    private var application: Application? = null

    /**
     * Initialize PostHog SDK with Application context.
     * Call this in MainActivity.onCreate() before using other methods.
     */
    fun initialize(application: Application, debug: Boolean = false) {
        if (isInitialized) return
        this.application = application

        val config = PostHogAndroidConfig(API_KEY, HOST).apply {
            captureScreenViews = false // We'll track screens manually
            captureApplicationLifecycleEvents = true
            captureDeepLinks = true
            this.debug = debug

            // Session Replay
            sessionReplay = true
            sessionReplayConfig.maskAllTextInputs = true
            sessionReplayConfig.maskAllImages = false
        }

        PostHogAndroid.setup(application, config)
        isInitialized = true
    }

    /**
     * Initialize from common code (no-op on Android, use initialize(Application) instead)
     */
    actual fun initialize() {
        // No-op - Android requires Application context, use initialize(Application) instead
    }

    actual fun identify(userId: String, properties: Map<String, Any>?) {
        if (!isInitialized) return
        PostHog.identify(userId, userProperties = properties)
    }

    actual fun capture(event: String, properties: Map<String, Any>?) {
        if (!isInitialized) return
        PostHog.capture(event, properties = properties)
    }

    /**
     * Capture an exception/crash as a PostHog `$exception` event.
     * Uses PostHog's standard exception property names so exceptions
     * appear correctly in the PostHog Errors dashboard.
     */
    actual fun captureException(throwable: Throwable, properties: Map<String, Any>?) {
        if (!isInitialized) return
        try {
            val exceptionProps = mutableMapOf<String, Any>(
                "\$exception_type" to (throwable::class.simpleName ?: "Unknown"),
                "\$exception_message" to (throwable.message ?: "No message"),
                "\$exception_stack_trace_raw" to throwable.stackTraceToString()
            )
            if (properties != null) {
                exceptionProps.putAll(properties)
            }
            PostHog.capture("\$exception", properties = exceptionProps)
        } catch (e: Exception) {
            Log.e(TAG, "Failed to capture exception to PostHog", e)
        }
    }

    actual fun screen(screenName: String, properties: Map<String, Any>?) {
        if (!isInitialized) return
        PostHog.screen(screenName, properties = properties)
    }

    actual fun reset() {
        if (!isInitialized) return
        PostHog.reset()
    }

    actual fun flush() {
        if (!isInitialized) return
        PostHog.flush()
    }

    /**
     * Install an uncaught exception handler that captures crashes to PostHog
     * before delegating to the default handler (which shows the crash dialog).
     * Call this after initialize() in MainActivity.onCreate().
     */
    actual fun setupExceptionHandler() {
        if (!isInitialized) return

        val defaultHandler = Thread.getDefaultUncaughtExceptionHandler()
        Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
            try {
                PostHog.capture(
                    event = "\$exception",
                    properties = mapOf(
                        "\$exception_type" to (throwable::class.simpleName ?: "Unknown"),
                        "\$exception_message" to (throwable.message ?: "No message"),
                        "\$exception_stack_trace_raw" to throwable.stackTraceToString(),
                        "\$exception_thread" to thread.name,
                        "\$exception_is_fatal" to true
                    )
                )
                // Flush to ensure the event is sent before the process dies
                PostHog.flush()
            } catch (_: Exception) {
                // Don't let our crash handler crash
            }
            // Call the default handler so the system crash dialog still appears
            defaultHandler?.uncaughtException(thread, throwable)
        }
        Log.d(TAG, "Uncaught exception handler installed")
    }
}
