package com.example.variableaxlemonitor

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.bluetooth.BluetoothDevice
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.core.*
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Canvas
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.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.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
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.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
import kotlin.math.cos
import kotlin.math.sin

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                listOf(
                    Manifest.permission.BLUETOOTH_SCAN,
                    Manifest.permission.BLUETOOTH_CONNECT
                )
            } else {
                listOf(
                    Manifest.permission.BLUETOOTH,
                    Manifest.permission.BLUETOOTH_ADMIN,
                    Manifest.permission.ACCESS_FINE_LOCATION
                )
            }

            val launcher = rememberLauncherForActivityResult(
                ActivityResultContracts.RequestMultiplePermissions()
            ) { results ->
                if (results.values.all { it }) {
                    Log.d("MainActivity", "All permissions granted")
                } else {
                    Toast.makeText(this, "블루투스 권한이 필요합니다.", Toast.LENGTH_SHORT).show()
                }
            }

            LaunchedEffect(Unit) {
                launcher.launch(permissions.toTypedArray())
            }

            VariableAxleMonitorTheme {
                MainApp()
            }
        }
    }
}

@Composable
fun MainApp() {
    val navController = rememberNavController()
    val viewModel: AxleViewModel = viewModel()
    
    NavHost(navController = navController, startDestination = "splash") {
        composable("splash") {
            SplashScreen(navController)
        }
        composable("login") {
            LoginScreen(navController, viewModel)
        }
        composable("monitoring") {
            MonitoringScreen(viewModel)
        }
    }
}

@Composable
fun SplashScreen(navController: NavController) {
    LaunchedEffect(Unit) {
        delay(2000) // 2초 대기
        navController.navigate("login") {
            popUpTo("splash") { inclusive = true }
        }
    }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White),
        contentAlignment = Alignment.Center
    ) {
        Image(
            painter = painterResource(id = R.drawable.variable_axle_load_loading),
            contentDescription = "App Title",
            modifier = Modifier.fillMaxWidth(0.8f)
        )
    }
}

