package com.hipograf.companion.ui

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.PermissionController
import androidx.lifecycle.lifecycleScope
import com.hipograf.companion.HipografApp
import com.hipograf.companion.api.HipografApi
import com.hipograf.companion.databinding.ActivityDashboardBinding
import com.hipograf.companion.health.HealthReader
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

class DashboardActivity : AppCompatActivity() {

    private lateinit var binding: ActivityDashboardBinding

    // Health Connect permission launcher
    private val requestPermissions =
        registerForActivityResult(PermissionController.createRequestPermissionResultContract()) { granted ->
            if (granted.containsAll(HealthReader.PERMISSIONS)) {
                Toast.makeText(this, "Permissions granted", Toast.LENGTH_SHORT).show()
                binding.tvStatus.text = "Ready to sync"
                syncNow()
            } else {
                binding.tvStatus.text = "Health Connect permissions denied"
                Toast.makeText(this, "Grant all permissions to sync your health data", Toast.LENGTH_LONG).show()
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityDashboardBinding.inflate(layoutInflater)
        setContentView(binding.root)

        updateLastSyncLabel()

        binding.btnSyncNow.setOnClickListener { onSyncClick() }
        binding.btnDiagnose.setOnClickListener { runDiagnose() }
        binding.btnLogout.setOnClickListener { logout() }

        checkHealthConnectStatus()
    }

    private fun checkHealthConnectStatus() {
        val status = HealthReader.availability(this)
        when (status) {
            HealthConnectClient.SDK_UNAVAILABLE -> {
                binding.tvStatus.text = "Health Connect not supported on this device"
                binding.btnSyncNow.isEnabled = false
            }
            HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED -> {
                binding.tvStatus.text = "Install Health Connect from Play Store"
                binding.btnSyncNow.text = "Install Health Connect"
                binding.btnSyncNow.isEnabled = true
            }
            HealthConnectClient.SDK_AVAILABLE -> {
                binding.tvStatus.text = "Ready to sync from Health Connect"
            }
        }
    }

    private fun onSyncClick() {
        val status = HealthReader.availability(this)
        if (status == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
            // Open Play Store to install Health Connect
            val intent = Intent(Intent.ACTION_VIEW).apply {
                data = Uri.parse("market://details?id=com.google.android.apps.healthdata")
                setPackage("com.android.vending")
            }
            try {
                startActivity(intent)
            } catch (_: Exception) {
                startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(
                    "https://play.google.com/store/apps/details?id=com.google.android.apps.healthdata"
                )))
            }
            return
        }

        if (status != HealthConnectClient.SDK_AVAILABLE) {
            Toast.makeText(this, "Health Connect not available", Toast.LENGTH_SHORT).show()
            return
        }

        lifecycleScope.launch {
            val hasPerms = HealthReader.hasAllPermissions(this@DashboardActivity)
            if (!hasPerms) {
                requestPermissions.launch(HealthReader.PERMISSIONS)
            } else {
                syncNow()
            }
        }
    }

    private fun syncNow() {
        val prefs = getSharedPreferences("hipograf", MODE_PRIVATE)
        val token = prefs.getString("token", null)
        if (token == null) {
            Toast.makeText(this, "Not logged in", Toast.LENGTH_SHORT).show()
            return
        }

        binding.btnSyncNow.isEnabled = false
        binding.btnSyncNow.text = "Syncing..."
        binding.tvStatus.text = "Reading Health Connect data..."

        lifecycleScope.launch {
            val result = withContext(Dispatchers.IO) {
                val readings = try {
                    HealthReader.readSince(this@DashboardActivity, 0L)
                } catch (e: HealthReader.MissingPermissionsException) {
                    return@withContext Result.failure<HipografApi.SyncResponse>(
                        Exception("Permissions missing. Tap Sync Now again to grant.")
                    )
                } catch (e: Exception) {
                    return@withContext Result.failure<HipografApi.SyncResponse>(
                        Exception("Read failed: ${e.message}")
                    )
                }
                if (readings.isEmpty()) {
                    return@withContext Result.failure<HipografApi.SyncResponse>(
                        Exception("No data in Health Connect. Open Samsung Health → Settings → Health Connect → enable categories (steps, heart rate, sleep, etc.) and wait a few minutes for sync.")
                    )
                }
                val apiReadings = readings.map { r ->
                    mapOf<String, Any>(
                        "metric" to r.metric,
                        "value" to r.value,
                        "unit" to r.unit,
                        "date" to r.date,
                        "metricType" to r.metricType,
                        "quality" to r.quality
                    )
                }
                val deviceInfo = HealthReader.getDeviceInfo()
                HipografApi.syncReadings(token, apiReadings, deviceInfo)
            }

            result.fold(
                onSuccess = { syncResp ->
                    binding.tvStatus.text = "Synced ${syncResp.accepted} readings"

                    val prefs2 = getSharedPreferences("hipograf", MODE_PRIVATE)
                    prefs2.edit()
                        .putLong("last_sync_timestamp", System.currentTimeMillis())
                        .apply()

                    updateLastSyncLabel()
                    Toast.makeText(this@DashboardActivity, "Sync complete!", Toast.LENGTH_SHORT).show()
                },
                onFailure = { error ->
                    binding.tvStatus.text = "Sync failed: ${error.message}"
                    Toast.makeText(this@DashboardActivity, error.message, Toast.LENGTH_LONG).show()
                }
            )

            binding.btnSyncNow.isEnabled = true
            binding.btnSyncNow.text = "Sync Now"
        }
    }

    private fun updateLastSyncLabel() {
        val prefs = getSharedPreferences("hipograf", MODE_PRIVATE)
        val lastSync = prefs.getLong("last_sync_timestamp", 0L)
        if (lastSync > 0) {
            val fmt = SimpleDateFormat("MMM d, HH:mm", Locale.getDefault())
            binding.tvLastSync.text = "Last synced: ${fmt.format(Date(lastSync))}"
        } else {
            binding.tvLastSync.text = "Never synced"
        }
    }

    private fun runDiagnose() {
        binding.btnDiagnose.isEnabled = false
        binding.btnDiagnose.text = "Diagnosing..."
        lifecycleScope.launch {
            val report = withContext(Dispatchers.IO) {
                try {
                    HealthReader.diagnose(this@DashboardActivity)
                } catch (e: Exception) {
                    "Diagnose failed: ${e.message}"
                }
            }
            AlertDialog.Builder(this@DashboardActivity)
                .setTitle("Health Connect Diagnostic")
                .setMessage(report)
                .setPositiveButton("Copy") { _, _ ->
                    val cm = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                    cm.setPrimaryClip(ClipData.newPlainText("HC Diagnostic", report))
                    Toast.makeText(this@DashboardActivity, "Copied to clipboard", Toast.LENGTH_SHORT).show()
                }
                .setNegativeButton("Close", null)
                .show()
            binding.btnDiagnose.isEnabled = true
            binding.btnDiagnose.text = "Diagnose Health Connect"
        }
    }

    private fun logout() {
        val prefs = getSharedPreferences("hipograf", MODE_PRIVATE)
        prefs.edit().clear().apply()
        (application as HipografApp).cancelSyncWorker()
        startActivity(Intent(this, LoginActivity::class.java))
        finish()
    }
}
