package com.devlab.app.ui.components

import androidx.compose.animation.core.*
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.devlab.app.data.model.MetricPoint
import com.devlab.app.ui.theme.*

@Composable
fun MetricsChart(
    points: List<MetricPoint>,
    modifier: Modifier = Modifier
) {
    if (points.isEmpty()) {
        Box(modifier = modifier.fillMaxWidth().height(200.dp)) {
            Text(
                text = "No metrics data available",
                color = Grey500,
                modifier = Modifier.padding(16.dp)
            )
        }
        return
    }

    val animationProgress by animateFloatAsState(
        targetValue = 1f,
        animationSpec = tween(1500, easing = FastOutSlowInEasing),
        label = "chartAnim"
    )

    Column(modifier = modifier) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            LegendItem(color = Orange500, label = "CPU")
            LegendItem(color = Blue700, label = "RAM")
            LegendItem(color = Green500, label = "Disk")
        }

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

        Canvas(
            modifier = Modifier
                .fillMaxWidth()
                .height(200.dp)
        ) {
            val chartWidth = size.width
            val chartHeight = size.height
            val padding = 40f
            val drawWidth = chartWidth - padding * 2
            val drawHeight = chartHeight - padding * 2

            val cpuValues = points.map { it.cpu_usage ?: 0.0 }
            val ramValues = points.map { it.ram_usage ?: 0.0 }
            val diskValues = points.map { it.disk_usage ?: 0.0 }
            val maxVal = 100.0

            fun toX(index: Int): Float {
                if (points.size <= 1) return padding
                return padding + (index.toFloat() / (points.size - 1).coerceAtLeast(1)) * drawWidth
            }

            fun toY(value: Double): Float {
                return (padding + drawHeight - ((value / maxVal) * drawHeight)).toFloat()
            }

            drawLine(
                color = Color.LightGray.copy(alpha = 0.5f),
                start = Offset(padding, padding),
                end = Offset(padding, padding + drawHeight),
                strokeWidth = 1f
            )
            drawLine(
                color = Color.LightGray.copy(alpha = 0.5f),
                start = Offset(padding, padding + drawHeight),
                end = Offset(padding + drawWidth, padding + drawHeight),
                strokeWidth = 1f
            )

            val gridSteps = 4
            for (i in 0..gridSteps) {
                val y = padding + (drawHeight / gridSteps) * i
                drawLine(
                    color = Color.LightGray.copy(alpha = 0.3f),
                    start = Offset(padding, y),
                    end = Offset(padding + drawWidth, y),
                    strokeWidth = 1f
                )
                val label = "${(maxVal - (maxVal / gridSteps) * i).toInt()}%"
                drawContext.canvas.nativeCanvas.drawText(
                    label,
                    4f,
                    y + 4f,
                    android.graphics.Paint().apply {
                        color = android.graphics.Color.GRAY
                        textSize = 22f
                    }
                )
            }

            fun drawMetricLine(values: List<Double>, color: Color) {
                if (points.size < 2) return
                val path = Path()
                val count = (points.size * animationProgress).toInt().coerceIn(2, points.size)

                for (i in 0 until count) {
                    val x = toX(i)
                    val y = toY(values[i])
                    if (i == 0) path.moveTo(x, y)
                    else path.lineTo(x, y)
                }

                drawPath(
                    path = path,
                    color = color,
                    style = Stroke(
                        width = 3f,
                        cap = StrokeCap.Round,
                        join = StrokeJoin.Round
                    )
                )

                drawCircle(color, 5f, Offset(toX(count - 1), toY(values[count - 1])))
            }

            drawMetricLine(cpuValues, Orange500)
            drawMetricLine(ramValues, Blue700)
            drawMetricLine(diskValues, Green500)
        }
    }
}

@Composable
private fun LegendItem(color: Color, label: String) {
    Row(verticalAlignment = androidx.compose.ui.Alignment.CenterVertically) {
        Canvas(modifier = Modifier.size(10.dp)) {
            drawCircle(color = color)
        }
        Spacer(modifier = Modifier.width(4.dp))
        Text(text = label, style = MaterialTheme.typography.labelSmall, color = Grey500)
    }
}