@Composable
fun LoginScreen(navController: NavController, viewModel: AxleViewModel) {
    var user by remember { mutableStateOf("") }
    var pass by remember { mutableStateOf("") }
    val loginSuccess by viewModel.loginSuccess
    
    LaunchedEffect(loginSuccess) {
        if (loginSuccess) {
            navController.navigate("monitoring") {
                popUpTo("login") { inclusive = true }
            }
        }
    }
    
    val context = LocalContext.current
    LaunchedEffect(Unit) {
        viewModel.loginError.collect { error ->
            Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
        }
    }

    Column(
        modifier = Modifier.fillMaxSize().padding(16.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("Variable Axle Monitor", fontSize = 24.sp, fontWeight = FontWeight.Bold)
        Spacer(modifier = Modifier.height(32.dp))
        OutlinedTextField(
            value = user,
            onValueChange = { user = it },
            label = { Text("ID") },
            modifier = Modifier.fillMaxWidth()
        )
        Spacer(modifier = Modifier.height(16.dp))
        OutlinedTextField(
            value = pass,
            onValueChange = { pass = it },
            label = { Text("Password") },
            visualTransformation = PasswordVisualTransformation(),
            modifier = Modifier.fillMaxWidth()
        )
        Spacer(modifier = Modifier.height(32.dp))
        Button(
            onClick = { viewModel.login(user, pass) },
            modifier = Modifier.fillMaxWidth().height(56.dp)
        ) {
            Text("Login")
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MonitoringScreen(viewModel: AxleViewModel) {
    val axleData by viewModel.axleData.collectAsState()
    val isConnected by viewModel.isConnected.collectAsState()
    val dataTrigger = viewModel.dataReceivedTrigger
    var showDeviceDialog by remember { mutableStateOf(false) }
    val lastUpdate by remember(axleData.timestamp) {
        derivedStateOf {
            if (axleData.timestamp == 0L) "--:--:--"
            else SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(Date(axleData.timestamp))
        }
    }
    var isBlinking by remember { mutableStateOf(false) }
    
    LaunchedEffect(dataTrigger) {
        dataTrigger.collect {
            isBlinking = true
            delay(200)
            isBlinking = false
        }
    }

    val context = LocalContext.current

    Scaffold(
        topBar = {
            CenterAlignedTopAppBar(
                title = { 
                    Text(
                        text = "가변축 모니터링",
                        fontSize = 32.sp,
                        fontWeight = FontWeight.Bold
                    ) 
                },
                actions = {
                    Box(
                        modifier = Modifier
                            .size(32.dp)
                            .clip(CircleShape)
                            .background(if (isBlinking) Color.Green else Color.LightGray.copy(alpha = 0.3f))
                    )
                    Spacer(modifier = Modifier.width(8.dp))
                    IconButton(
                        onClick = { showDeviceDialog = true },
                        modifier = Modifier.size(64.dp)
                    ) {
                        Icon(
                            imageVector = Icons.Default.Bluetooth,
                            contentDescription = "Bluetooth Status",
                            tint = if (isConnected) Color.Green else Color.Red,
                            modifier = Modifier.size(48.dp)
                        )
                    }
                    IconButton(
                        onClick = { 
                            viewModel.disconnect()
                            (context as? Activity)?.finishAffinity() 
                        },
                        modifier = Modifier.size(64.dp)
                    ) {
                        Icon(
                            imageVector = Icons.Default.ExitToApp,
                            contentDescription = "Exit App",
                            tint = MaterialTheme.colorScheme.error,
                            modifier = Modifier.size(48.dp)
                        )
                    }
                }
            )
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize()
                .padding(8.dp)
        ) {
            Column(modifier = Modifier.weight(1f)) {
                // Row 1: 압력센서, 속도
                Row(modifier = Modifier.weight(1f)) {
                    MonitoringCard(
                        title = "압력 센서",
                        value = String.format(Locale.US, "%.1f kgf/cm²", axleData.pressure * 0.1f),
                        iconRes = R.drawable.pressure_sensor_gauge,
                        isBitmap = true,
                        iconSize = 150.dp,
                        modifier = Modifier.weight(1f),
                        customIcon = { PressureGauge(pressure = axleData.pressure * 0.1f) }
                    )
                    MonitoringCard(
                        title = "속도(Speed)",
                        value = "${axleData.speed} km/h",
                        iconRes = R.drawable.speed_display,
                        isBitmap = true,
                        modifier = Modifier.weight(1f),
                        customIcon = { SpeedGauge(speed = axleData.speed) }
                    )
                }
                
                // Row 2: 가변축 하중, 구동축 하중
                Row(modifier = Modifier.weight(1f)) {
                    MonitoringCard(
                        title = "가변축 하중",
                        value = String.format(Locale.US, "%.3f ton", axleData.variableAxleLoad * 0.001f),
                        iconRes = R.drawable.axle_load_variable,
                        isBitmap = true,
                        iconSize = 200.dp,
                        modifier = Modifier.weight(1f)
                    )
                    MonitoringCard(
                        title = "구동축 하중",
                        value = String.format(Locale.US, "%.3f ton", axleData.driveAxleLoad * 0.001f),
                        iconRes = R.drawable.axle_load_driver,
                        isBitmap = true,
                        iconSize = 200.dp,
                        modifier = Modifier.weight(1f)
                    )
                }
                
                // Row 3: 가변축 상태, 하중분배율
                Row(modifier = Modifier.weight(1f)) {
                    MonitoringCard(
                        title = "가변축 상태",
                        value = if (axleData.isDown) "가변축 Down" else "가변축 Up",
                        iconRes = if (axleData.isDown) R.drawable.axle_down else R.drawable.axle_up,
                        isBitmap = true,
                        iconSize = 200.dp,
                        modifier = Modifier.weight(1f)
                    )
                    val distributionRatio = if (axleData.driveAxleLoad + axleData.variableAxleLoad > 0) {
                        (axleData.variableAxleLoad.toFloat() / (axleData.driveAxleLoad.toFloat()+axleData.variableAxleLoad.toFloat()) * 100f)
                    } else 0f
                    
                    MonitoringCard(
                        title = "가변축 하중 분배율",
                        value = String.format(Locale.US, "%.1f %%", distributionRatio),
                        iconRes = when {
                            distributionRatio < 50f -> R.drawable.load_sharing_ratio_d50
                            distributionRatio == 50f -> R.drawable.load_sharing_ratio_50
                            else -> R.drawable.load_sharing_ratio_u50
                        },
                        isBitmap = true,
                        iconSize = 300.dp,
                        modifier = Modifier.weight(1f)
                    )
                }
            }
            
            Spacer(modifier = Modifier.height(8.dp))
            Text(
                text = "마지막 데이터 수신: $lastUpdate",
                modifier = Modifier.align(Alignment.End),
                fontSize = 11.sp,
                color = Color.Gray
            )
        }
    }

    if (showDeviceDialog) {
        LaunchedEffect(Unit) {
            viewModel.startScan()
        }
        
        val foundDevices by viewModel.foundDevices.collectAsState()
        BluetoothDeviceDialog(
            devices = foundDevices,
            onDeviceSelected = { device ->
                viewModel.stopScan()
                viewModel.connectToDevice(device)
                showDeviceDialog = false
            },
            onDismiss = { 
                viewModel.stopScan()
                showDeviceDialog = false 
            }
        )
    }
}

@Composable
fun PressureGauge(
    pressure: Float,
    modifier: Modifier = Modifier
) {
    val maxPressure = 12f
    // 사용자의 요청에 따라 0은 135도, 12은 -135도로 설정
    val startAngle = 136f   //135f
    val sweepAngle = 270f   //270f
    
    val animatedPressure by animateFloatAsState(
        targetValue = pressure.coerceIn(0f, maxPressure),
        animationSpec = tween(durationMillis = 500),
        label = "PressureNeedle"
    )

    Box(
        modifier = modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Box(
            modifier = Modifier
                .fillMaxSize(0.6f) // 게이지 이미지를 부모 영역의 80%로 제한
                .aspectRatio(1f),
            contentAlignment = Alignment.Center
        ) {
            Image(
                painter = painterResource(id = R.drawable.pressure_sensor_gauge),
                contentDescription = null,
                modifier = Modifier.fillMaxSize()
            )

            val angleDeg = startAngle + (animatedPressure / maxPressure) * sweepAngle

            Image(
                painter = painterResource(id = R.drawable.pressure_arrow2),
                contentDescription = "Pressure Needle",
                modifier = Modifier
                    .fillMaxSize(0.7f)  //0.7
                    .graphicsLayer(
                        rotationZ = angleDeg + 90f,
                        transformOrigin = TransformOrigin(0.5f, 0.5f)
                    )
            )
        }
    }
}

@Composable
fun SpeedGauge(
    speed: Int,
    modifier: Modifier = Modifier
) {
    val maxSpeed = 160f
    // 사용자의 피드백에 따라 수평 왼쪽(180도)을 0으로, 수평 오른쪽(0도)을 160으로 설정
    val startAngle = 180f 
    val sweepAngle = 180f
    
    val animatedSpeed by animateFloatAsState(
        targetValue = speed.coerceIn(0, maxSpeed.toInt()).toFloat(),
        animationSpec = tween(durationMillis = 500),
        label = "SpeedNeedle"
    )

    Box(
        modifier = modifier
            .aspectRatio(1f)
            .fillMaxSize(0.8f), // 전체 사이즈 0.8배 축소
        contentAlignment = Alignment.Center
    ) {
        Image(
            painter = painterResource(id = R.drawable.speed_display),
            contentDescription = null,
            modifier = Modifier.fillMaxSize()
        )

        Canvas(modifier = Modifier.fillMaxSize()) {
            // 바늘의 회전 중심축 위치를 사용자가 확인한 0.7f 지점으로 고정
            val center = Offset(size.width / 2, size.height * 0.72f)
            val radius = size.minDimension / 2
            
            // 시계 방향으로 회전하므로 각도 계산
            val angleDeg = startAngle + (animatedSpeed / maxSpeed) * sweepAngle
            val angleRad = Math.toRadians(angleDeg.toDouble())
            
            // 바늘의 길이 (게이지 크기에 맞춰 조정)
            val needleLength = radius * 0.8f
            
            // 바늘(화살표) 그리기 - 삼각형 형태
            val needlePath = androidx.compose.ui.graphics.Path().apply {
                val endX = center.x + needleLength * cos(angleRad).toFloat()
                val endY = center.y + needleLength * sin(angleRad).toFloat()
                
                // 바늘 뿌리 부분의 각도 (바늘 방향과 수직)
                val baseAngleRad = Math.toRadians((angleDeg + 90).toDouble())
                val baseWidth = 8.dp.toPx() // 뿌리 너비
                
                val baseLeftX = center.x + baseWidth * cos(baseAngleRad).toFloat()
                val baseLeftY = center.y + baseWidth * sin(baseAngleRad).toFloat()
                
                val baseRightX = center.x - baseWidth * cos(baseAngleRad).toFloat()
                val baseRightY = center.y - baseWidth * sin(baseAngleRad).toFloat()
                
                moveTo(baseLeftX, baseLeftY)
                lineTo(endX, endY)
                lineTo(baseRightX, baseRightY)
                close()
            }
            
            // 바늘 그림자
            drawPath(
                path = needlePath,
                color = Color.Black.copy(alpha = 0.2f),
                style = androidx.compose.ui.graphics.drawscope.Fill
            )
            
            // 바늘 본체 (빨간색)
            drawPath(
                path = needlePath,
                color = Color.Red,
                style = androidx.compose.ui.graphics.drawscope.Fill
            )
            
            // 중앙 검은 점(캡) 그리기
            drawCircle(
                color = Color.DarkGray,
                radius = 10.dp.toPx(),
                center = center
            )
            drawCircle(
                color = Color.Black,
                radius = 6.dp.toPx(),
                center = center
            )
        }
    }
}

@Composable
fun MonitoringCard(
    modifier: Modifier = Modifier.fillMaxSize(),
    title: String,
    value: String,
    iconRes: Int = 0,
    isBitmap: Boolean = false,
    iconSize: Dp = 200.dp,
    titleFontSize: TextUnit = 32.sp,
    valueFontSize: TextUnit = 26.sp,
    titleModifier: Modifier = Modifier,
    valueModifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier,
    titlePaddingTop: Dp = 24.dp,
    contentSpacing: Dp = 14.dp,
    customIcon: @Composable (() -> Unit)? = null
) {
    Card(
        modifier = modifier.padding(4.dp),
        shape = RoundedCornerShape(12.dp),
        colors = CardDefaults.cardColors(containerColor = Color.White),
        border = BorderStroke(1.dp, Color.LightGray)
    ) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(bottom = 8.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Spacer(modifier = Modifier.height(titlePaddingTop))
            Text(
                text = title, 
                fontSize = titleFontSize, 
                fontWeight = FontWeight.Bold,
                color = Color(0xFF444444),
                modifier = titleModifier
            )
            Spacer(modifier = Modifier.height(contentSpacing))
            Text(
                text = value, 
                fontSize = valueFontSize, 
                fontWeight = FontWeight.ExtraBold, 
                color = Color.Blue,
                modifier = valueModifier
            )
            Box(
                modifier = Modifier.weight(1f).fillMaxWidth(),
                contentAlignment = Alignment.Center
            ) {
                if (customIcon != null) {
                    customIcon()
                } else if (iconRes != 0) {
                    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
                        )
                    }
                }
            }
        }
    }
}

@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 ?: "알 수 없는 기기"
                        Text(
                            text = deviceName,
                            modifier = Modifier
                                .fillMaxWidth()
                                .clickable { onDeviceSelected(device) }
                                .padding(vertical = 12.dp),
                            fontSize = 16.sp
                        )
                        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("취소")
                }
            }
        }
    }
}
