package cy.hexor.furumi.ui.player

import android.content.Intent
import android.graphics.Bitmap
import androidx.activity.compose.BackHandler
import androidx.compose.animation.core.Animatable
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
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.platform.LocalDensity
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.drawscope.Fill
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt

@Composable
internal fun PlayGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val path = Path().apply {
            moveTo(size.width * 0.28f, size.height * 0.18f)
            lineTo(size.width * 0.28f, size.height * 0.82f)
            lineTo(size.width * 0.82f, size.height * 0.50f)
            close()
        }
        drawPath(path, color)
    }
}

@Composable
internal fun PauseGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val barWidth = size.width * 0.18f
        drawRoundRect(
            color = color,
            topLeft = Offset(size.width * 0.24f, size.height * 0.18f),
            size = androidx.compose.ui.geometry.Size(barWidth, size.height * 0.64f)
        )
        drawRoundRect(
            color = color,
            topLeft = Offset(size.width * 0.58f, size.height * 0.18f),
            size = androidx.compose.ui.geometry.Size(barWidth, size.height * 0.64f)
        )
    }
}

@Composable
internal fun PlaybackGlyph(
    playback: AudioPlaybackState,
    playSize: Int,
    pauseSize: Int
) {
    when {
        playback.isBuffering -> CircularProgressIndicator(
            modifier = Modifier.size(pauseSize.dp),
            color = FurumiBlack,
            strokeWidth = 2.dp
        )
        playback.isPlaying -> PauseGlyph(Modifier.size(pauseSize.dp), FurumiBlack)
        else -> PlayGlyph(Modifier.size(playSize.dp), FurumiBlack)
    }
}

@Composable
internal fun PlusGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val stroke = size.minDimension * 0.14f
        drawLine(
            color = color,
            start = Offset(size.width * 0.5f, size.height * 0.2f),
            end = Offset(size.width * 0.5f, size.height * 0.8f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.2f, size.height * 0.5f),
            end = Offset(size.width * 0.8f, size.height * 0.5f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
    }
}

@Composable
internal fun BackGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        drawLine(
            color = color,
            start = Offset(size.width * 0.72f, size.height * 0.16f),
            end = Offset(size.width * 0.28f, size.height * 0.50f),
            strokeWidth = size.minDimension * 0.12f,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.28f, size.height * 0.50f),
            end = Offset(size.width * 0.72f, size.height * 0.84f),
            strokeWidth = size.minDimension * 0.12f,
            cap = StrokeCap.Round
        )
    }
}

@Composable
internal fun PreviousGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val first = Path().apply {
            moveTo(size.width * 0.48f, size.height * 0.18f)
            lineTo(size.width * 0.48f, size.height * 0.82f)
            lineTo(size.width * 0.16f, size.height * 0.50f)
            close()
        }
        val second = Path().apply {
            moveTo(size.width * 0.84f, size.height * 0.18f)
            lineTo(size.width * 0.84f, size.height * 0.82f)
            lineTo(size.width * 0.52f, size.height * 0.50f)
            close()
        }
        drawPath(first, color)
        drawPath(second, color)
    }
}

@Composable
internal fun NextGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val first = Path().apply {
            moveTo(size.width * 0.16f, size.height * 0.18f)
            lineTo(size.width * 0.16f, size.height * 0.82f)
            lineTo(size.width * 0.48f, size.height * 0.50f)
            close()
        }
        val second = Path().apply {
            moveTo(size.width * 0.52f, size.height * 0.18f)
            lineTo(size.width * 0.52f, size.height * 0.82f)
            lineTo(size.width * 0.84f, size.height * 0.50f)
            close()
        }
        drawPath(first, color)
        drawPath(second, color)
    }
}

@Composable
internal fun ShuffleGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val stroke = size.minDimension * 0.10f
        drawLine(
            color = color,
            start = Offset(size.width * 0.14f, size.height * 0.30f),
            end = Offset(size.width * 0.34f, size.height * 0.30f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.34f, size.height * 0.30f),
            end = Offset(size.width * 0.66f, size.height * 0.70f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.66f, size.height * 0.70f),
            end = Offset(size.width * 0.86f, size.height * 0.70f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.14f, size.height * 0.70f),
            end = Offset(size.width * 0.34f, size.height * 0.70f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.34f, size.height * 0.70f),
            end = Offset(size.width * 0.66f, size.height * 0.30f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.66f, size.height * 0.30f),
            end = Offset(size.width * 0.86f, size.height * 0.30f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.76f, size.height * 0.20f),
            end = Offset(size.width * 0.86f, size.height * 0.30f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.76f, size.height * 0.40f),
            end = Offset(size.width * 0.86f, size.height * 0.30f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.76f, size.height * 0.60f),
            end = Offset(size.width * 0.86f, size.height * 0.70f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.76f, size.height * 0.80f),
            end = Offset(size.width * 0.86f, size.height * 0.70f),
            strokeWidth = stroke,
            cap = StrokeCap.Round
        )
    }
}

