<template>
    <button :type="type" :class="buttonClasses" :disabled="disabled" @click="handleClick">
        <slot name="icon-left" />
        <slot />
        <slot name="icon-right" />
    </button>
</template>

<script setup lang="ts">
import { computed } from 'vue'

export interface ButtonProps {
    /** Visual variant */
    variant?: 'solid' | 'outline' | 'ghost' | 'soft'
    /** Color token */
    color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'neutral'
    /** Size preset */
    size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
    /** HTML button type */
    type?: 'button' | 'submit' | 'reset'
    /** Disabled state */
    disabled?: boolean
    /** Loading state */
    loading?: boolean
    /** Full width */
    fullWidth?: boolean
}

const props = withDefaults(defineProps<ButtonProps>(), {
    variant: 'solid',
    color: 'primary',
    size: 'md',
    type: 'button',
    disabled: false,
    loading: false,
    fullWidth: false,
})

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

const handleClick = (event: MouseEvent) => {
    if (!props.disabled && !props.loading) {
        emit('click', event)
    }
}

/**
 * Tailwind class maps using new design tokens
 */
const base = `
    inline-flex items-center justify-center gap-2 font-medium rounded-lg
    focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2
    transition-all duration-micro ease-micro
    disabled:opacity-50 disabled:pointer-events-none
    active:scale-[0.98] transform-gpu
`.trim().replace(/\s+/g, ' ')

const sizeClasses: Record<string, string> = {
    xs: 'px-2 py-1 text-xs h-6',
    sm: 'px-3 py-1.5 text-sm h-8',
    md: 'px-4 py-2 text-sm h-10',
    lg: 'px-6 py-3 text-base h-12',
    xl: 'px-8 py-4 text-lg h-14',
}

const colorMatrix: Record<string, Record<string, string>> = {
    solid: {
        primary: `
            bg-primary-500 text-white shadow-soft
            hover:bg-primary-600 hover:shadow-medium
            focus-visible:ring-primary-500/50
            active:bg-primary-700
        `.trim().replace(/\s+/g, ' '),
        secondary: `
            bg-secondary text-white shadow-soft
            hover:bg-secondary/90 hover:shadow-medium
            focus-visible:ring-secondary/50
        `.trim().replace(/\s+/g, ' '),
        success: `
            bg-success-500 text-white shadow-soft
            hover:bg-success-600 hover:shadow-medium
            focus-visible:ring-success-500/50
            active:bg-success-700
        `.trim().replace(/\s+/g, ' '),
        warning: `
            bg-warning-500 text-white shadow-soft
            hover:bg-warning-600 hover:shadow-medium
            focus-visible:ring-warning-500/50
            active:bg-warning-700
        `.trim().replace(/\s+/g, ' '),
        error: `
            bg-error-500 text-white shadow-soft
            hover:bg-error-600 hover:shadow-medium
            focus-visible:ring-error-500/50
            active:bg-error-700
        `.trim().replace(/\s+/g, ' '),
        neutral: `
            bg-neutral-500 text-white shadow-soft
            hover:bg-neutral-600 hover:shadow-medium
            focus-visible:ring-neutral-500/50
            active:bg-neutral-700
        `.trim().replace(/\s+/g, ' '),
    },
    outline: {
        primary: `
            border border-primary-300 text-primary-600 bg-white
            hover:bg-primary-50 hover:border-primary-400
            focus-visible:ring-primary-500/50
            active:bg-primary-100
        `.trim().replace(/\s+/g, ' '),
        secondary: `
            border border-gray-300 text-secondary bg-white
            hover:bg-gray-50 hover:border-gray-400
            focus-visible:ring-secondary/50
        `.trim().replace(/\s+/g, ' '),
        success: `
            border border-success-300 text-success-600 bg-white
            hover:bg-success-50 hover:border-success-400
            focus-visible:ring-success-500/50
            active:bg-success-100
        `.trim().replace(/\s+/g, ' '),
        warning: `
            border border-warning-300 text-warning-600 bg-white
            hover:bg-warning-50 hover:border-warning-400
            focus-visible:ring-warning-500/50
            active:bg-warning-100
        `.trim().replace(/\s+/g, ' '),
        error: `
            border border-error-300 text-error-600 bg-white
            hover:bg-error-50 hover:border-error-400
            focus-visible:ring-error-500/50
            active:bg-error-100
        `.trim().replace(/\s+/g, ' '),
        neutral: `
            border border-neutral-300 text-neutral-600 bg-white
            hover:bg-neutral-50 hover:border-neutral-400
            focus-visible:ring-neutral-500/50
            active:bg-neutral-100
        `.trim().replace(/\s+/g, ' '),
    },
    ghost: {
        primary: `
            text-primary-600 bg-transparent
            hover:bg-primary-50
            focus-visible:ring-primary-500/50
            active:bg-primary-100
        `.trim().replace(/\s+/g, ' '),
        secondary: `
            text-secondary bg-transparent
            hover:bg-gray-50
            focus-visible:ring-secondary/50
        `.trim().replace(/\s+/g, ' '),
        success: `
            text-success-600 bg-transparent
            hover:bg-success-50
            focus-visible:ring-success-500/50
            active:bg-success-100
        `.trim().replace(/\s+/g, ' '),
        warning: `
            text-warning-600 bg-transparent
            hover:bg-warning-50
            focus-visible:ring-warning-500/50
            active:bg-warning-100
        `.trim().replace(/\s+/g, ' '),
        error: `
            text-error-600 bg-transparent
            hover:bg-error-50
            focus-visible:ring-error-500/50
            active:bg-error-100
        `.trim().replace(/\s+/g, ' '),
        neutral: `
            text-neutral-600 bg-transparent
            hover:bg-neutral-50
            focus-visible:ring-neutral-500/50
            active:bg-neutral-100
        `.trim().replace(/\s+/g, ' '),
    },
    soft: {
        primary: `
            bg-primary-100 text-primary-700
            hover:bg-primary-200
            focus-visible:ring-primary-500/50
            active:bg-primary-300
        `.trim().replace(/\s+/g, ' '),
        secondary: `
            bg-gray-100 text-secondary
            hover:bg-gray-200
            focus-visible:ring-secondary/50
        `.trim().replace(/\s+/g, ' '),
        success: `
            bg-success-100 text-success-700
            hover:bg-success-200
            focus-visible:ring-success-500/50
            active:bg-success-300
        `.trim().replace(/\s+/g, ' '),
        warning: `
            bg-warning-100 text-warning-700
            hover:bg-warning-200
            focus-visible:ring-warning-500/50
            active:bg-warning-300
        `.trim().replace(/\s+/g, ' '),
        error: `
            bg-error-100 text-error-700
            hover:bg-error-200
            focus-visible:ring-error-500/50
            active:bg-error-300
        `.trim().replace(/\s+/g, ' '),
        neutral: `
            bg-neutral-100 text-neutral-700
            hover:bg-neutral-200
            focus-visible:ring-neutral-500/50
            active:bg-neutral-300
        `.trim().replace(/\s+/g, ' '),
    },
}

const buttonClasses = computed(() => {
    const classes = [
        base,
        sizeClasses[props.size],
        colorMatrix[props.variant][props.color],
    ]

    if (props.fullWidth) {
        classes.push('w-full')
    }

    if (props.loading) {
        classes.push('cursor-wait')
    }

    return classes.join(' ')
})
</script>