<script setup lang="ts">
defineOptions({ name: 'BglCard' })
import type { GradientDirProp, GradientProp } from '@bagelink/vue'
import { computed } from 'vue'
import { useGradientVariant } from '@bagelink/vue'

const props = defineProps<{
	label?: string
	/** Card header title. Pairs with the `#header-action` slot (e.g. a "View all"
	    button or a more-menu) to render a divided header row — replacing the common
	    hand-rolled `<div class="flex space-between border-bottom">…</div>` pattern.
	    For full control use the `#header` slot instead. */
	title?: string
	thin?: boolean
	outline?: boolean
	h100?: boolean
	to?: string
	href?: string
	overflowX?: boolean
	overflowY?: boolean
	frame?: boolean
	/** Theme tone used as the gradient's first stop (e.g. `color="green"`). */
	color?: string
	/** Paint the card with a gradient. `true` = auto (a darker shade of `color`);
	    a tone list like "green" or "blue purple pink" sets explicit stops. */
	gradient?: GradientProp
	/** Gradient direction — a named dir (`to-br`) or an angle in degrees. */
	gradientDir?: GradientDirProp
	bg?:
		| 'gray'
		| 'light'
		| 'dark'
		| 'primary'
		| 'secondary'
		| 'success'
		| 'danger'
		| 'warning'
		| 'info'
		| 'white'
		| 'transparent'
}>()

const { isGradient, gradientStyle } = useGradientVariant({
	gradient: () => props.gradient,
	gradientDir: () => props.gradientDir,
	color: () => props.color,
})

// A `pair-*` class is required to activate the `.gradient` paint rule. Mirror
// Btn: default to the auto case (primary) when no color is given.
const pairClass = computed(() => isGradient.value ? `pair-${props.color || 'primary'}` : undefined)

const bind = computed(() => {
	const obj: { [key: string]: any } = {}
	if (props.href !== undefined && props.href !== '') { obj.href = props.href }
	else if (props.to !== undefined && props.to !== '') { obj.to = props.to }
	return obj
})

const is = computed(() => {
	if (props.href !== undefined && props.href !== '') { return 'a' }
	if (props.to !== undefined && props.to !== '') { return 'router-link' }
	return 'div'
})
</script>

<template>
	<component
		:is="is" v-ripple="!!to" v-bind="bind" class="bgl_card" :class="[{
			thin,
			'border bg-transparent': outline,
			'h-100': h100,
			[bg || '']: bg,
			'overflow-x': overflowX,
			'overflow-y': overflowY,
			'card_frame': frame,
			'gradient': isGradient,
		}, pairClass]" :style="gradientStyle"
	>
		<span v-if="label" class="card_label block label">
			{{ label }}
		</span>
		<!-- Header row: title + optional trailing action. Full override via #header. -->
		<div v-if="$slots.header || title || $slots['header-action']" class="card_header flex space-between align-items-center">
			<slot name="header">
				<span class="card_header_title">{{ title }}</span>
				<span class="card_header_action flex align-items-center gap-05"><slot name="header-action" /></span>
			</slot>
		</div>
		<slot />
	</component>
</template>

<style>

.card_frame {
border: 1px solid var(--bgl-border-color);
}

/* Header row (title + action). Pulls out to the card edges via negative margins
   so its divider spans full-width regardless of the card's own padding, then
   restores breathing room below. On a p-0 card the negative margins resolve to 0. */
.card_header {
margin: calc(var(--bgl-card-pad) * -1) calc(var(--bgl-card-pad) * -1) var(--bgl-card-pad);
padding: 0.85rem var(--bgl-card-pad);
border-bottom: 1px solid var(--bgl-border-color);
min-height: 0;
}
.card_header_title {
font-weight: 600;
}

.bgl_card {
--bgl-card-pad: 2rem;
border-radius: var(--bgl-card-border-radius);
background: var(--bgl-box-bg);
padding: var(--bgl-card-pad);
position: relative;
}

.bgl_card.gray {
background: var(--bgl-gray-tint);
}

.bgl_card.thin {
--bgl-card-pad: 1rem;
padding: var(--bgl-card-pad);
}
/* When padding is stripped via the p-0 utility, the header supplies its own. */
.bgl_card.p-0 { --bgl-card-pad: 0rem; }
.bgl_card.p-0 .card_header { padding-inline: 1rem; padding-block: 0.75rem; margin-bottom: 0; }
/* Likewise the label hangs off the card edge on a p-0 card, so give it its own. */
.bgl_card.p-0 .card_label { padding-inline: 1rem; padding-top: 0.75rem; }

.bgl_card.BagelTable {
height: 100%;
overflow: auto;
padding-top: 0;
}

.bgl_card.thin .tabs {
margin-bottom: 1rem;
}

.bgl_card .bgl_card.tabs-top {
padding: 0;
}

</style>
