<script setup lang="ts">
import type { IconType, ThemeType } from '@bagelink/vue'
import type { SetupContext } from 'vue'
import { Btn, Icon } from '@bagelink/vue'
import { useSlots } from 'vue'

interface BtnProp {
	icon?: IconType
	onClick: () => void
	value?: string
}

const props = defineProps<{
	disabled?: boolean
	icon?: IconType
	iconEnd?: IconType
	color?: ThemeType
	theme?: ThemeType
	flat?: boolean
	border?: boolean
	outline?: boolean
	loading?: boolean
	value?: string
	modelValue?: string
	round?: boolean
	btn?: BtnProp
	btnEnd?: BtnProp
	large?: boolean
	small?: boolean
}>()

const slots: SetupContext['slots'] = useSlots()

const computedTheme = $computed(
	() => {
		if (props.disabled) return 'gray-light'
		return (props.color || props.theme) as ThemeType
	},
)

const computedDefaultColors = $computed(
	() => ({
		backgroundColor: 'var(--bgl-primary)',
		color: props.flat ? 'var(--bgl-text-color)' : 'var(--bgl-light-text)',
	}),
)

function getThemeColors(theme: Partial<typeof computedDefaultColors>): typeof computedDefaultColors {
	return {
		...computedDefaultColors,
		...theme,
		color: props.flat
			? theme.backgroundColor as string
			: theme.color as string,
	}
}

const themes: Partial<Record<ThemeType, typeof computedDefaultColors>> = {
	'red': getThemeColors({ backgroundColor: 'var(--bgl-red)' }),
	'white': getThemeColors({ backgroundColor: 'var(--bgl-white)', color: 'var(--bgl-black)' }),
	'black': getThemeColors({ backgroundColor: 'var(--bgl-black)', color: 'var(--bgl-white)' }),
	'green': getThemeColors({ backgroundColor: 'var(--bgl-green)', color: 'var(--bgl-white)' }),
	'primary': getThemeColors({ backgroundColor: 'var(--bgl-primary)', color: 'var(--bgl-white)' }),
	'yellow': getThemeColors({ backgroundColor: 'var(--bgl-yellow)', color: 'var(--bgl-black)' }),
	'gray': getThemeColors({ backgroundColor: 'var(--bgl-gray-light)', color: 'var(--bgl-black)' }),
	'light': getThemeColors({ backgroundColor: 'var(--bgl-primary-light)', color: 'var(--bgl-primary)' }),
	'gray-light': getThemeColors({ backgroundColor: 'var(--bgl-gray-light)', color: 'var(--bgl-gray)' }),
	'blue': getThemeColors({}),
}

const cumputedTextColor = $computed(
	() => (themes[computedTheme as ThemeType]?.color ?? computedDefaultColors.color),
)

const computedBackgroundColor = $computed(
	() => (themes[computedTheme as ThemeType]?.backgroundColor ?? computedDefaultColors.backgroundColor),
)
</script>

<template>
	<div
		style="height: var(--pill-height);"
		:disabled="disabled" :class="{
			'bgl_pill': !icon || slots.default || value,
			round,
			'bgl_flatPill': flat,
			'bgl_pill-border': border || outline,
			'pillLarge': large,
			'pillSmall': small,
		}"
	>
		<div class="bgl_pill-flex">
			<div v-if="loading" class="loading" />
			<div v-else>
				<div v-if="btn" class="flex h-100">
					<Btn class="bgl_pill-btn" round thin v-bind="btn" />
				</div>
			</div>
			<Icon v-if="icon" :icon="icon" style="font-size: var(--pill-font-size)" />
			<slot />
			<template v-if="!slots.default">
				<p
					class="pillText"
				>
					{{ value || modelValue }}
					{{ slots.default ? slots.default : value || modelValue }}
					{{ value || modelValue }}
				</p>
			</template>
			<Icon v-if="iconEnd" :icon="iconEnd" style="font-size: var(--pill-font-size)" />
			<div v-if="loading" class="loading" />
			<div v-else>
				<div v-if="btnEnd" class="flex h-100">
					<Btn class="bgl_pill-btn" round thin flat v-bind="btnEnd" />
				</div>
			</div>
		</div>
	</div>
</template>

<style scoped>
.pillLarge{
	--pill-font-size: var(--bgl-font-size);
	--pill-height:auto;
}
.pillSmall{
	--pill-font-size: 9px;
	--pill-height:15px;
}
.pillText{
	font-size: var(--pill-font-size);
}
.bgl_pill-btn{
	color: var(--pill-btn-color);
	background: var(--pill-btn-bg);
	width: calc(var(--pill-height) / 1.25)!important;
	height: calc(var(--pill-height) / 1.25)!important;
}
.loading {
  border: 1px solid var(--bgl-light-text);
  border-bottom: 2px solid var(--bgl-light-text);
  animation: spin 1s linear infinite;
  border-radius: 100px;
  width: 1rem;
  height: 1rem;
  margin: auto;
}
.bgl_flatPill .loading {
	border-bottom: 2px solid var(--bgl-text-color);
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.bgl_pill {
  padding-inline: calc(var(--pill-font-size) / 6);
  padding-block: calc(var(--pill-font-size) / 24);
  transition: var(--bgl-transition);
  background-color: v-bind(computedBackgroundColor);
  color: v-bind(cumputedTextColor);
  display: inline-block;
  margin-inline-end: 0.25rem;
  border-radius: var(--pill-border-radius);
  min-height: var(--pill-height);
  vertical-align: middle;
  margin-bottom: 0.25rem;
}

.bgl_pill[disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

.bgl_pill-flex {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  justify-content: center;
  height: 100%;
}
.bgl_pill.bgl_flatPill {
  background: transparent;
}

.bgl_pill.round {
  border-radius: 1000px;
}

.bgl_pill-border {
  outline: 1px solid v-bind(computedBackgroundColor);
  color: v-bind(computedBackgroundColor);
  background: transparent;
}
</style>
