package dev.adriankuta.visualizer.view

import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
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.draw.drawBehind
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dev.adriankuta.visualizer.ui.components.KeepScreenOn
import timber.log.Timber


@Composable
fun VisualizerScreen(
    modifier: Modifier = Modifier,
    viewModel: VisualizerScreenViewModel = hiltViewModel()
) {
    val context = LocalContext.current
    val lifecycleOwner = LocalLifecycleOwner.current
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()

    KeepScreenOn()

    // Permission state management
    var hasAudioPermission by remember {
        mutableStateOf(
            ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.RECORD_AUDIO
            ) == PackageManager.PERMISSION_GRANTED
        )
    }

    var showPermissionRationale by remember { mutableStateOf(false) }

    // Permission request launcher
    val permissionLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.RequestPermission()
    ) { isGranted ->
        hasAudioPermission = isGranted
        if (isGranted) {
            Timber.d("Audio permission granted, starting visualizer")
            viewModel.start()
        } else {
            Timber.w("Audio permission denied")
            showPermissionRationale = true
        }
    }

    // Function to start audio visualizer with permission check
    fun startVisualizerWithPermissionCheck() {
        when {
            hasAudioPermission -> {
                viewModel.start()
            }

            else -> {
                Timber.d("Requesting audio permission")
                permissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
            }
        }
    }

    // Handle lifecycle events
    DisposableEffect(lifecycleOwner) {
        val observer = LifecycleEventObserver { _, event ->
            when (event) {
                Lifecycle.Event.ON_START -> startVisualizerWithPermissionCheck()
                Lifecycle.Event.ON_STOP -> viewModel.stop()
                else -> {}
            }
        }

        lifecycleOwner.lifecycle.addObserver(observer)

        onDispose {
            lifecycleOwner.lifecycle.removeObserver(observer)
            viewModel.stop()
        }
    }

    Column(
        modifier = modifier
            .fillMaxSize()
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        // Title
        Text(
            text = "Audio Color Visualizer",
            fontSize = 24.sp,
            fontWeight = FontWeight.Bold,
            textAlign = TextAlign.Center,
            modifier = Modifier.padding(bottom = 32.dp)
        )

        // Color display area
        ColorDisplay(uiState)

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

        // Status indicator
        StatusIndicator(
            isActive = uiState.isActive,
            hasPermission = hasAudioPermission
        )

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

        // Instructions
        Text(
            text = when {
                !hasAudioPermission -> "Audio permission is required to visualize sound"
                uiState.isActive -> "Play some music or make sounds to see the colors change!"
                else -> "Starting audio visualizer..."
            },
            fontSize = 16.sp,
            textAlign = TextAlign.Center,
            color = MaterialTheme.colorScheme.onSurfaceVariant,
            modifier = Modifier.padding(horizontal = 32.dp)
        )

        // Permission request button (shown when permission is denied)
        if (!hasAudioPermission) {
            Spacer(modifier = Modifier.height(16.dp))

            Button(
                onClick = {
                    showPermissionRationale = false
                    permissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
                },
                modifier = Modifier.padding(horizontal = 32.dp)
            ) {
                Text("Grant Audio Permission")
            }
        }
    }

    // Permission rationale dialog
    if (showPermissionRationale) {
        AlertDialog(
            onDismissRequest = { showPermissionRationale = false },
            title = { Text("Audio Permission Required") },
            text = {
                Text("This app needs access to your microphone to visualize audio and create colors based on sound. Please grant the audio recording permission to continue.")
            },
            confirmButton = {
                TextButton(
                    onClick = {
                        showPermissionRationale = false
                        permissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
                    }
                ) {
                    Text("Grant Permission")
                }
            },
            dismissButton = {
                TextButton(
                    onClick = { showPermissionRationale = false }
                ) {
                    Text("Cancel")
                }
            }
        )
    }
}

@Composable
private fun ColorDisplay(uiState: VisualizerScreenUiState) {
    val animatedColor by animateColorAsState(
        uiState.color,
        animationSpec = tween(50),
    )
    Box(
        modifier = Modifier
            .size(300.dp)
            .clip(RoundedCornerShape(16.dp))
            .drawBehind {
                drawRect(animatedColor)
            }
            .padding(16.dp),
        contentAlignment = Alignment.Center
    ) {
        // Show color information
        ColorInfoCard(
            color = uiState.color,
        )
    }
}

/**
 * Card displaying color information.
 */
@Composable
private fun ColorInfoCard(
    color: Color,
    modifier: Modifier = Modifier
) {
    Card(
        modifier = modifier,
        colors = CardDefaults.cardColors(
            containerColor = Color.White.copy(alpha = 0.9f)
        ),
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
    ) {
        Column(
            modifier = Modifier.padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(
                text = "Current Color",
                fontSize = 14.sp,
                fontWeight = FontWeight.Medium,
                color = Color.Black
            )

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

            // RGB values
            val (r, g, b) = with(color) {
                Triple(
                    (red * 255).toInt(),
                    (green * 255).toInt(),
                    (blue * 255).toInt()
                )
            }

            Text(
                text = "RGB($r, $g, $b)",
                fontSize = 12.sp,
                color = Color.Black.copy(alpha = 0.7f),
                fontWeight = FontWeight.Light
            )
        }
    }
}

/**
 * Status indicator showing whether the visualizer is active and permission status.
 */
@Composable
private fun StatusIndicator(
    isActive: Boolean,
    hasPermission: Boolean,
    modifier: Modifier = Modifier
) {
    Row(
        modifier = modifier,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Box(
            modifier = Modifier
                .size(12.dp)
                .clip(RoundedCornerShape(6.dp))
                .background(
                    when {
                        !hasPermission -> Color.Gray
                        isActive -> Color.Green
                        else -> Color.Red
                    }
                )
        )

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

        Text(
            text = when {
                !hasPermission -> "Permission Required"
                isActive -> "Active"
                else -> "Inactive"
            },
            fontSize = 14.sp,
            color = MaterialTheme.colorScheme.onSurface
        )
    }
}
