package com.example.variableaxlemonitor

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.bluetooth.BluetoothDevice
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bluetooth
import androidx.compose.material.icons.filled.ExitToApp
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.window.Dialog
import androidx.core.content.ContextCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.variableaxlemonitor.ui.theme.VariableAxleMonitorTheme
import com.example.variableaxlemonitor.viewmodel.AxleViewModel
import kotlinx.coroutines.delay

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            VariableAxleMonitorTheme {
                MainApp()
            }
        }
    }
}

@Composable
fun MainApp() {
    val navController = rememberNavController()
    val viewModel: AxleViewModel = viewModel()
    val context = LocalContext.current

    val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        arrayOf(
            Manifest.permission.BLUETOOTH_SCAN,
            Manifest.permission.BLUETOOTH_CONNECT,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    } else {
        arrayOf(
            Manifest.permission.BLUETOOTH,
            Manifest.permission.BLUETOOTH_ADMIN,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    }

    val launcher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.RequestMultiplePermissions()
    ) { results ->
        if (results.values.all { it }) {
            // Permissions granted
        } else {
            Toast.makeText(context, "Permissions required for Bluetooth", Toast.LENGTH_SHORT).show()
        }
    }

    LaunchedEffect(Unit) {
        val missing = permissions.filter {
            ContextCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED
        }
        if (missing.isNotEmpty()) {
            launcher.launch(missing.toTypedArray())
        }
    }

    NavHost(navController = navController, startDestination = "login") {
        composable("login") {
            LoginScreen(navController, viewModel)
        }
        composable("monitoring") {
            MonitoringScreen(viewModel)
        }
    }
}

