package com.david.hydroflux

import android.annotation.SuppressLint
import android.os.Bundle
import android.webkit.JavascriptInterface
import android.webkit.WebView
import android.webkit.WebViewClient
import android.webkit.WebChromeClient
import android.widget.Toast // Added for Debugging
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.permission.HealthPermission
import androidx.health.connect.client.records.StepsRecord
import androidx.health.connect.client.records.SleepSessionRecord
import androidx.health.connect.client.request.ReadRecordsRequest
import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.time.TimeRangeFilter
import kotlinx.coroutines.launch
import java.time.Instant
import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit

class MainActivity : FragmentActivity() {
    private lateinit var myWebView: WebView
    private lateinit var healthConnectClient: HealthConnectClient
    
    // Define Permissions we need
    private val PERMISSIONS = setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getReadPermission(SleepSessionRecord::class)
    )

    private val requestPermissions = registerForActivityResult(
        androidx.health.connect.client.PermissionController.createRequestPermissionResultContract()
    ) { granted ->
        if (granted.containsAll(PERMISSIONS)) {
            // Permissions Granted - Silent Sync
             if (::healthConnectClient.isInitialized) {
                 // Use a slight delay to allow permission propogation
                 android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
                     WebAppInterface(this@MainActivity).triggerSync() 
                 }, 500)
             }
        } else {
            val missing = PERMISSIONS.minus(granted)
            Toast.makeText(this, "Denied. Opening Settings...", Toast.LENGTH_LONG).show()
            // Fallback: Open Health Connect Settings so user can enable manually
            try {
                val intent = android.content.Intent("androidx.health.ACTION_HEALTH_CONNECT_SETTINGS")
                startActivity(intent)
            } catch (e: Exception) {
                 // Try generic app details
                 Toast.makeText(this, "Could not open Health Settings", Toast.LENGTH_SHORT).show()
                 val intent = android.content.Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                 intent.data = android.net.Uri.parse("package:$packageName")
                 startActivity(intent)
            }
        }
    }

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Setup WebView FIRST to ensure we have it
        myWebView = findViewById(R.id.webview)
        myWebView.settings.javaScriptEnabled = true
        myWebView.settings.domStorageEnabled = true
        myWebView.settings.allowFileAccess = true
        myWebView.settings.allowFileAccessFromFileURLs = true
        myWebView.settings.allowUniversalAccessFromFileURLs = true
        myWebView.webViewClient = WebViewClient()
        myWebView.webChromeClient = WebChromeClient()
        myWebView.addJavascriptInterface(WebAppInterface(this), "HydroFluxNative")
        myWebView.loadUrl("file:///android_asset/index.html")

        // Setup Health Connect
        val availabilityStatus = HealthConnectClient.getSdkStatus(this)
        
        if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) {
            Toast.makeText(this, "Health Connect Unavailable on this device", Toast.LENGTH_LONG).show()
            return 
        }
        if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
            Toast.makeText(this, "Health Connect Update Required", Toast.LENGTH_LONG).show()
            return
        }
        
        // Grab client
        try {
            healthConnectClient = HealthConnectClient.getOrCreate(this)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        
        // Start Periodic Sleep Check (6am - 10am)
        startPeriodicCheck()
    }

    private fun startPeriodicCheck() {
        val handler = android.os.Handler(android.os.Looper.getMainLooper())
        val runnable = object : Runnable {
            override fun run() {
                val cal = java.util.Calendar.getInstance()
                val hour = cal.get(java.util.Calendar.HOUR_OF_DAY)
                
                // Check between 6:00 and 10:00
                if (hour in 6..10) {
                     WebAppInterface(this@MainActivity).triggerSync()
                }
                
                // Repeat every 30 minutes (30 * 60 * 1000)
                handler.postDelayed(this, 1800000) 
            }
        }
        handler.post(runnable) // Start immediately
    }

    inner class WebAppInterface(private val activity: MainActivity) {
        @JavascriptInterface
        fun requestHealthPermissions() {
            runOnUiThread {
                if (!::healthConnectClient.isInitialized) {
                    Toast.makeText(activity, "Health Client Not Init", Toast.LENGTH_SHORT).show()
                    return@runOnUiThread
                }
                
                activity.lifecycleScope.launch {
                    try {
                        val granted = healthConnectClient.permissionController.getGrantedPermissions()
                        
                        if (granted.containsAll(PERMISSIONS)) {
                            triggerSync()
                        } else {
                            try {
                                requestPermissions.launch(PERMISSIONS)
                            } catch (e: Exception) {
                                val err = e.message ?: "Unknown"
                                Toast.makeText(activity, "Launch Error: $err", Toast.LENGTH_LONG).show()
                                e.printStackTrace()
                            }
                        }
                    } catch (e: Exception) {
                         e.printStackTrace()
                    }
                }
            }
        }

        @JavascriptInterface
        fun triggerSync() {
            if (!::healthConnectClient.isInitialized) return

            activity.lifecycleScope.launch {
                // MOVE TO IO THREAD for stability (Prevents IllegalStateException)
                kotlinx.coroutines.withContext(kotlinx.coroutines.Dispatchers.IO) {

                    // Use Application Context for Client
                    try {
                        if (!::healthConnectClient.isInitialized) {
                             healthConnectClient = HealthConnectClient.getOrCreate(activity.applicationContext)
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                    
                    val startOfDay = ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS).toInstant()
                    val now = Instant.now()
    
                    var totalSteps = 0L
                    var sleepHours = 0.0
    
                    // 1. Try Read Steps (AGGREGATE)
                    try {
                        val response = healthConnectClient.aggregate(
                            AggregateRequest(
                                metrics = setOf(StepsRecord.COUNT_TOTAL),
                                timeRangeFilter = TimeRangeFilter.between(startOfDay, now)
                            )
                        )
                        // The result may be null if no data
                        totalSteps = response[StepsRecord.COUNT_TOTAL] ?: 0
                    } catch (e: Exception) {
                        e.printStackTrace()
                        val msg = e.message ?: "Unknown Error"
                        runOnUiThread { Toast.makeText(activity, "Steps Error: $msg", Toast.LENGTH_LONG).show() }
                        totalSteps = 0
                    }
    
                    // 2. Try Read Sleep (AGGREGATE)
                    try {
                        val sleepResponse = healthConnectClient.aggregate(
                            AggregateRequest(
                                metrics = setOf(SleepSessionRecord.SLEEP_DURATION_TOTAL),
                                timeRangeFilter = TimeRangeFilter.between(now.minus(24, ChronoUnit.HOURS), now)
                            )
                        )
                        // Get total duration in Seconds (Duration -> Seconds)
                        val duration = sleepResponse[SleepSessionRecord.SLEEP_DURATION_TOTAL]
                        if (duration != null) {
                             sleepHours = duration.seconds / 3600.0
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                        sleepHours = 0.0
                    }
    
                    runOnUiThread {
                        if (!activity.isFinishing && !activity.isDestroyed) {
                            try {
                                myWebView.evaluateJavascript("window.updateHealthData($totalSteps, $sleepHours)", null)
                            } catch (e: Exception) {
                                e.printStackTrace()
                            }
                        }
                    }
                }
            }
        }
    }

    @Suppress("DEPRECATION")
    @Deprecated("Deprecated in Java")
    override fun onBackPressed() {
        if (myWebView.canGoBack()) {
            myWebView.goBack()
        } else {
            super.onBackPressed()
        }
    }
}