<script setup lang="ts">
import type { IconType, ExtendedThemeType, TranslatableString } from '@bagelink/vue'
import type { SetupContext } from 'vue'
import { Icon, Loading, useModal, useI18n, resolveI18n } from '@bagelink/vue'
import { useSlots, ref, onMounted, onUnmounted, computed } from 'vue'
import { RouterLink } from 'vue-router'

const props = withDefaults(
	defineProps<{
		disabled?: boolean
		icon?: IconType
		iconEnd?: IconType
		iconSize?: number | string
		iconMobileSize?: number | string
		color?: ExtendedThemeType
		theme?: ExtendedThemeType
		flat?: boolean
		border?: boolean
		outline?: boolean
		thin?: boolean
		size?: 'xs' | 's' | 'm' | 'l' | 'xl' | 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large'
		type?: 'button' | 'submit' | 'reset'
		loading?: boolean
		role?: string
		value?: TranslatableString
		to?: string
		href?: string
		round?: boolean
		is?: string
		ripple?: boolean
		fullWidth?: boolean
		fullWidthMobile?: boolean
		alignTxt?: 'center' | 'start' | 'end'
		alignTxtMobile?: 'center' | 'start' | 'end'
		onClick?: (e: MouseEvent) => void
		confirm?: boolean | string
	}>(),
	{
		onClick: () => '',
		loading: false,
		round: false,
		disabled: false,
		type: 'button',
		role: 'button',
		is: 'button',
		border: false,
		outline: false,
		ripple: true,
		fullWidth: false,
		fullWidthMobile: false,
		alignTxt: 'center',
		alignTxtMobile: 'center',
	},
)

const emit = defineEmits<{
	confirmed: [event: MouseEvent]
}>()

const { $t } = useI18n()

const computedPairClass = computed(() => {
	const theme = props.color || props.theme
	if (!theme) {
		// Only flat/border buttons get a default for visibility
		if (props.flat || props.border || props.outline) {
			return 'pair-black'
		}
		return 'pair-default'
	}
	return `pair-${theme}`
})

const isMobileScreen = ref(false)

function checkMobile() {
	isMobileScreen.value = window.innerWidth <= 910
}

onMounted(() => {
	checkMobile()
	window.addEventListener('resize', checkMobile)
})

onUnmounted(() => {
	window.removeEventListener('resize', checkMobile)
})

async function handleClick(event: MouseEvent) {
	if (props.confirm !== undefined && props.confirm !== false) {
		const { confirmModal } = useModal()
		const message = typeof props.confirm === 'string' ? props.confirm : $t('modalConfirm.message')
		const confirmed = await confirmModal({
			title: $t('modalConfirm.title'),
			message
		})

		if (!confirmed) { return }

		props.onClick(event)
		emit('confirmed', event)
	} else {
		props.onClick(event)
	}
}

const iconSizeComputed = computed(() => {
	if (props.iconSize !== undefined) { return props.iconSize }

	// Default icon sizes based on button size
	const sizeMap = {
		'xs': 0.7,
		'extra-small': 0.7,
		's': 0.9,
		'small': 0.9,
		'm': 1,
		'medium': 1,
		'l': 1.3,
		'large': 1.3,
		'xl': 1.6,
		'extra-large': 1.6
	}

	if (props.size && sizeMap[props.size as keyof typeof sizeMap]) {
		return sizeMap[props.size as keyof typeof sizeMap]
	}

	return isMobileScreen.value ? 1 : 1.2
})

const isComponent = computed(() => {
	if (props.disabled) { return props.is }
	if (props.to !== undefined && props.to !== '') { return RouterLink }
	if (props.href !== undefined && props.href !== '') { return 'a' }
	return props.is
})

const bind = computed(() => {
	const obj: { [key: string]: any } = {}
	if (!props.disabled) {
		if (props.to !== undefined && props.to !== '') { obj.to = props.to }
		else if (props.href !== undefined && props.href !== '') { obj.href = props.href }
	}
	if ((props.to === undefined || props.to === '') && (props.href === undefined || props.href === '')) {
		obj.role = props.role
		obj.type = props.type
	}
	return obj
})
const slots: SetupContext['slots'] = useSlots()
</script>

<template>
	<component
		:is="isComponent" v-ripple="ripple" v-bind="bind" :disabled="disabled" class="bgl_btn" :class="[{
			'bgl_btn-icon': icon && !slots.default && !value,
			thin,
			'bgl_btn_xsSize': size === 'xs' || size === 'extra-small',
			'bgl_btn_sSize': size === 's' || size === 'small',
			'bgl_btn_mSize': size === 'm' || size === 'medium',
			'bgl_btn_lSize': size === 'l' || size === 'large',
			'bgl_btn_xlSize': size === 'xl' || size === 'extra-large',
			'bgl_btn_fullWidth': fullWidth,
			'bgl_btn_fullWidthMobile': fullWidthMobile,
			'bgl_btn_alignStart': alignTxt === 'start',
			'bgl_btn_alignEnd': alignTxt === 'end',
			'bgl_btn_alignStartMobile': alignTxtMobile === 'start',
			'bgl_btn_alignEndMobile': alignTxtMobile === 'end',
			round,
			'bgl_flatPill': flat,
			'bgl_pill-border': border || outline,
		}, computedPairClass]" :tabindex="disabled ? -1 : 0" @click.stop="handleClick" @keydown.enter="handleClick" @keydown.space="handleClick"
	>
		<Loading v-if="loading" class="h-100p" size="15" color="currentColor" />
		<div v-else class="bgl_btn-flex">
			<Icon
				v-if="icon" :icon="icon" class="transition-400" :size="iconSizeComputed"
				:mobile-size="iconMobileSize"
			/>
			<slot />
			<template v-if="!slots.default && value">
				{{ resolveI18n(value) }}
			</template>
			<Icon
				v-if="iconEnd" :icon="iconEnd" class="transition-400" :size="iconSizeComputed"
				:mobile-size="iconMobileSize"
			/>
		</div>
	</component>