@Composable
fun LoginScreen(navController: NavController, viewModel: AxleViewModel) {
    var user by remember { mutableStateOf("") }
    var pass by remember { mutableStateOf("") }
    val context = LocalContext.current
    val loginSuccess by viewModel.loginSuccess

    LaunchedEffect(loginSuccess) {
        if (loginSuccess) {
            navController.navigate("monitoring")
        }
    }

    LaunchedEffect(Unit) {
        viewModel.loginError.collect { error ->
            Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
        }
    }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text("가변축 시스템", fontSize = 32.sp, fontWeight = FontWeight.Bold)
        Spacer(modifier = Modifier.height(32.dp))
        OutlinedTextField(
            value = user,
            onValueChange = { user = it },
            label = { Text("User") },
            modifier = Modifier.fillMaxWidth()
        )
        OutlinedTextField(
            value = pass,
            onValueChange = { pass = it },
            label = { Text("Password") },
            visualTransformation = PasswordVisualTransformation(),
            modifier = Modifier.fillMaxWidth()
        )
        Spacer(modifier = Modifier.height(16.dp))
        Button(
            onClick = { viewModel.login(user, pass) },
            modifier = Modifier.fillMaxWidth()
        ) {
            Text("로그인")
        }
        Spacer(modifier = Modifier.height(8.dp))
        TextButton(
            onClick = { (context as? Activity)?.finishAffinity() },
            modifier = Modifier.fillMaxWidth()
        ) {
            Text("앱 종료")
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("DefaultLocale")
@Composable
fun MonitoringScreen(viewModel: AxleViewModel) {
    val axleData by viewModel.axleData.collectAsState()
    val isConnected by viewModel.isConnected.collectAsState()
    var showDeviceDialog by remember { mutableStateOf(false) }
    val context = LocalContext.current
    var lastUpdate by remember { mutableStateOf("-") }
    var receiveCount by remember { mutableIntStateOf(0) }
    val timeFormatter = remember { SimpleDateFormat("HH:mm:ss", Locale.getDefault()) }

    LaunchedEffect(viewModel) {
        Log.d("MonitoringScreen", "ViewModel Instance: ${System.identityHashCode(viewModel)}")
    }

    LaunchedEffect(Unit) {
        viewModel.dataReceivedTrigger.collect {
            receiveCount++
            lastUpdate = timeFormatter.format(Date())
            Log.d("MonitoringScreen", "Data Received Trigger #$receiveCount at $lastUpdate")
        }
    }

    LaunchedEffect(axleData) {
        Log.d("MonitoringScreen", "UI Update: $axleData")
    }

    Scaffold(
        topBar = {
            CenterAlignedTopAppBar(
                title = { 
                    Text("가변축 시스템 모니터링", fontSize = 32.sp, fontWeight = FontWeight.Bold)
                },
                actions = {
                    IconButton(onClick = { showDeviceDialog = true }) {
                        Icon(
                            imageVector = Icons.Default.Bluetooth,
                            contentDescription = "Bluetooth Status",
                            tint = if (isConnected) Color.Green else Color.Red
                        )
                    }
                }
            )
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .padding(8.dp)
        ) {
            LazyVerticalGrid(
                columns = GridCells.Fixed(2),
                modifier = Modifier.weight(1f),
                contentPadding = PaddingValues(4.dp),
                verticalArrangement = Arrangement.spacedBy(4.dp),
                horizontalArrangement = Arrangement.spacedBy(4.dp)
            ) {
                // 1. 압력센서
                item {
                    MonitoringCard(
                        title = "압력 센서",
                        value = String.format(Locale.US, "%.1f kgf/cm²", axleData.pressure * 0.1f),
                        iconRes = R.drawable.pressure_sensor,
                        isBitmap = true
                    )
                }
                // 2. 속도
                item {
                    MonitoringCard(
                        title = "속도(Speed)",
                        value = "${axleData.speed} km/h",
                        iconRes = R.drawable.speed_display,
                        isBitmap = true
                    )
                }
                // 3. 가변축 하중
                item {
                    MonitoringCard(
                        title = "가변축 하중",
                        value = String.format(Locale.US, "%.3f ton", axleData.variableAxleLoad * 0.001f),
                        iconRes = R.drawable.variable_axle_load,
                        isBitmap = true,
                        iconSize = 60.dp
                    )
                }
                // 4. 구동축 하중
                item {
                    MonitoringCard(
                        title = "구동축 하중",
                        value = String.format(Locale.US, "%.3f ton", axleData.driveAxleLoad * 0.001f),
                        iconRes = R.drawable.ic_axle_drive
                    )
                }
                // 5. 가변축 상태
                item {
                    MonitoringCard(
                        title = "가변축 상태",
                        value = if (axleData.isDown) "가변축 Down" else "가변축 Up",
                        iconRes = if (axleData.isDown) R.drawable.ic_axle_down else R.drawable.ic_axle_up
                    )
                }
                // 6. 설정 및 종료
                item {
                    SystemCard(
                        isConnected = isConnected,
                        onBluetoothClick = { showDeviceDialog = true },
                        onExitClick = { 
                            viewModel.disconnect()
                            (context as? Activity)?.finishAffinity() 
                        },
                        dataTrigger = viewModel.dataReceivedTrigger,
                        modifier = Modifier.fillMaxWidth().aspectRatio(1.2f)
                    )
                }
            }
            
            Spacer(modifier = Modifier.height(8.dp))
            Text(
                text = "마지막 데이터 수신: $lastUpdate",
                modifier = Modifier.align(Alignment.End),
                fontSize = 12.sp,
                color = Color.Gray
            )
        }
    }

    if (showDeviceDialog) {
        val devices by viewModel.foundDevices.collectAsState()
        
        DisposableEffect(Unit) {
            viewModel.startScan()
            onDispose {
                viewModel.stopScan()
            }
        }

        BluetoothDeviceDialog(
            devices = devices,
            onDeviceSelected = {
                viewModel.connectToDevice(it)
                showDeviceDialog = false
            },
            onDismiss = { showDeviceDialog = false }
        )
    }
}

@Composable
fun MonitoringCard(
    title: String,
    value: String,
    iconRes: Int,
    modifier: Modifier = Modifier
        .fillMaxWidth()
        .aspectRatio(1.2f), // Slightly wider to accommodate text
    isBitmap: Boolean = false,
    iconSize: Dp = 50.dp, // Reduced default size
    titleFontSize: TextUnit = 18.sp, // Reduced font size
    valueFontSize: TextUnit = 22.sp, // Reduced font size
    titleModifier: Modifier = Modifier,
    valueModifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    Card(
        modifier = modifier,
        shape = RoundedCornerShape(12.dp),
        colors = CardDefaults.cardColors(containerColor = Color.White),
        border = BorderStroke(1.dp, Color.LightGray)
    ) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(8.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Text(
                text = title, 
                fontSize = titleFontSize, 
                fontWeight = FontWeight.Bold,
                color = Color.DarkGray,
                modifier = titleModifier
            )
            Spacer(modifier = Modifier.height(4.dp))
            if (isBitmap) {
                Image(
                    painter = painterResource(id = iconRes),
                    contentDescription = title,
                    modifier = iconModifier.size(iconSize)
                )
            } else {
                Icon(
                    painter = painterResource(id = iconRes),
                    contentDescription = title,
                    modifier = iconModifier.size(iconSize),
                    tint = MaterialTheme.colorScheme.secondary
                )
            }
            Spacer(modifier = Modifier.height(4.dp))
            Text(
                text = value, 
                fontSize = valueFontSize, 
                fontWeight = FontWeight.ExtraBold, 
                color = Color.Blue,
                modifier = valueModifier
            )
        }
    }
}

@Composable
fun SystemCard(
    isConnected: Boolean,
    onBluetoothClick: () -> Unit,
    onExitClick: () -> Unit,
    dataTrigger: kotlinx.coroutines.flow.SharedFlow<Unit>,
    modifier: Modifier = Modifier
        .fillMaxWidth()
        .aspectRatio(1f),
    topSectionModifier: Modifier = Modifier,
    bottomSectionModifier: Modifier = Modifier
) {
    var isBlinking by remember { mutableStateOf(false) }

    LaunchedEffect(Unit) {
        dataTrigger.collect {
            isBlinking = true
            delay(200)
            isBlinking = false
        }
    }

    Card(
        modifier = modifier,
        shape = RoundedCornerShape(16.dp),
        colors = CardDefaults.cardColors(containerColor = Color.White),
        border = BorderStroke(1.dp, Color.DarkGray)
    ) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(12.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.SpaceBetween
        ) {
            Row(
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.Center,
                modifier = topSectionModifier.fillMaxWidth()
            ) {
                Icon(
                    imageVector = Icons.Default.Bluetooth,
                    contentDescription = "Bluetooth",
                    modifier = Modifier
                        .size(32.dp)
                        .clickable { onBluetoothClick() },
                    tint = if (isConnected) Color.Green else Color.Red
                )
                Spacer(modifier = Modifier.width(8.dp))
                Box(
                    modifier = Modifier
                        .size(16.dp)
                        .clip(CircleShape)
                        .background(if (isBlinking) Color.Green else Color.Transparent)
                )
            }
            
            Button(
                onClick = onExitClick,
                modifier = bottomSectionModifier,
                colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)
            ) {
                Icon(Icons.Default.ExitToApp, contentDescription = null)
                Spacer(modifier = Modifier.width(4.dp))
                Text("종료")
            }
        }
    }
}

