package com.inou.clawdnode.ui

import android.Manifest
import android.app.role.RoleManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.provider.Settings
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.inou.clawdnode.ClawdNodeApp
import com.inou.clawdnode.databinding.ActivityMainBinding
import com.inou.clawdnode.service.NodeService

/**
 * Main setup and status activity.
 * - Configure Gateway connection
 * - Grant required permissions
 * - Show connection status
 * - View audit log
 */
class MainActivity : AppCompatActivity() {
    
    private lateinit var binding: ActivityMainBinding
    private var nodeService: NodeService? = null
    private var serviceBound = false
    
    private val serviceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            nodeService = (service as NodeService.LocalBinder).getService()
            serviceBound = true
            updateUI()
            
            nodeService?.onConnectionChange = { connected ->
                runOnUiThread { updateConnectionStatus(connected) }
            }
        }
        
        override fun onServiceDisconnected(name: ComponentName?) {
            nodeService = null
            serviceBound = false
        }
    }
    
    private val permissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        updatePermissionStatus()
    }
    
    private val callScreeningRoleLauncher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { 
        updatePermissionStatus()
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        setupUI()
        startAndBindService()
    }
    
    override fun onResume() {
        super.onResume()
        updateUI()
    }
    
    override fun onDestroy() {
        super.onDestroy()
        if (serviceBound) {
            unbindService(serviceConnection)
        }
    }
    
    private fun setupUI() {
        // Gateway configuration
        binding.btnSaveGateway.setOnClickListener {
            saveGatewayConfig()
        }
        
        // Load existing config
        val tokenStore = ClawdNodeApp.instance.tokenStore
        binding.etGatewayUrl.setText(tokenStore.gatewayUrl ?: "")
        binding.etGatewayToken.setText(tokenStore.gatewayToken ?: "")
        
        // Permission buttons
        binding.btnGrantNotifications.setOnClickListener {
            openNotificationListenerSettings()
        }
        
        binding.btnGrantCallScreening.setOnClickListener {
            requestCallScreeningRole()
        }
        
        binding.btnGrantPermissions.setOnClickListener {
            requestRuntimePermissions()
        }
        
        // Connection control
        binding.btnConnect.setOnClickListener {
            nodeService?.connect()
        }
        
        binding.btnDisconnect.setOnClickListener {
            nodeService?.disconnect()
        }
        
        // Audit log
        binding.btnViewAuditLog.setOnClickListener {
            showAuditLog()
        }
    }
    
    private fun startAndBindService() {
        // Start foreground service
        val intent = Intent(this, NodeService::class.java)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(intent)
        } else {
            startService(intent)
        }
        
        // Bind to service
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
    }
    
    private fun saveGatewayConfig() {
        val url = binding.etGatewayUrl.text.toString().trim()
        val token = binding.etGatewayToken.text.toString().trim()
        
        if (url.isEmpty() || token.isEmpty()) {
            Toast.makeText(this, "Please enter Gateway URL and token", Toast.LENGTH_SHORT).show()
            return
        }
        
        val tokenStore = ClawdNodeApp.instance.tokenStore
        tokenStore.gatewayUrl = url
        tokenStore.gatewayToken = token
        
        ClawdNodeApp.instance.auditLog.log(
            "CONFIG_SAVED",
            "Gateway configuration updated",
            mapOf("url" to url)
        )
        
        Toast.makeText(this, "Configuration saved", Toast.LENGTH_SHORT).show()
        
        // Reconnect with new config
        nodeService?.disconnect()
        nodeService?.connect()
    }
    
    private fun updateUI() {
        updatePermissionStatus()
        updateConnectionStatus(nodeService?.isConnected() ?: false)
    }
    
    private fun updateConnectionStatus(connected: Boolean) {
        binding.tvConnectionStatus.text = if (connected) {
            "✓ Connected to Gateway"
        } else {
            "✗ Disconnected"
        }
        
        binding.tvConnectionStatus.setTextColor(
            ContextCompat.getColor(this, 
                if (connected) android.R.color.holo_green_dark 
                else android.R.color.holo_red_dark
            )
        )
    }
    
    private fun updatePermissionStatus() {
        // Notification listener
        val notificationEnabled = isNotificationListenerEnabled()
        binding.tvNotificationStatus.text = if (notificationEnabled) "✓ Granted" else "✗ Not granted"
        
        // Call screening
        val callScreeningEnabled = isCallScreeningRoleHeld()
        binding.tvCallScreeningStatus.text = if (callScreeningEnabled) "✓ Granted" else "✗ Not granted"
        
        // Runtime permissions
        val permissionsGranted = areRuntimePermissionsGranted()
        binding.tvPermissionsStatus.text = if (permissionsGranted) "✓ All granted" else "✗ Some missing"
    }
    
    // ========================================
    // PERMISSIONS
    // ========================================
    
    private fun isNotificationListenerEnabled(): Boolean {
        val flat = Settings.Secure.getString(contentResolver, "enabled_notification_listeners")
        return flat?.contains(packageName) == true
    }
    
    private fun openNotificationListenerSettings() {
        startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS))
    }
    
    private fun isCallScreeningRoleHeld(): Boolean {
        val roleManager = getSystemService(RoleManager::class.java)
        return roleManager.isRoleHeld(RoleManager.ROLE_CALL_SCREENING)
    }
    
    private fun requestCallScreeningRole() {
        val roleManager = getSystemService(RoleManager::class.java)
        if (roleManager.isRoleAvailable(RoleManager.ROLE_CALL_SCREENING)) {
            val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING)
            callScreeningRoleLauncher.launch(intent)
        } else {
            Toast.makeText(this, "Call screening not available", Toast.LENGTH_SHORT).show()
        }
    }
    
    private fun areRuntimePermissionsGranted(): Boolean {
        return REQUIRED_PERMISSIONS.all {
            ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }
    }
    
    private fun requestRuntimePermissions() {
        val missing = REQUIRED_PERMISSIONS.filter {
            ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
        }
        
        if (missing.isNotEmpty()) {
            permissionLauncher.launch(missing.toTypedArray())
        }
    }
    
    private fun showAuditLog() {
        val entries = ClawdNodeApp.instance.auditLog.getRecentEntries(50)
        val text = entries.joinToString("\n\n") { entry ->
            "${entry.timestamp}\n${entry.action}: ${entry.details}"
        }
        
        AlertDialog.Builder(this)
            .setTitle("Audit Log (last 50)")
            .setMessage(text.ifEmpty { "No entries yet" })
            .setPositiveButton("OK", null)
            .show()
    }
    
    companion object {
        private val REQUIRED_PERMISSIONS = arrayOf(
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.READ_CALL_LOG,
            Manifest.permission.ANSWER_PHONE_CALLS,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.READ_CONTACTS,
            Manifest.permission.POST_NOTIFICATIONS
        )
    }
}
