/**
 * The UI showing the fitting resource stats: CPU, powergrid etc.
 */

package theorycrafter.ui.fitstats

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import compose.utils.EasyTooltipPlacement
import compose.widgets.GridScope
import compose.widgets.SimpleGrid
import eve.data.asCpu
import eve.data.asPower
import theorycrafter.fitting.Fit
import theorycrafter.ui.TheorycrafterTheme
import theorycrafter.ui.tooltip
import theorycrafter.ui.widgets.PercentageView
import theorycrafter.ui.widgets.PercentageViewColors
import theorycrafter.utils.AttractAttentionOnValueChange
import theorycrafter.utils.DpOffsetX
import kotlin.math.absoluteValue


/**
 * Shows the fitting resource (CPU, PG etc.) utilization.
 */
@Composable
fun FittingResourceStats(fit: Fit) {
    SimpleGrid(
        columnWidths = listOf(
            TheorycrafterTheme.sizes.fitStatsCaptionColumnWidth,
            TheorycrafterTheme.sizes.fitStatsPercentageViewWidth,
            Dp.Unspecified),
        defaultRowModifier = Modifier.padding(bottom = 6.dp),
        defaultRowAlignment = Alignment.CenterVertically,
        defaultCellModifier = Modifier.padding(end = 4.dp).fillMaxWidth()
    ){
        row(0) {
            ResourceRow(
                resourceName = "CPU",
                resource = fit.fitting.cpu,
                colors = TheorycrafterTheme.colors.cpuIndicatorColors(),
                valueToString = Double::asCpu
            )
        }
        row(1, modifier = Modifier.padding(bottom = 0.dp)) {  // Remove bottom padding from last row
            ResourceRow(
                resourceName = "Power",
                resource = fit.fitting.power,
                colors = TheorycrafterTheme.colors.powerIndicatorColors(),
                valueToString = Double::asPower
            )
        }
    }
}


/**
 * Shows the utilization of some ship resource.
 */
@Composable
private fun GridScope.GridRowScope.ResourceRow(
    resourceName: String,
    resource: Fit.Resource<Double>,
    colors: PercentageViewColors,
    valueToString: (Double, withUnits: Boolean) -> String,
) {
    val used = resource.used
    val total = resource.total
    val usedFraction = if (total == 0.0) 0.0 else (used / total)
    cell(0, modifier = Modifier.padding(end = TheorycrafterTheme.spacing.xsmall)) {
        Text(
            text = resourceName,
            style = TheorycrafterTheme.textStyles.caption,
            modifier = Modifier.align(Alignment.CenterEnd)
        )
    }
    cell(1) {
        ResourcePercentageView(
            value = usedFraction.toFloat(),
            colors = colors,
            modifier = Modifier
                .fillMaxWidth()
                .tooltip(
                    text = { "${valueToString(used, false)} of ${valueToString(total, true)} used" },
                    placement = EasyTooltipPlacement.ElementCenterEnd(
                        offset = DpOffsetX(TheorycrafterTheme.spacing.xxxsmall)
                    )
                )
        )
    }
    cell(2) {
        val remaining = total - used
        AttractAttentionOnValueChange(
            value = remaining,
            modifier = Modifier.align(Alignment.CenterStart)
        ) {
            Text(
                text = valueToString(remaining.absoluteValue, true) +
                        " " +
                        if (remaining >= 0) "available" else "over",
                color = TheorycrafterTheme.colors.invalidContent(valid = remaining >= 0)
            )
        }
    }
}


/**
 * Shows the utilization of a resource in a [PercentageView].
 */
@Composable
private fun ResourcePercentageView(
    value: Float,
    colors: PercentageViewColors,
    modifier: Modifier = Modifier
) {
    PercentageView(
        value = value,
        decimals = 1,
        colors = colors,
        modifier = modifier
    )
}
