package com.nexlab.openclaw.node.ui

import android.accessibilityservice.AccessibilityServiceInfo
import android.content.Context
import android.content.Intent
import android.provider.Settings
import android.util.Log
import android.view.accessibility.AccessibilityManager
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import com.nexlab.openclaw.node.data.repository.SettingsRepository
import com.nexlab.openclaw.node.service.NodeService
import com.nexlab.openclaw.node.service.TouchService
import com.nexlab.openclaw.node.ui.theme.OpenClawAndroidNodeTheme
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import javax.inject.Inject

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    @Inject
    lateinit var settingsRepository: SettingsRepository

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        setContent {
            OpenClawAndroidNodeTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    MainScreen(
                        settingsRepository = settingsRepository,
                        onStartService = { protocol, ip, port, token, nodeId -> startNodeService(protocol, ip, port, token, nodeId) },
                        onStopService = { stopNodeService() },
                        onOpenAccessibilitySettings = { openAccessibilitySettings() },
                        onOpenNotificationSettings = { openNotificationSettings() }
                    )
                }
            }
        }
    }

    private fun startNodeService(protocol: String, ip: String, port: String, token: String, nodeId: String) {
        // Debug write
        try {
            val debugFile = java.io.File(cacheDir, "mainactivity_debug.txt")
            debugFile.writeText("startNodeService at ${System.currentTimeMillis()}\n")
        } catch (e: Exception) {}
        
        // Also save to SharedPreferences for NodeService fallback
        try {
            val prefs = getSharedPreferences("openclaw_settings", MODE_PRIVATE)
            prefs.edit()
                .putString("gateway_protocol", protocol)
                .putString("gateway_ip", ip)
                .putString("gateway_port", port)
                .putString("node_token", token)
                .putString("node_id", nodeId)
                .apply()
        } catch (e: Exception) {}
        
        android.widget.Toast.makeText(this, "Starting: $ip:$port", android.widget.Toast.LENGTH_LONG).show()
        val intent = Intent(this, NodeService::class.java).apply {
            action = "START"
            putExtra("gateway_protocol", protocol)
            putExtra("gateway_ip", ip)
            putExtra("gateway_port", port)
            putExtra("node_token", token)
            putExtra("node_id", nodeId)
        }
        startForegroundService(intent)
    }

    private fun stopNodeService() {
        val intent = Intent(this, NodeService::class.java).apply {
            action = "STOP"
        }
        startService(intent)
    }

    private fun openAccessibilitySettings() {
        startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
    }

    private fun openNotificationSettings() {
        startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS))
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(
    settingsRepository: com.nexlab.openclaw.node.data.repository.SettingsRepository,
    onStartService: (String, String, String, String, String) -> Unit,
    onStopService: () -> Unit,
    onOpenAccessibilitySettings: () -> Unit,
    onOpenNotificationSettings: () -> Unit
) {
    var protocol by remember { mutableStateOf("WS") }
    var ipAddress by remember { mutableStateOf("") }
    var port by remember { mutableStateOf("18789") }
    var nodeToken by remember { mutableStateOf("") }
    var nodeId by remember { mutableStateOf("") }
    var isConnected by remember { mutableStateOf(false) }
    var statusMessage by remember { mutableStateOf("Not connected") }
    
    val context = LocalContext.current
    val scope = rememberCoroutineScope()
    
    // Load settings from DataStore on first composition
    LaunchedEffect(Unit) {
        try {
            settingsRepository.gatewayProtocol.first().let { if (it.isNotBlank()) protocol = it }
            settingsRepository.gatewayIp.first().let { if (it.isNotBlank()) ipAddress = it }
            settingsRepository.gatewayPort.first().let { if (it.isNotBlank()) port = it }
            settingsRepository.nodeToken.first().let { 
                if (it.isNotBlank()) nodeToken = it 
            }
            settingsRepository.nodeId.first().let { if (it.isNotBlank()) nodeId = it }
            
            // Save to SharedPreferences for NodeService fallback
            try {
                val prefs = context.getSharedPreferences("openclaw_settings", Context.MODE_PRIVATE)
                prefs.edit()
                    .putString("gateway_protocol", protocol)
                    .putString("gateway_ip", ipAddress)
                    .putString("gateway_port", port)
                    .putString("node_token", nodeToken)
                    .putString("node_id", nodeId)
                    .apply()
            } catch (e: Exception) {}
            
            // Auto-start service immediately if settings exist
            if (ipAddress.isNotBlank() && port.isNotBlank() && nodeToken.isNotBlank()) {
                statusMessage = "Auto-connecting..."
                onStartService(protocol, ipAddress, port, nodeToken, nodeId)
                isConnected = true
            } else {
                statusMessage = "Ready to connect"
            }
        } catch (e: Exception) {
            statusMessage = "Error loading settings"
        }
    }
    
    // Check accessibility status
    val accessibilityEnabled = remember {
        val am = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
        val service = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC)
        service.any { it.id.contains("com.nexlab.openclaw.node") }
    }

    // Build full URL from parts
    val fullUrl = if (protocol == "WSS") "wss://$ipAddress:$port/node" else "ws://$ipAddress:$port/node"

    // Load saved settings on start
    LaunchedEffect(Unit) {
        settingsRepository.gatewayProtocol.collect { protocol = it }
    }
    LaunchedEffect(Unit) {
        settingsRepository.gatewayIp.collect { ipAddress = it }
    }
    LaunchedEffect(Unit) {
        settingsRepository.gatewayPort.collect { port = it }
    }
    LaunchedEffect(Unit) {
        settingsRepository.nodeToken.collect { nodeToken = it }
    }
    LaunchedEffect(Unit) {
        settingsRepository.nodeId.collect { nodeId = it }
    }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
            .verticalScroll(rememberScrollState()),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ) {
        Text(
            text = "OpenClaw Android Node",
            style = MaterialTheme.typography.headlineMedium
        )
        
        Text(
            text = "Control your Android device remotely",
            style = MaterialTheme.typography.bodyMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )

        Spacer(modifier = Modifier.height(8.dp))

        // Connection Card
        Card(
            modifier = Modifier.fillMaxWidth()
        ) {
            Column(
                modifier = Modifier.padding(16.dp),
                verticalArrangement = Arrangement.spacedBy(12.dp)
            ) {
                Text(
                    text = "Gateway Connection",
                    style = MaterialTheme.typography.titleMedium
                )

                // Protocol selector
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.spacedBy(8.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(
                        text = "Protocol:",
                        style = MaterialTheme.typography.bodyMedium,
                        modifier = Modifier.width(70.dp)
                    )
                    Row(
                        horizontalArrangement = Arrangement.spacedBy(8.dp)
                    ) {
                        FilterChip(
                            selected = protocol == "WS",
                            onClick = { protocol = "WS" },
                            label = { Text("WS") },
                            enabled = !isConnected
                        )
                        FilterChip(
                            selected = protocol == "WSS",
                            onClick = { protocol = "WSS" },
                            label = { Text("WSS") },
                            enabled = !isConnected
                        )
                    }
                }

                // IP Address
                OutlinedTextField(
                    value = ipAddress,
                    onValueChange = { ipAddress = it },
                    label = { Text("IP Address") },
                    placeholder = { Text("192.168.1.100") },
                    modifier = Modifier.fillMaxWidth(),
                    enabled = !isConnected,
                    singleLine = true
                )

                // Port
                OutlinedTextField(
                    value = port,
                    onValueChange = { port = it },
                    label = { Text("Port") },
                    placeholder = { Text("18789") },
                    modifier = Modifier.fillMaxWidth(),
                    enabled = !isConnected,
                    singleLine = true
                )

                OutlinedTextField(
                    value = nodeToken,
                    onValueChange = { nodeToken = it },
                    label = { Text("Auth Token") },
                    placeholder = { Text("Enter your auth token") },
                    modifier = Modifier.fillMaxWidth(),
                    enabled = !isConnected,
                    singleLine = true
                )

                OutlinedTextField(
                    value = nodeId,
                    onValueChange = { nodeId = it },
                    label = { Text("Node ID (optional)") },
                    placeholder = { Text("android_device_1") },
                    modifier = Modifier.fillMaxWidth(),
                    enabled = !isConnected,
                    singleLine = true
                )

                Button(
                    onClick = {
                        Log.e("MainActivity", "Connect clicked! ip=$ipAddress port=$port tokenPresent=${nodeToken.isNotBlank()}")
                        if (isConnected) {
                            onStopService()
                            isConnected = false
                            statusMessage = "Disconnected"
                        } else {
                            Log.e("MainActivity", "Values check: ipBlank=${ipAddress.isBlank()} portBlank=${port.isBlank()} tokenBlank=${nodeToken.isBlank()}")
                            if (ipAddress.isNotBlank() && port.isNotBlank() && nodeToken.isNotBlank()) {
                                // Start service with settings directly
                                onStartService(protocol, ipAddress, port, nodeToken, nodeId)
                                isConnected = true
                                statusMessage = "Connecting to $fullUrl..."
                            } else {
                                statusMessage = "Please enter IP, port and token"
                            }
                        }
                    },
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Text(if (isConnected) "Disconnect" else "Connect")
                }

                Text(
                    text = statusMessage,
                    style = MaterialTheme.typography.bodyMedium,
                    color = if (isConnected) MaterialTheme.colorScheme.primary 
                           else MaterialTheme.colorScheme.onSurfaceVariant
                )
            }
        }

        // Permissions Card
        Card(
            modifier = Modifier.fillMaxWidth()
        ) {
            Column(
                modifier = Modifier.padding(16.dp),
                verticalArrangement = Arrangement.spacedBy(12.dp)
            ) {
                Text(
                    text = "Required Permissions",
                    style = MaterialTheme.typography.titleMedium
                )

                PermissionRow(
                    name = "Accessibility",
                    description = "For touch gestures (tap, swipe)",
                    isEnabled = accessibilityEnabled,
                    onClick = onOpenAccessibilitySettings
                )

                Divider()

                PermissionRow(
                    name = "Notification Access",
                    description = "To mirror notifications",
                    isEnabled = false, // Would check notification listener
                    onClick = onOpenNotificationSettings
                )
            }
        }

        // Features Card
        Card(
            modifier = Modifier.fillMaxWidth()
        ) {
            Column(
                modifier = Modifier.padding(16.dp),
                verticalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                Text(
                    text = "Features",
                    style = MaterialTheme.typography.titleMedium
                )
                
                FeatureItem("📸 Screenshot capture")
                FeatureItem("👆 Touch control (tap, swipe, long press)")
                FeatureItem("🚀 Launch apps")
                FeatureItem("🔔 Notification mirroring")
                FeatureItem("📱 Device info")
            }
        }
        
        // Help text
        Text(
            text = "Enter Gateway IP, port, and token. For local network use WS. WSS requires TLS setup.",
            style = MaterialTheme.typography.bodySmall,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )
    }
}

@Composable
fun PermissionRow(
    name: String,
    description: String,
    isEnabled: Boolean,
    onClick: () -> Unit
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Column(modifier = Modifier.weight(1f)) {
            Text(
                text = name,
                style = MaterialTheme.typography.bodyLarge
            )
            Text(
                text = description,
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
        }
        
        Button(
            onClick = onClick,
            colors = ButtonDefaults.buttonColors(
                containerColor = if (isEnabled) MaterialTheme.colorScheme.primary 
                                else MaterialTheme.colorScheme.secondary
            )
        ) {
            Text(if (isEnabled) "Enabled" else "Enable")
        }
    }
}

@Composable
fun FeatureItem(text: String) {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        Text(
            text = text,
            style = MaterialTheme.typography.bodyMedium
        )
    }
}
