package com.fabledsword.minstrel.quarantine.ui

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.AssistChip
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.composables.icons.lucide.ArchiveRestore
import com.composables.icons.lucide.Lucide
import com.fabledsword.minstrel.models.QuarantineRef
import com.fabledsword.minstrel.shared.UiState
import com.fabledsword.minstrel.shared.widgets.EmptyState
import com.fabledsword.minstrel.shared.widgets.ErrorRetry
import com.fabledsword.minstrel.shared.widgets.LoadingCentered
import com.fabledsword.minstrel.shared.widgets.PullToRefreshScaffold
import com.fabledsword.minstrel.shared.widgets.TrackCoverThumb

@Composable
fun HiddenTab(viewModel: HiddenTabViewModel = hiltViewModel()) {
    val state by viewModel.uiState.collectAsStateWithLifecycle()
    PullToRefreshScaffold(onRefresh = { viewModel.refresh().join() }) {
        when (val s = state) {
            UiState.Loading -> LoadingCentered()
            UiState.Empty -> EmptyState(
                title = "No hidden tracks",
                body = "Flag a track from its menu (bad rip, wrong tags, etc.) " +
                    "and it'll show up here. The track stays out of system " +
                    "playlists until you unhide it.",
            )
            is UiState.Error -> ErrorRetry(
                title = "Couldn't load hidden tracks",
                message = s.message,
                onRetry = { viewModel.refresh() },
            )
            is UiState.Success -> HiddenList(
                rows = s.data,
                onUnflag = viewModel::unflag,
            )
        }
    }
}

@Composable
private fun HiddenList(rows: List<QuarantineRef>, onUnflag: (String) -> Unit) {
    LazyColumn(modifier = Modifier.fillMaxSize()) {
        items(items = rows, key = { it.trackId }) { row ->
            HiddenRow(row = row, onUnflag = { onUnflag(row.trackId) })
            HorizontalDivider()
        }
    }
}

@Composable
private fun HiddenRow(row: QuarantineRef, onUnflag: () -> Unit) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 12.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(12.dp),
    ) {
        TrackCoverThumb(coverUrl = row.coverUrl, contentDescription = row.trackTitle)
        Column(modifier = Modifier.weight(1f)) {
            Text(
                text = row.trackTitle,
                style = MaterialTheme.typography.bodyLarge,
                color = MaterialTheme.colorScheme.onSurface,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis,
            )
            Text(
                text = "${row.artistName} · ${row.albumTitle}",
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis,
            )
            Row(
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.spacedBy(8.dp),
                modifier = Modifier.padding(top = 4.dp),
            ) {
                AssistChip(
                    onClick = {},
                    enabled = false,
                    label = { Text(row.reasonLabel) },
                )
                if (row.createdAt.isNotEmpty()) {
                    Text(
                        text = relativeTime(row.createdAt),
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.onSurfaceVariant,
                    )
                }
            }
        }
        IconButton(onClick = onUnflag) {
            Icon(
                Lucide.ArchiveRestore,
                contentDescription = "Unhide",
                tint = MaterialTheme.colorScheme.onSurfaceVariant,
            )
        }
    }
}

// ─── Time helper (duplicated from HistoryTab to keep the widget local) ──

private const val MINUTES_PER_HOUR = 60L
private const val HOURS_PER_DAY = 24L
private const val DAYS_PER_WEEK = 7L

private fun relativeTime(iso: String): String {
    val parsed = runCatching { java.time.OffsetDateTime.parse(iso) }.getOrNull()
        ?: return iso
    val local = parsed.atZoneSameInstant(java.time.ZoneId.systemDefault())
    val now = java.time.OffsetDateTime.now(java.time.ZoneId.systemDefault())
    val minutes = java.time.temporal.ChronoUnit.MINUTES.between(local, now)
    val hours = java.time.temporal.ChronoUnit.HOURS.between(local, now)
    val days = java.time.temporal.ChronoUnit.DAYS.between(local, now)
    return when {
        minutes < MINUTES_PER_HOUR -> "${minutes.coerceAtLeast(1)}m ago"
        hours < HOURS_PER_DAY -> "${hours}h ago"
        days < DAYS_PER_WEEK -> {
            val dow = local.dayOfWeek.getDisplayName(
                java.time.format.TextStyle.SHORT,
                java.util.Locale.getDefault(),
            )
            val time = local.toLocalTime()
                .format(java.time.format.DateTimeFormatter.ofPattern("HH:mm"))
            "$dow $time"
        }
        else -> {
            val pattern = if (local.year == now.year) "MMM d" else "MMM d, yyyy"
            local.toLocalDate().format(java.time.format.DateTimeFormatter.ofPattern(pattern))
        }
    }
}
