package xyz.cottongin.radio247.ui.screens.settings

import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Arrangement
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.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowDownward
import androidx.compose.material.icons.filled.ArrowUpward
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilterChip
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
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.platform.LocalContext
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import xyz.cottongin.radio247.data.model.ListeningSession
import xyz.cottongin.radio247.data.model.MetadataSnapshot

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(
    onBack: () -> Unit,
    modifier: Modifier = Modifier,
    viewModel: SettingsViewModel = viewModel(
        factory = SettingsViewModelFactory(
            LocalContext.current.applicationContext as xyz.cottongin.radio247.RadioApplication
        )
    )
) {
    val stayConnected by viewModel.stayConnected.collectAsState()
    val bufferMs by viewModel.bufferMs.collectAsState()
    val qualityPref by viewModel.qualityPreference.collectAsState()
    val historyEnabled by viewModel.historyEnabled.collectAsState()
    val historyFormat by viewModel.historyFormat.collectAsState()
    val historyDirUri by viewModel.historyDirUri.collectAsState()
    val recentSessions by viewModel.recentSessions.collectAsState()
    val filteredTracks by viewModel.filteredTracks.collectAsState()
    val stations by viewModel.stations.collectAsState()
    val isRestarting by viewModel.isRestarting.collectAsState()

    var trackHistoryQuery by remember { mutableStateOf("") }
    var showExportDialog by remember { mutableStateOf(false) }
    var showResetDialog by remember { mutableStateOf(false) }
    var resetAlsoDeleteStations by remember { mutableStateOf(false) }

    val qualityOrder = remember(qualityPref) { viewModel.parseQualityOrder(qualityPref) }

    val createDocumentM3u = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.CreateDocument("audio/x-mpegurl")
    ) { uri: Uri? ->
        uri?.let { viewModel.exportPlaylist(null, stations, "m3u", it) }
    }

    val createDocumentPls = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.CreateDocument("audio/x-scpls")
    ) { uri: Uri? ->
        uri?.let { viewModel.exportPlaylist(null, stations, "pls", it) }
    }

    val pickHistoryDir = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.OpenDocumentTree()
    ) { uri: Uri? ->
        uri?.let {
            val context = viewModel.getApplication<xyz.cottongin.radio247.RadioApplication>()
            val flags = android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION or
                android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION
            context.contentResolver.takePersistableUriPermission(it, flags)
            viewModel.setHistoryDirUri(it.toString())
        }
    }

    Scaffold(
        modifier = modifier.fillMaxSize(),
        topBar = {
            TopAppBar(
                title = { Text("Settings") },
                navigationIcon = {
                    IconButton(onClick = onBack) {
                        Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
                    }
                },
                colors = TopAppBarDefaults.topAppBarColors(
                    containerColor = MaterialTheme.colorScheme.surface,
                    titleContentColor = MaterialTheme.colorScheme.onSurface,
                    navigationIconContentColor = MaterialTheme.colorScheme.onSurface
                )
            )
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(innerPadding)
                .verticalScroll(rememberScrollState())
                .padding(16.dp)
        ) {
            // ── PLAYBACK ──
            SectionHeader("PLAYBACK")
            SettingRow("Stay Connected") {
                Switch(checked = stayConnected, onCheckedChange = { viewModel.setStayConnected(it) })
            }
            Text("Buffer: ${bufferMs}ms", style = MaterialTheme.typography.bodySmall)
            Slider(
                value = bufferMs.toFloat(),
                onValueChange = { viewModel.setBufferMs(it.toInt()) },
                valueRange = 0f..500f,
                steps = 49,
                modifier = Modifier.fillMaxWidth(),
                colors = SliderDefaults.colors(
                    thumbColor = MaterialTheme.colorScheme.primary,
                    activeTrackColor = MaterialTheme.colorScheme.primary
                )
            )

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

            // ── SOMAFM QUALITY ──
            SectionHeader("SOMAFM QUALITY")
            Text(
                "Drag to reorder stream quality preference. The app will try each option in order, falling back to the next if unavailable.",
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
            Spacer(modifier = Modifier.height(8.dp))
            QualityOrderList(
                order = qualityOrder,
                onReorder = { viewModel.setQualityPreference(it) }
            )

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

            // ── NOW PLAYING HISTORY ──
            SectionHeader("NOW PLAYING HISTORY")
            SettingRow("Enable History Logging") {
                Switch(checked = historyEnabled, onCheckedChange = { viewModel.setHistoryEnabled(it) })
            }
            if (historyEnabled) {
                Spacer(modifier = Modifier.height(8.dp))
                Text("Format", style = MaterialTheme.typography.bodySmall)
                Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                    listOf("csv" to "CSV", "json" to "JSON", "plain" to "Plain Text").forEach { (key, label) ->
                        FilterChip(
                            selected = historyFormat == key,
                            onClick = { viewModel.setHistoryFormat(key) },
                            label = { Text(label) }
                        )
                    }
                }
                Spacer(modifier = Modifier.height(8.dp))
                Text(
                    text = if (historyDirUri.isNotEmpty()) {
                        val uri = Uri.parse(historyDirUri)
                        uri.lastPathSegment ?: historyDirUri
                    } else {
                        "Default (app storage)"
                    },
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
                Button(
                    onClick = { pickHistoryDir.launch(null) },
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Text("Choose Directory")
                }
            }

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

            // ── EXPORT ──
            SectionHeader("EXPORT")
            Button(onClick = { showExportDialog = true }, modifier = Modifier.fillMaxWidth()) {
                Text("Export Playlist")
            }

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

            // ── RECENTLY PLAYED ──
            SectionHeader("RECENTLY PLAYED")
            val stationMap = stations.associateBy { it.id }
            LazyColumn(
                modifier = Modifier.heightIn(max = 200.dp),
                verticalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                items(recentSessions, key = { it.id }) { session ->
                    RecentSessionRow(
                        session = session,
                        stationName = stationMap[session.stationId]?.name ?: "Unknown"
                    )
                }
            }

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

            // ── TRACK HISTORY ──
            SectionHeader("TRACK HISTORY")
            OutlinedTextField(
                value = trackHistoryQuery,
                onValueChange = {
                    trackHistoryQuery = it
                    viewModel.setTrackHistoryQuery(it)
                },
                modifier = Modifier.fillMaxWidth(),
                placeholder = { Text("Search...") },
                singleLine = true
            )
            Spacer(modifier = Modifier.height(8.dp))
            LazyColumn(
                modifier = Modifier.heightIn(max = 200.dp),
                verticalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                items(filteredTracks, key = { it.id }) { snapshot ->
                    TrackHistoryRow(
                        snapshot = snapshot,
                        stationName = stationMap[snapshot.stationId]?.name ?: "Unknown"
                    )
                }
            }

            Spacer(modifier = Modifier.height(24.dp))
            HorizontalDivider()
            Spacer(modifier = Modifier.height(24.dp))

            // ── ABOUT ──
            SectionHeader("ABOUT")
            Text(
                text = "24/7 Radio",
                style = MaterialTheme.typography.titleMedium,
                color = MaterialTheme.colorScheme.onSurface
            )
            Text(
                text = "Version ${xyz.cottongin.radio247.BuildConfig.VERSION_NAME}",
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
            Spacer(modifier = Modifier.height(4.dp))
            Text(
                text = "Personal-use internet radio streaming app with ultra-low latency playback and Icecast/Shoutcast metadata support.",
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
            Spacer(modifier = Modifier.height(4.dp))
            Text(
                text = xyz.cottongin.radio247.BuildConfig.APPLICATION_ID,
                style = MaterialTheme.typography.labelSmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f)
            )

            Spacer(modifier = Modifier.height(24.dp))
            HorizontalDivider()
            Spacer(modifier = Modifier.height(24.dp))

            // ── RESET ──
            SectionHeader("RESET")
            SettingRow("Also delete saved stations/playlists") {
                Switch(
                    checked = resetAlsoDeleteStations,
                    onCheckedChange = { resetAlsoDeleteStations = it }
                )
            }
            Spacer(modifier = Modifier.height(8.dp))
            Button(
                onClick = { showResetDialog = true },
                modifier = Modifier.fillMaxWidth(),
                colors = ButtonDefaults.buttonColors(
                    containerColor = MaterialTheme.colorScheme.error,
                    contentColor = MaterialTheme.colorScheme.onError
                )
            ) {
                Text("Reset All Customizations")
            }

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

            // ── RESTART ──
            SectionHeader("APP")
            Button(
                onClick = { viewModel.restartApp() },
                modifier = Modifier.fillMaxWidth(),
                enabled = !isRestarting
            ) {
                if (isRestarting) {
                    CircularProgressIndicator(modifier = Modifier.size(18.dp), strokeWidth = 2.dp)
                } else {
                    Text("Restart App")
                }
            }

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

    // ── DIALOGS ──

    if (showExportDialog) {
        AlertDialog(
            onDismissRequest = { showExportDialog = false },
            confirmButton = {
                Button(onClick = { showExportDialog = false }) { Text("Cancel") }
            },
            title = { Text("Export format") },
            text = {
                Column {
                    Button(
                        onClick = {
                            showExportDialog = false
                            createDocumentM3u.launch("playlist.m3u")
                        },
                        modifier = Modifier.fillMaxWidth()
                    ) { Text("M3U") }
                    Spacer(modifier = Modifier.height(8.dp))
                    Button(
                        onClick = {
                            showExportDialog = false
                            createDocumentPls.launch("playlist.pls")
                        },
                        modifier = Modifier.fillMaxWidth()
                    ) { Text("PLS") }
                }
            }
        )
    }

    if (showResetDialog) {
        val message = if (resetAlsoDeleteStations) {
            "This will clear all stars, custom sort orders, hidden states, and quality overrides. All user-added stations and playlists will be deleted. This cannot be undone."
        } else {
            "This will clear all stars, custom sort orders, hidden states, and quality overrides. Your saved stations will be kept. This cannot be undone."
        }
        AlertDialog(
            onDismissRequest = { showResetDialog = false },
            confirmButton = {
                Button(
                    onClick = {
                        showResetDialog = false
                        viewModel.resetCustomizations(resetAlsoDeleteStations)
                    },
                    colors = ButtonDefaults.buttonColors(
                        containerColor = MaterialTheme.colorScheme.error,
                        contentColor = MaterialTheme.colorScheme.onError
                    )
                ) { Text("Reset") }
            },
            dismissButton = {
                Button(onClick = { showResetDialog = false }) { Text("Cancel") }
            },
            title = { Text("Reset Customizations") },
            text = { Text(message) }
        )
    }
}

@Composable
private fun SettingRow(
    label: String,
    modifier: Modifier = Modifier,
    control: @Composable () -> Unit
) {
    Row(
        modifier = modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(text = label, modifier = Modifier.weight(1f))
        control()
    }
}

@Composable
private fun QualityOrderList(
    order: List<String>,
    onReorder: (List<String>) -> Unit
) {
    val labels = mapOf(
        "256-ssl" to "256 kbps (SSL)",
        "256-nossl" to "256 kbps",
        "128-ssl" to "128 kbps (SSL)",
        "128-nossl" to "128 kbps"
    )
    Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
        order.forEachIndexed { index, key ->
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 4.dp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    text = "${index + 1}.",
                    style = MaterialTheme.typography.bodyMedium,
                    color = MaterialTheme.colorScheme.primary,
                    modifier = Modifier.padding(end = 8.dp)
                )
                Text(
                    text = labels[key] ?: key,
                    style = MaterialTheme.typography.bodyMedium,
                    modifier = Modifier.weight(1f)
                )
                IconButton(
                    onClick = {
                        if (index > 0) {
                            val mutable = order.toMutableList()
                            mutable[index] = mutable[index - 1].also { mutable[index - 1] = mutable[index] }
                            onReorder(mutable)
                        }
                    },
                    enabled = index > 0
                ) {
                    Icon(Icons.Default.ArrowUpward, contentDescription = "Move up", modifier = Modifier.size(20.dp))
                }
                IconButton(
                    onClick = {
                        if (index < order.lastIndex) {
                            val mutable = order.toMutableList()
                            mutable[index] = mutable[index + 1].also { mutable[index + 1] = mutable[index] }
                            onReorder(mutable)
                        }
                    },
                    enabled = index < order.lastIndex
                ) {
                    Icon(Icons.Default.ArrowDownward, contentDescription = "Move down", modifier = Modifier.size(20.dp))
                }
            }
        }
    }
}

