package com.fabledsword.minstrel.shared.widgets.trackactions

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
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.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.composables.icons.lucide.Disc3
import com.composables.icons.lucide.Eye
import com.composables.icons.lucide.EyeOff
import com.composables.icons.lucide.Heart
import com.composables.icons.lucide.ListMusic
import com.composables.icons.lucide.ListPlus
import com.composables.icons.lucide.ListVideo
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Radio
import com.composables.icons.lucide.User
import com.fabledsword.minstrel.models.TrackRef

/**
 * The 7-item track-actions modal bottom sheet. Mirrors Flutter's
 * `TrackActionsSheet`. Opens via [TrackActionsButton] (or any caller
 * holding a `TrackRef`); closes via [onDismiss] after any item runs
 * or when the user swipes down.
 *
 * The sheet pops first when an item is tapped (immediate visual
 * feedback) and then runs the action. For Add to playlist… and Hide,
 * the sub-sheet opens on top of this one; the parent stays mounted
 * so the user can pop back out without losing context.
 *
 * [hideQueueActions] suppresses Play next + Add to queue — set true
 * on the NowPlaying caller where the menu's track IS the playing one.
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TrackActionsSheet(
    track: TrackRef,
    hideQueueActions: Boolean,
    onDismiss: () -> Unit,
    onNavigateToAlbum: (albumId: String) -> Unit,
    onNavigateToArtist: (artistId: String) -> Unit,
    viewModel: TrackActionsViewModel = hiltViewModel(),
) {
    val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
    val isLiked by viewModel.isLikedFlow(track.id).collectAsStateWithLifecycle(initialValue = false)
    val isHidden by viewModel.isHiddenFlow(track.id).collectAsStateWithLifecycle(initialValue = false)
    var showAddToPlaylist by remember { mutableStateOf(false) }
    var showHideSheet by remember { mutableStateOf(false) }

    ModalBottomSheet(
        onDismissRequest = onDismiss,
        sheetState = sheetState,
    ) {
        TrackActionMenuItems(
            track = track,
            hideQueueActions = hideQueueActions,
            isLiked = isLiked,
            isHidden = isHidden,
            viewModel = viewModel,
            onDismiss = onDismiss,
            onNavigateToAlbum = onNavigateToAlbum,
            onNavigateToArtist = onNavigateToArtist,
            onShowAddToPlaylist = { showAddToPlaylist = true },
            onShowHideSheet = { showHideSheet = true },
        )
    }
    TrackActionSubSheets(
        track = track,
        showAddToPlaylist = showAddToPlaylist,
        showHideSheet = showHideSheet,
        viewModel = viewModel,
        onDismissParent = onDismiss,
        onCloseAddToPlaylist = { showAddToPlaylist = false },
        onCloseHideSheet = { showHideSheet = false },
    )
}

@Composable
private fun TrackActionMenuItems(
    track: TrackRef,
    hideQueueActions: Boolean,
    isLiked: Boolean,
    isHidden: Boolean,
    viewModel: TrackActionsViewModel,
    onDismiss: () -> Unit,
    onNavigateToAlbum: (String) -> Unit,
    onNavigateToArtist: (String) -> Unit,
    onShowAddToPlaylist: () -> Unit,
    onShowHideSheet: () -> Unit,
) {
    Column(modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)) {
        if (!hideQueueActions) {
            MenuItem(Lucide.ListVideo, "Play next") {
                viewModel.playNext(track); onDismiss()
            }
            MenuItem(Lucide.ListMusic, "Add to queue") {
                viewModel.enqueue(track); onDismiss()
            }
            HorizontalDivider()
        }
        MenuItem(Lucide.Heart, if (isLiked) "Unlike" else "Like") {
            viewModel.toggleLike(track.id, isLiked); onDismiss()
        }
        MenuItem(Lucide.ListPlus, "Add to playlist…", onShowAddToPlaylist)
        MenuItem(Lucide.Radio, "Start radio") {
            viewModel.startRadio(track.id); onDismiss()
        }
        HorizontalDivider()
        MenuItem(Lucide.Disc3, "Go to album") {
            onDismiss()
            if (track.albumId.isNotEmpty()) onNavigateToAlbum(track.albumId)
        }
        MenuItem(Lucide.User, "Go to artist") {
            onDismiss()
            if (track.artistId.isNotEmpty()) onNavigateToArtist(track.artistId)
        }
        HorizontalDivider()
        MenuItem(
            icon = if (isHidden) Lucide.Eye else Lucide.EyeOff,
            label = if (isHidden) "Unhide" else "Hide",
        ) {
            if (isHidden) {
                viewModel.unflag(track.id); onDismiss()
            } else {
                onShowHideSheet()
            }
        }
    }
}

@Composable
private fun TrackActionSubSheets(
    track: TrackRef,
    showAddToPlaylist: Boolean,
    showHideSheet: Boolean,
    viewModel: TrackActionsViewModel,
    onDismissParent: () -> Unit,
    onCloseAddToPlaylist: () -> Unit,
    onCloseHideSheet: () -> Unit,
) {
    if (showAddToPlaylist) {
        AddToPlaylistSheet(
            onPick = { playlistId ->
                viewModel.appendToPlaylist(playlistId, track.id)
                onCloseAddToPlaylist()
                onDismissParent()
            },
            onDismiss = onCloseAddToPlaylist,
        )
    }
    if (showHideSheet) {
        HideTrackSheet(
            onSubmit = { reason, notes ->
                viewModel.flag(track, reason, notes)
                onCloseHideSheet()
                onDismissParent()
            },
            onDismiss = onCloseHideSheet,
        )
    }
}

@Composable
private fun MenuItem(icon: ImageVector, label: String, onClick: () -> Unit) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(onClick = onClick)
            .padding(horizontal = 20.dp, vertical = 14.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(16.dp),
    ) {
        Icon(
            imageVector = icon,
            contentDescription = null,
            tint = MaterialTheme.colorScheme.onSurface,
        )
        Text(
            text = label,
            style = MaterialTheme.typography.bodyLarge,
            color = MaterialTheme.colorScheme.onSurface,
        )
    }
}
