<template>
    <view class="tj-icon-wrap" :class="[`tj-icon-wrap--${size}`]">
        <image
            v-if="!useFallback"
            class="tj-icon"
            :class="[`tj-icon--${name}`, `tj-icon--${size}`]"
            :src="iconSrc"
            mode="aspectFit"
            @error="onImageError"
        />
        <text
            v-else
            class="tj-icon-fallback"
            :class="[`tj-icon-fallback--${size}`]"
            :style="{ color }"
        >{{ fallbackGlyph }}</text>
    </view>
</template>

<script setup>
import { computed, ref } from 'vue'
import { svgToDataUrl } from '../utils/svgDataUrl.js'

const props = defineProps({
    name: { type: String, required: true },
    size: { type: String, default: 'md' },
    color: { type: String, default: '#0891B2' }
})

const useFallback = ref(false)

/** Lucide 风格描边路径 */
const ICON_PATHS = {
    view: '<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/>',
    ticket: '<path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"/><path d="M13 5v2"/><path d="M13 17v2"/><path d="M13 11v2"/>',
    calendar: '<rect width="18" height="18" x="3" y="4" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/>',
    flame: '<path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"/>',
    'check-circle': '<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/>',
    glucose: '<path d="M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z"/>',
    heart: '<path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/>',
    activity: '<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>',
    users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
    'alert-triangle': '<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/>',
    minus: '<path d="M5 12h14"/>',
    droplet: '<path d="M12 22a7 7 0 0 0 7-7c0-2-1-3.5-2.5-5.5C15 7 12 2 12 2S9 7 7.5 9.5 5 13 5 15a7 7 0 0 0 7 7z"/>',
    sparkles: '<path d="m12 3-1.9 5.8L4 12l5.8 1.9L12 21l1.9-5.8L20 12l-5.8-1.9L12 3Z"/><path d="M5 3v4M19 17v4M3 5h4M17 19h4"/>',
    trophy: '<path d="M6 9H4.5a2.5 2.5 0 0 1 0-5H6M18 9h1.5a2.5 2.5 0 0 0 0-5H18M4 22h16M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20 7 22M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20 17 22M18 2H6v7a6 6 0 0 0 12 0V2Z"/>',
    share: '<path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13"/>',
    plus: '<path d="M5 12h14M12 5v14"/>',
    refresh: '<path d="M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8M3 3v5h5M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16M21 21v-5h-5"/>',
    volume: '<path d="M11 5 6 9H2v6h4l5 4V5zM15.54 8.46a5 5 0 0 1 0 7.07M19.07 4.93a10 10 0 0 1 0 14.14"/>',
    pause: '<rect width="4" height="16" x="14" y="4" rx="1"/><rect width="4" height="16" x="6" y="4" rx="1"/>',
    play: '<polygon points="6 3 20 12 6 21 6 3"/>',
    info: '<circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/>',
    sun: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41-1.41M17.66 6.34l1.41-1.41M6.34 4.93l1.41 1.41"/>',
    moon: '<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>',
    sunset: '<path d="M12 10V2M18.364 5.636l-2.12 2.12M5.636 18.364l2.12-2.12M22 18h-3M5 18H2M18.364 18.364l-2.12-2.12M5.636 5.636l2.12 2.12M16 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z"/>'
}

/** 图片加载失败时的 emoji 回退 */
const ICON_FALLBACK = {
    view: '👁',
    ticket: '🎫',
    calendar: '📅',
    flame: '🔥',
    'check-circle': '✓',
    glucose: '💧',
    heart: '❤',
    activity: '🏃',
    users: '👥',
    'alert-triangle': '⚠',
    minus: '—',
    droplet: '💧',
    sparkles: '✨',
    trophy: '🏆',
    share: '↗',
    plus: '＋',
    refresh: '↻',
    volume: '🔊',
    pause: '⏸',
    play: '▶',
    info: '!',
    sun: '☀',
    moon: '🌙',
    sunset: '☀'
}

const strokeColor = computed(() => {
    const c = String(props.color || '#0891B2').trim()
    return /^#[0-9A-Fa-f]{3,8}$/.test(c) ? c : '#0891B2'
})

const iconSrc = computed(() => {
    const path = ICON_PATHS[props.name] || ICON_PATHS.view
    const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="${strokeColor.value}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${path}</svg>`
    return svgToDataUrl(svg)
})

const fallbackGlyph = computed(() => ICON_FALLBACK[props.name] || ICON_FALLBACK.view)

function onImageError() {
    useFallback.value = true
}
</script>

<style lang="scss" scoped>
.tj-icon-wrap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.tj-icon-wrap--sm {
    width: 32rpx;
    height: 32rpx;
}
.tj-icon-wrap--md {
    width: 40rpx;
    height: 40rpx;
}
.tj-icon-wrap--lg {
    width: 48rpx;
    height: 48rpx;
}
.tj-icon-wrap--xl {
    width: 56rpx;
    height: 56rpx;
}
.tj-icon {
    display: block;
    width: 100%;
    height: 100%;
}
.tj-icon-fallback {
    display: block;
    line-height: 1;
    font-weight: 700;
    text-align: center;
}
.tj-icon-fallback--sm {
    font-size: 24rpx;
}
.tj-icon-fallback--md {
    font-size: 30rpx;
}
.tj-icon-fallback--lg {
    font-size: 36rpx;
}
.tj-icon-fallback--xl {
    font-size: 42rpx;
}
</style>
