package com.fabledsword.minstrel.discover.ui

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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.AssistChip
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import com.composables.icons.lucide.Clock
import com.composables.icons.lucide.Disc3
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.User
import com.fabledsword.minstrel.models.ArtistSuggestionRef
import com.fabledsword.minstrel.models.LidarrSearchResultRef
import com.fabledsword.minstrel.models.SuggestionSnoozeRef

@Composable
internal fun SuggestionTile(
    s: ArtistSuggestionRef,
    snoozed: Boolean,
    onRequest: () -> Unit,
    onSnooze: () -> Unit,
    onUnsnooze: () -> Unit,
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 10.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(12.dp),
    ) {
        Avatar(imageUrl = s.imageUrl, fallback = Lucide.User, circular = true)
        Column(modifier = Modifier.weight(1f)) {
            Text(
                text = s.name,
                style = MaterialTheme.typography.bodyLarge,
                color = MaterialTheme.colorScheme.onSurface,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis,
            )
            // Once parked, the "because you liked X" line is no longer the
            // useful thing to say — confirming what just happened is.
            val secondary =
                if (snoozed) "Not right now — hidden for a while" else s.reasonText
            if (secondary.isNotEmpty()) {
                Text(
                    text = secondary,
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    maxLines = 2,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
        if (snoozed) {
            TextButton(onClick = onUnsnooze) { Text("Undo") }
        } else {
            Button(onClick = onRequest) { Text("Request") }
            IconButton(onClick = onSnooze) {
                Icon(
                    imageVector = Lucide.Clock,
                    // Rule #101: the label states what happens, and passes no
                    // judgement on the music. Never "not for me".
                    contentDescription = "Not right now — hide ${s.name} for a while",
                    tint = MaterialTheme.colorScheme.onSurfaceVariant,
                )
            }
        }
    }
}

/**
 * One row of the parked list. This exists because a snoozed candidate is by
 * definition absent from the deck above, so without it there is no route back
 * to an un-snooze once the card has gone.
 */
@Composable
internal fun SnoozedTile(row: SuggestionSnoozeRef, onUnsnooze: () -> Unit) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 8.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(12.dp),
    ) {
        Column(modifier = Modifier.weight(1f)) {
            Text(
                text = row.name,
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.onSurface,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis,
            )
            Text(
                text = "Back ${row.returnsIn()}",
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant,
            )
        }
        TextButton(onClick = onUnsnooze) { Text("Bring back") }
    }
}

@Composable
internal fun ResultTile(
    row: LidarrSearchResultRef,
    locallyRequested: Boolean,
    onRequest: () -> Unit,
) {
    val effectivelyRequested = row.requested || locallyRequested
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 10.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(12.dp),
    ) {
        Avatar(imageUrl = row.imageUrl, fallback = Lucide.Disc3, circular = false)
        Column(modifier = Modifier.weight(1f)) {
            Text(
                text = row.name,
                style = MaterialTheme.typography.bodyLarge,
                color = MaterialTheme.colorScheme.onSurface,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis,
            )
            if (row.secondaryText.isNotEmpty()) {
                Text(
                    text = row.secondaryText,
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
        when {
            row.inLibrary -> AssistChip(onClick = {}, enabled = false, label = { Text("In library") })
            effectivelyRequested ->
                AssistChip(onClick = {}, enabled = false, label = { Text("Requested") })
            else -> Button(onClick = onRequest) { Text("Request") }
        }
    }
}

@Composable
private fun Avatar(imageUrl: String, fallback: ImageVector, circular: Boolean) {
    val clip = if (circular) CircleShape else RoundedCornerShape(6.dp)
    Box(
        modifier = Modifier
            .size(56.dp)
            .clip(clip)
            .background(MaterialTheme.colorScheme.surfaceVariant),
        contentAlignment = Alignment.Center,
    ) {
        if (imageUrl.isEmpty()) {
            Icon(
                imageVector = fallback,
                contentDescription = null,
                tint = MaterialTheme.colorScheme.onSurfaceVariant,
            )
        } else {
            AsyncImage(
                model = imageUrl,
                contentDescription = null,
                modifier = Modifier.fillMaxSize(),
            )
        }
    }
}