@Composable
fun BluetoothDeviceDialog(
    devices: List<BluetoothDevice>,
    onDeviceSelected: (BluetoothDevice) -> Unit,
    onDismiss: () -> Unit
) {
    Dialog(onDismissRequest = onDismiss) {
        Surface(
            shape = RoundedCornerShape(16.dp),
            color = MaterialTheme.colorScheme.surface
        ) {
            Column(modifier = Modifier.padding(16.dp)) {
                Text("블루투스 기기 선택", fontSize = 20.sp, fontWeight = FontWeight.Bold)
                Spacer(modifier = Modifier.height(16.dp))
                LazyColumn {
                    items(devices) { device ->
                        @SuppressLint("MissingPermission")
                        val deviceName = device.name ?: "알 수 없는 기기"
                        val deviceAddress = device.address
                        Column(
                            modifier = Modifier
                                .fillMaxWidth()
                                .clickable { onDeviceSelected(device) }
                                .padding(vertical = 12.dp)
                        ) {
                            Text(text = deviceName, fontSize = 16.sp, fontWeight = FontWeight.SemiBold)
                            Text(text = deviceAddress, fontSize = 12.sp, color = Color.Gray)
                        }
                        HorizontalDivider()
                    }
                }
                if (devices.isEmpty()) {
                    Text("주변 기기를 검색 중입니다...", modifier = Modifier.padding(vertical = 16.dp))
                }
                Spacer(modifier = Modifier.height(16.dp))
                TextButton(onClick = onDismiss, modifier = Modifier.align(Alignment.End)) {
                    Text("취소")
                }
            }
        }
    }
}