</template>

<style scoped>
/* @import '../styles/base-colors.css'; */

.bgl_btn {
	padding-left: var(--btn-padding);
	padding-right: var(--btn-padding);
	transition: var(--bgl-transition);
	text-decoration: none;
	/* Colors now handled by pair-* classes */
}

.bgl_btn.bgl_btn-icon {
	padding-left: 0;
	padding-right: 0;
	height: var(--btn-height);
	width: var(--btn-height);
	border-radius: 100%;
	font-size: 1rem;
	flex-shrink: 0;
}

a {
	text-decoration: none;
}

.bgl_btn-flex {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	justify-content: center;
	height: 100%;
}

.bgl_btn .bgl_btn-icon {
	font-size: calc(var(--input-font-size) * 1.3);
}

.bgl_btn:hover,
.bgl_btn-icon:hover {
	filter: var(--bgl-hover-filter);
}

.bgl_btn:active:not(:disabled),
.bgl_btn-icon:active:not(:disabled) {
	filter: var(--bgl-active-filter);
}

/* Flat hover/active styles now handled by base-colors.css */

.bgl_btn.round {
	border-radius: 1000px !important;
}

[dir="rtl"] .bgl_btn-icon {
	transform: rotateY(180deg);
}

[dir="rtl"] .ltr .bgl_btn-icon {
	transform: rotateY(0deg);
}

/* Border active styles now handled by base-colors.css */

.bgl_btn:disabled,
.bgl_btn[disabled=true] {
	opacity: 0.7;
	filter: grayscale(0.3);
	cursor: not-allowed;
}

.bgl_btn-icon .bgl_btn-flex {
	height: 100%;
}

/* xs size */
.bgl_btn_xsSize {
	padding-inline: calc(var(--btn-padding) / 6);
	border-radius: calc(var(--btn-border-radius) / 2);
	font-size: calc(var(--input-font-size) * 0.6);
}

.bgl_btn-icon.bgl_btn_xsSize {
	height: calc(var(--btn-height) / 2);
	width: calc(var(--btn-height) / 2);
	line-height: normal;
}

.bgl_btn_xsSize {
	height: calc(var(--btn-height) / 2);
	line-height: calc(var(--btn-height) / 2);
}

.bgl_btn_xsSize .bgl_btn-flex {
	gap: 0.2rem;
}

/* s size */
.bgl_btn.thin,
.bgl_btn_sSize {
	padding-inline: calc(var(--btn-padding) / 3);
	border-radius: calc(var(--btn-border-radius) / 1.5);
}

.bgl_btn-icon.thin,
.bgl_btn-icon.bgl_btn_sSize {
	height: calc(var(--btn-height) / 1.5);
	width: calc(var(--btn-height) / 1.5);
	line-height: normal;
}

.bgl_btn.thin,
.bgl_btn_sSize {
	height: calc(var(--btn-height) * 0.7);
	line-height: calc(var(--btn-height) * 0.7);
}

/* m size */
.bgl_btn_mSize {
	padding-inline: var(--btn-padding);
	font-size: var(--input-font-size);
	height: var(--btn-height);
	line-height: var(--btn-height);
}

.bgl_btn-icon.bgl_btn_mSize {
	height: var(--btn-height);
	width: var(--btn-height);
}

/* l size */
.bgl_btn_lSize {
	padding-inline: calc(var(--btn-padding) * 1.3);
	font-size: calc(var(--input-font-size) * 1.1);
	height: calc(var(--btn-height) * 1.2);
	line-height: calc(var(--btn-height) * 1.2);
}

.bgl_btn-icon.bgl_btn_lSize {
	height: calc(var(--btn-height) * 1.2);
	width: calc(var(--btn-height) * 1.2);
}

/* xl size */
.bgl_btn_xlSize {
	padding-inline: calc(var(--btn-padding) * 1.6);
	font-size: calc(var(--input-font-size) * 1.3);
	height: calc(var(--btn-height) * 1.5);
	line-height: calc(var(--btn-height) * 1.5);
}

.bgl_btn-icon.bgl_btn_xlSize {
	height: calc(var(--btn-height) * 1.5);
	width: calc(var(--btn-height) * 1.5);
}

.bgl_btn_fullWidth {
	width: 100%;
}

.bgl_btn_fullWidthMobile {
	width: auto;
}

/* Content alignment styles */
.bgl_btn_alignStart .bgl_btn-flex {
	justify-content: flex-start;
}

.bgl_btn_alignEnd .bgl_btn-flex {
	justify-content: flex-end;
}

.bgl_btn_alignStartMobile .bgl_btn-flex {
	justify-content: center;
}

.bgl_btn_alignEndMobile .bgl_btn-flex {
	justify-content: center;
}

@media screen and (max-width: 910px) {
	.bgl_btn_fullWidthMobile {
		width: 100%;
	}

	.bgl_btn_alignStartMobile .bgl_btn-flex {
		justify-content: flex-start;
	}

	.bgl_btn_alignEndMobile .bgl_btn-flex {
		justify-content: flex-end;
	}
}

/* Ensure external color classes always override pair classes */
.bgl_btn.color-white {
	color: white !important;
}

.bgl_btn.color-black {
	color: black !important;
}

.bgl_btn.text-white {
	color: white !important;
}

.bgl_btn.text-black {
	color: black !important;
}
</style>
