package club.clubk.ktag.apps

import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import club.clubk.ktag.apps.core.SubApp
import club.clubk.ktag.apps.core.SubAppRegistry
import club.clubk.ktag.apps.core.ui.theme.KTagGreen
import club.clubk.ktag.apps.core.ui.theme.KTagRed
import club.clubk.ktag.apps.core.ui.theme.KTagYellow
import club.clubk.ktag.apps.mqttbroker.BrokerSettingsActivity
import club.clubk.ktag.apps.mqttbroker.BrokerStatus
import club.clubk.ktag.apps.mqttbroker.MqttBrokerManager
import club.clubk.ktag.apps.sharedservices.LocationPublisher
import club.clubk.ktag.apps.sharedservices.MqttClientStatus
import club.clubk.ktag.apps.sharedservices.SharedMqttClient
import club.clubk.ktag.apps.ui.theme.KTagAppsTheme

class MainActivity : ComponentActivity() {

    private val permissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { startMqttServices() }

    override fun onDestroy() {
        super.onDestroy()
        LocationPublisher.stop()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            KTagAppsTheme {
                LauncherScreen()
            }
        }

        val permissionsToRequest = buildList {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
                ContextCompat.checkSelfPermission(this@MainActivity, Manifest.permission.POST_NOTIFICATIONS)
                    != PackageManager.PERMISSION_GRANTED
            ) {
                add(Manifest.permission.POST_NOTIFICATIONS)
            }
            if (ContextCompat.checkSelfPermission(this@MainActivity, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED
            ) {
                add(Manifest.permission.ACCESS_FINE_LOCATION)
            }
        }

        if (permissionsToRequest.isNotEmpty()) {
            permissionLauncher.launch(permissionsToRequest.toTypedArray())
        } else {
            startMqttServices()
        }
    }

    private fun startMqttServices() {
        MqttBrokerManager.startBrokerIfEnabled(this)
        SharedMqttClient.connect(this)
        LocationPublisher.start(this)
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LauncherScreen() {
    val subApps = SubAppRegistry.getAll()
    val context = LocalContext.current
    var menuExpanded by remember { mutableStateOf(false) }
    var showAboutDialog by remember { mutableStateOf(false) }
    val brokerStatus by MqttBrokerManager.status.collectAsState()
    val brokerEnabled = remember { MqttBrokerManager.isBrokerEnabled(context) }
    val clientStatus by SharedMqttClient.status.collectAsState()
    val deviceId = SharedMqttClient.currentDeviceId

    Scaffold(
        topBar = {
            Column {
                TopAppBar(
                    title = { Text("KTag Apps") },
                    actions = {
                        IconButton(onClick = { menuExpanded = true }) {
                            Icon(Icons.Default.MoreVert, contentDescription = "Menu")
                        }
                        DropdownMenu(
                            expanded = menuExpanded,
                            onDismissRequest = { menuExpanded = false }
                        ) {
                            DropdownMenuItem(
                                text = { Text("MQTT Settings") },
                                onClick = {
                                    menuExpanded = false
                                    context.startActivity(BrokerSettingsActivity.createIntent(context))
                                }
                            )
                            DropdownMenuItem(
                                text = { Text("BLE Settings") },
                                onClick = {
                                    menuExpanded = false
                                    context.startActivity(BleSettingsActivity.createIntent(context))
                                }
                            )
                            DropdownMenuItem(
                                text = { Text("About") },
                                onClick = {
                                    menuExpanded = false
                                    showAboutDialog = true
                                }
                            )
                        }
                    }
                )
                if (brokerEnabled) {
                    BrokerStatusBar(brokerStatus)
                }
                ClientStatusBar(clientStatus, deviceId)
            }
        }
    ) { padding ->
        if (showAboutDialog) {
            AboutDialog(onDismiss = { showAboutDialog = false })
        }

        LazyVerticalGrid(
            columns = GridCells.Adaptive(minSize = 100.dp),
            modifier = Modifier
                .fillMaxSize()
                .padding(padding),
            contentPadding = PaddingValues(16.dp),
            horizontalArrangement = Arrangement.spacedBy(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            items(subApps) { subApp ->
                SubAppItem(subApp)
            }
        }
    }
}

@Composable
fun AboutDialog(onDismiss: () -> Unit) {
    AlertDialog(
        onDismissRequest = onDismiss,
        title = { Text("KTag Apps") },
        text = {
            Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                Text("Version  ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})")
                Text("Commit   ${BuildConfig.GIT_HASH}")
                Text("Built    ${BuildConfig.BUILD_TIME}")
                Text("Type     ${BuildConfig.BUILD_TYPE}")
            }
        },
        confirmButton = {
            TextButton(onClick = onDismiss) { Text("OK") }
        }
    )
}

@Composable
fun BrokerStatusBar(status: BrokerStatus) {
    val context = LocalContext.current

    val (dotColor, statusText) = when (status) {
        is BrokerStatus.Starting -> KTagYellow to "MQTT Broker starting\u2026"
        is BrokerStatus.Running -> {
            val ip = MqttBrokerManager.getDeviceIpAddress(context) ?: "no network"
            val ports = if (status.sslPort != null) {
                "$ip:${status.port} / SSL :${status.sslPort}"
            } else {
                "$ip:${status.port}"
            }
            KTagGreen to "MQTT Broker running \u00b7 $ports"
        }
        is BrokerStatus.Error -> KTagRed to "MQTT Broker error: ${status.message}"
        is BrokerStatus.Stopped -> KTagRed to "MQTT Broker stopped"
    }

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(MaterialTheme.colorScheme.surfaceVariant)
            .padding(horizontal = 16.dp, vertical = 8.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        Box(
            modifier = Modifier
                .size(8.dp)
                .clip(CircleShape)
                .background(dotColor)
        )
        Text(
            text = statusText,
            style = MaterialTheme.typography.bodySmall,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )
    }
}

@Composable
fun ClientStatusBar(status: MqttClientStatus, deviceId: String) {
    val (dotColor, statusText) = when (status) {
        is MqttClientStatus.Connecting -> KTagYellow to "MQTT Client connecting\u2026"
        is MqttClientStatus.Connected -> KTagGreen to "MQTT Client connected as $deviceId"
        is MqttClientStatus.Error -> KTagRed to "MQTT Client error: ${status.message}"
        is MqttClientStatus.Disconnected -> KTagRed to "MQTT Client disconnected"
    }

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(MaterialTheme.colorScheme.surfaceVariant)
            .padding(horizontal = 16.dp, vertical = 8.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        Box(
            modifier = Modifier
                .size(8.dp)
                .clip(CircleShape)
                .background(dotColor)
        )
        Text(
            text = statusText,
            style = MaterialTheme.typography.bodySmall,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )
    }
}

@Composable
fun SubAppItem(subApp: SubApp) {
    val context = LocalContext.current
    Column(
        modifier = Modifier
            .clickable { context.startActivity(subApp.createIntent(context)) }
            .padding(8.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Image(
            painter = painterResource(id = subApp.icon),
            contentDescription = subApp.name,
            modifier = Modifier.size(48.dp)
        )
        Text(
            text = subApp.name,
            style = MaterialTheme.typography.bodySmall,
            textAlign = TextAlign.Center,
            modifier = Modifier.padding(top = 4.dp)
        )
    }
}