@Composable
internal fun RepeatGlyph(
    modifier: Modifier,
    color: Color,
    repeatMode: String
) {
    Box(modifier = modifier) {
        Canvas(modifier = Modifier.fillMaxSize()) {
            val stroke = size.minDimension * 0.10f
            drawLine(
                color = color,
                start = Offset(size.width * 0.24f, size.height * 0.30f),
                end = Offset(size.width * 0.78f, size.height * 0.30f),
                strokeWidth = stroke,
                cap = StrokeCap.Round
            )
            drawLine(
                color = color,
                start = Offset(size.width * 0.78f, size.height * 0.30f),
                end = Offset(size.width * 0.66f, size.height * 0.18f),
                strokeWidth = stroke,
                cap = StrokeCap.Round
            )
            drawLine(
                color = color,
                start = Offset(size.width * 0.78f, size.height * 0.30f),
                end = Offset(size.width * 0.66f, size.height * 0.42f),
                strokeWidth = stroke,
                cap = StrokeCap.Round
            )
            drawLine(
                color = color,
                start = Offset(size.width * 0.76f, size.height * 0.70f),
                end = Offset(size.width * 0.22f, size.height * 0.70f),
                strokeWidth = stroke,
                cap = StrokeCap.Round
            )
            drawLine(
                color = color,
                start = Offset(size.width * 0.22f, size.height * 0.70f),
                end = Offset(size.width * 0.34f, size.height * 0.58f),
                strokeWidth = stroke,
                cap = StrokeCap.Round
            )
            drawLine(
                color = color,
                start = Offset(size.width * 0.22f, size.height * 0.70f),
                end = Offset(size.width * 0.34f, size.height * 0.82f),
                strokeWidth = stroke,
                cap = StrokeCap.Round
            )
        }
        if (repeatMode.equals("one", ignoreCase = true)) {
            Text(
                text = "1",
                modifier = Modifier.align(Alignment.Center),
                style = MaterialTheme.typography.labelSmall.copy(fontSize = 9.sp),
                color = color,
                fontWeight = FontWeight.ExtraBold
            )
        }
    }
}

@Composable
internal fun GlobalGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val strokeWidth = size.minDimension * 0.09f
        drawCircle(
            color = color,
            radius = size.minDimension * 0.38f,
            center = Offset(size.width * 0.50f, size.height * 0.50f),
            style = Stroke(width = strokeWidth)
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.50f, size.height * 0.16f),
            end = Offset(size.width * 0.50f, size.height * 0.84f),
            strokeWidth = strokeWidth,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.16f, size.height * 0.50f),
            end = Offset(size.width * 0.84f, size.height * 0.50f),
            strokeWidth = strokeWidth,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color.copy(alpha = 0.74f),
            start = Offset(size.width * 0.24f, size.height * 0.34f),
            end = Offset(size.width * 0.76f, size.height * 0.34f),
            strokeWidth = strokeWidth * 0.78f,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color.copy(alpha = 0.74f),
            start = Offset(size.width * 0.24f, size.height * 0.66f),
            end = Offset(size.width * 0.76f, size.height * 0.66f),
            strokeWidth = strokeWidth * 0.78f,
            cap = StrokeCap.Round
        )
    }
}

@Composable
internal fun SearchGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        drawCircle(
            color = color,
            radius = size.minDimension * 0.30f,
            center = Offset(size.width * 0.42f, size.height * 0.42f),
            style = Stroke(width = size.minDimension * 0.10f)
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.64f, size.height * 0.64f),
            end = Offset(size.width * 0.88f, size.height * 0.88f),
            strokeWidth = size.minDimension * 0.10f,
            cap = StrokeCap.Round
        )
    }
}

@Composable
internal fun LibraryGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val strokeWidth = size.minDimension * 0.10f
        drawLine(
            color = color,
            start = Offset(size.width * 0.18f, size.height * 0.16f),
            end = Offset(size.width * 0.18f, size.height * 0.86f),
            strokeWidth = strokeWidth,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.46f, size.height * 0.16f),
            end = Offset(size.width * 0.46f, size.height * 0.86f),
            strokeWidth = strokeWidth,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.70f, size.height * 0.22f),
            end = Offset(size.width * 0.86f, size.height * 0.82f),
            strokeWidth = strokeWidth,
            cap = StrokeCap.Round
        )
    }
}

