<script setup lang="ts">
/**
 * RankBars — horizontal ranked bars for top-N lists (leaderboards, sources by
 * revenue, most-viewed). Pure CSS bars: label + bar + value per row.
 *
 *   <RankBars :data="[{label:'Google',value:4200},{label:'Direct',value:3100}]" />
 *   <RankBars :data="rows" color="purple" currency="USD" :max-rows="5" />
 */
import { computed } from 'vue'
import { ramp, resolveColor } from './core/palette'
import { formatValue, type ValueFormat } from './core/format'
import type { ThemeType } from '../../types'

interface Row { label: string; value: number; color?: ThemeType | string }

const props = withDefaults(defineProps<{
	data: Row[]
	/** Base tone for bars (monochrome shade ramp by rank). */
	color?: ThemeType | string
	/** One tone per row instead of shades. Per-row `color` always wins. */
	mode?: 'shades' | 'multi'
	/** Cap rows shown (already-sorted input recommended). */
	maxRows?: number
	/** Sort descending by value before rendering. */
	sort?: boolean
	currency?: string
	prefix?: string
	suffix?: string
}>(), {
	color: 'primary',
	mode: 'shades',
	sort: true,
})

const fmt = computed<ValueFormat>(() => ({ currency: props.currency, prefix: props.prefix, suffix: props.suffix }))

const rows = computed(() => {
	let r = [...props.data]
	if (props.sort) r.sort((a, b) => b.value - a.value)
	if (props.maxRows) r = r.slice(0, props.maxRows)
	const max = Math.max(1, ...r.map(d => d.value))
	return r.map((d, i) => ({
		label: d.label,
		value: d.value,
		display: formatValue(d.value, fmt.value),
		pct: (d.value / max) * 100,
		color: d.color
			? resolveColor(d.color)
			: props.mode === 'multi'
				? resolveColor(undefined, i)
				: ramp(props.color, r.length, i),
	}))
})
</script>

<template>
	<div class="bgl-rank grid w-100p gap-05">
		<div v-for="(r, i) in rows" :key="i" class="bgl-rank__row align-items-center grid gap-075">
			<span class="bgl-rank__label ellipsis-1 txt14" :title="r.label">{{ r.label }}</span>
			<span class="bgl-rank__track overflow-hidden round">
				<span class="bgl-rank__bar display-block round" :style="{ width: `${r.pct}%`, background: r.color }" />
			</span>
			<span class="txt13 tabular-nums semibold">{{ r.display }}</span>
		</div>
	</div>
</template>

<style scoped>
.bgl-rank__row { grid-template-columns: minmax(60px, 28%) 1fr auto; }
.bgl-rank__track { height: 10px; background: var(--bgl-border-color); }
.bgl-rank__bar { height: 100%; transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1); }
</style>