@Composable
private fun SectionHeader(title: String, modifier: Modifier = Modifier) {
    Text(
        text = title,
        style = MaterialTheme.typography.titleSmall,
        color = MaterialTheme.colorScheme.primary,
        modifier = modifier.padding(vertical = 8.dp)
    )
}

@Composable
private fun RecentSessionRow(
    session: ListeningSession,
    stationName: String,
    modifier: Modifier = Modifier
) {
    val duration = if (session.endedAt != null) {
        formatDuration(session.endedAt - session.startedAt)
    } else {
        "In progress"
    }
    val relativeTime = formatRelativeTime(session.startedAt)

    Row(
        modifier = modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(
            text = stationName,
            style = MaterialTheme.typography.bodyMedium,
            modifier = Modifier.weight(1f)
        )
        Text(
            text = "$relativeTime | $duration",
            style = MaterialTheme.typography.bodySmall,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )
    }
}

@Composable
private fun TrackHistoryRow(
    snapshot: MetadataSnapshot,
    stationName: String,
    modifier: Modifier = Modifier
) {
    val trackInfo = when {
        snapshot.artist != null && snapshot.title != null ->
            "${snapshot.artist} - ${snapshot.title}"
        snapshot.title != null -> snapshot.title
        snapshot.artist != null -> snapshot.artist
        else -> "Unknown track"
    }
    val timestamp = formatRelativeTime(snapshot.timestamp)

    Column(modifier = modifier.fillMaxWidth()) {
        Text(text = trackInfo, style = MaterialTheme.typography.bodyMedium)
        Text(
            text = "$stationName | $timestamp",
            style = MaterialTheme.typography.bodySmall,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )
    }
}

private fun formatDuration(millis: Long): String {
    if (millis <= 0) return "0s"
    val totalSeconds = millis / 1000
    val hours = totalSeconds / 3600
    val minutes = (totalSeconds % 3600) / 60
    val seconds = totalSeconds % 60
    return buildString {
        if (hours > 0) append("${hours}h ")
        if (minutes > 0 || hours > 0) append("${minutes}m ")
        append("${seconds}s")
    }.trim()
}

private fun formatRelativeTime(timestampMs: Long): String {
    val now = System.currentTimeMillis()
    val diff = now - timestampMs
    return when {
        diff < 60_000 -> "${diff / 1000}s ago"
        diff < 3600_000 -> "${diff / 60_000}m ago"
        diff < 86400_000 -> "${diff / 3600_000}h ago"
        else -> "${diff / 86400_000}d ago"
    }
}