@Composable
internal fun ShareGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val strokeWidth = size.minDimension * 0.10f
        val nodeRadius = size.minDimension * 0.11f
        val left = Offset(size.width * 0.24f, size.height * 0.50f)
        val topRight = Offset(size.width * 0.76f, size.height * 0.22f)
        val bottomRight = Offset(size.width * 0.76f, size.height * 0.78f)

        drawLine(
            color = color,
            start = left,
            end = topRight,
            strokeWidth = strokeWidth,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = left,
            end = bottomRight,
            strokeWidth = strokeWidth,
            cap = StrokeCap.Round
        )
        drawCircle(color = color, radius = nodeRadius, center = left)
        drawCircle(color = color, radius = nodeRadius, center = topRight)
        drawCircle(color = color, radius = nodeRadius, center = bottomRight)
    }
}

@Composable
internal fun DevicesGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val strokeWidth = size.minDimension * 0.08f
        val phoneLeft = size.width * 0.54f
        val phoneTop = size.height * 0.16f
        val phoneWidth = size.width * 0.28f
        val phoneHeight = size.height * 0.58f
        drawRoundRect(
            color = color,
            topLeft = Offset(phoneLeft, phoneTop),
            size = androidx.compose.ui.geometry.Size(phoneWidth, phoneHeight),
            cornerRadius = androidx.compose.ui.geometry.CornerRadius(size.minDimension * 0.08f),
            style = Stroke(width = strokeWidth)
        )
        drawCircle(
            color = color,
            radius = size.minDimension * 0.025f,
            center = Offset(phoneLeft + phoneWidth / 2f, phoneTop + phoneHeight - size.height * 0.07f)
        )
        val speakerCenter = Offset(size.width * 0.30f, size.height * 0.60f)
        drawCircle(
            color = color,
            radius = size.minDimension * 0.09f,
            center = speakerCenter,
            style = Stroke(width = strokeWidth)
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.18f, size.height * 0.82f),
            end = Offset(size.width * 0.44f, size.height * 0.82f),
            strokeWidth = strokeWidth,
            cap = StrokeCap.Round
        )
        drawLine(
            color = color,
            start = Offset(size.width * 0.30f, size.height * 0.70f),
            end = Offset(size.width * 0.30f, size.height * 0.82f),
            strokeWidth = strokeWidth,
            cap = StrokeCap.Round
        )
    }
}

@Composable
internal fun HeartGlyph(
    isLiked: Boolean,
    modifier: Modifier,
    alpha: Float = 1.0f
) {
    Canvas(modifier = modifier) {
        val cx = size.width * 0.5f
        val top = size.height * 0.22f
        val bottom = size.height * 0.82f
        val left = size.width * 0.14f
        val right = size.width * 0.86f
        val midY = size.height * 0.38f

        val path = Path().apply {
            moveTo(cx, bottom)
            cubicTo(left, size.height * 0.62f, left, top, cx, midY)
            moveTo(cx, bottom)
            cubicTo(right, size.height * 0.62f, right, top, cx, midY)
        }

        if (isLiked) {
            drawPath(path, color = Color(0xFFFF3EA5).copy(alpha = alpha), style = Fill)
        }
        drawPath(
            path,
            color = if (isLiked) Color(0xFFFF3EA5).copy(alpha = alpha) else Color(0xFFC9B8D6).copy(alpha = alpha),
            style = Stroke(width = size.minDimension * 0.08f)
        )
    }
}

@Composable
internal fun AudioWaveGlyph(
    modifier: Modifier,
    color: Color
) {
    Canvas(modifier = modifier) {
        val barWidth = size.width * 0.12f
        val gap = size.width * 0.12f
        val heights = listOf(0.4f, 0.8f, 0.6f, 0.9f)
        
        heights.forEachIndexed { i, h ->
            val x = size.width * 0.15f + i * (barWidth + gap)
            val barHeight = size.height * h
            val y = (size.height - barHeight) / 2f
            
            drawRoundRect(
                color = color,
                topLeft = Offset(x, y),
                size = androidx.compose.ui.geometry.Size(barWidth, barHeight),
                cornerRadius = androidx.compose.ui.geometry.CornerRadius(barWidth / 2f)
            )
        }
    }
}

@Composable
internal fun MoreDotsGlyph(
    modifier: Modifier,
    color: Color = Color(0xFFC9B8D6)
) {
    Canvas(modifier = modifier) {
        val dotRadius = size.minDimension * 0.07f
        val cx = size.width * 0.5f
        drawCircle(color = color, radius = dotRadius, center = Offset(cx, size.height * 0.30f))
        drawCircle(color = color, radius = dotRadius, center = Offset(cx, size.height * 0.50f))
        drawCircle(color = color, radius = dotRadius, center = Offset(cx, size.height * 0.70f))
    }
}
