<template>
	<div class="depth-input" :class="{ color: isColor, disabled: attrs.disabled }">
		<span class="decorate"></span>
		<span v-show="icon" class="icon">
			<svg-icon :name="icon" :size="iconSize" />
		</span>
		<span v-show="before" class="before">{{ before }}</span>

		<input
			v-if="!isColor"
			v-bind="attrs"
			:value="modelValue"
			@input="onInput"
			@change="onChange"
			@copy.stop
			@keydown.stop
		/>
		<template v-else>
			<input
				v-bind="attrs"
				type="color"
				:value="colorObj.color"
				@input="onInput"
				@change="onChange"
				@copy.stop
				@keydown.stop
			/>
			<input readonly :value="colorObj.color" @copy.stop @keydown.stop />
			<span class="decorate marginl"></span>
			<input
				v-bind="attrs"
				class="alpha"
				type="number"
				:value="Math.round(colorObj.alpha * 100)"
				min="0"
				max="100"
				@input="(e) => onInput(e, 'alpha')"
				@change="(e) => onChange(e, 'alpha')"
				@copy.stop
				@keydown.stop
			/>
		</template>

		<span v-show="after" class="after">{{ after }}</span>
	</div>
</template>

<script setup lang="ts">
	import { ref, useAttrs, watch, computed } from 'vue'
	const props = defineProps({
		modelValue: { type: [String, Number] },
		icon: { default: '', type: String },
		iconSize: { default: '10', type: [Number, String] },
		before: { default: '', type: String },
		after: { default: '', type: String }
	})
	const attrs = useAttrs()
	const emit = defineEmits(['update:modelValue', 'input', 'change'])
	const isColor = computed(() => attrs.type === 'color')
	const colorObj = computed(() => {
		if (isColor.value && props.modelValue) {
			let color = parseColor(props.modelValue)
			color.color = `#${toHex(color.r)}${toHex(color.g)}${toHex(color.b)}`
			return color
		}
		return { color: '#fff', alpha: 1 }
	})

	const inputtime = ref(null)
	const onInput = (e, type?: string) => {
		clearTimeout(inputtime.value)
		inputtime.value = setTimeout(() => {
			const value = handleInputChange(e, type)
			emit('update:modelValue', value)
			emit('input', value)
		}, 10)
	}
	const changetime = ref(null)
	const onChange = (e, type?: string) => {
		clearTimeout(changetime.value)
		changetime.value = setTimeout(() => {
			const value = handleInputChange(e, type)
			emit('update:modelValue', value)
			emit('change', value)
		}, 50)
	}
	// 处理输入事件
	const handleInputChange = (e, type?: string) => {
		var value = e.target.value
		if (attrs.type === 'number') value = Number(value)
		if (isColor.value) {
			const rgba = { ...colorObj.value }
			if (type === 'alpha') {
				let a = value / 100
				value = `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${a})`
			} else {
				let { r, g, b } = parseColor(value)
				value = `rgba(${r}, ${g}, ${b}, ${rgba.a})`
			}
		}
		return value
	}

	function parseColor(colorString) {
		// 处理 rgba/rgb
		const rgbaMatch = colorString.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/i)
		if (rgbaMatch) {
			return {
				type: 'rgb',
				r: parseInt(rgbaMatch[1]),
				g: parseInt(rgbaMatch[2]),
				b: parseInt(rgbaMatch[3]),
				a: rgbaMatch[4] ? parseFloat(rgbaMatch[4]) : 1,
				color: `#${toHex(rgbaMatch[1])}${toHex(rgbaMatch[2])}${toHex(rgbaMatch[3])}`,
				alpha: rgbaMatch[4] ? parseFloat(rgbaMatch[4]) : 1
			}
		}

		// 处理十六进制
		const hexMatch = colorString.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i)
		if (hexMatch) {
			let hex = hexMatch[1]
			if (hex.length === 3) {
				hex = hex
					.split('')
					.map((c) => c + c)
					.join('')
			}
			return {
				type: 'hex',
				r: parseInt(hex.substring(0, 2), 16),
				g: parseInt(hex.substring(2, 4), 16),
				b: parseInt(hex.substring(4, 6), 16),
				a: 1,
				color: `#${hex}`,
				alpha: 1
			}
		}

		// 处理 hsl/hsla
		const hslMatch = colorString.match(/hsla?\((\d+),\s*([\d.]+)%,\s*([\d.]+)%(?:,\s*([\d.]+))?\)/i)
		if (hslMatch) {
			const h = parseInt(hslMatch[1])
			const s = parseInt(hslMatch[2])
			const l = parseInt(hslMatch[3])
			const a = hslMatch[4] ? parseFloat(hslMatch[4]) : 1
			const rgb = hslToRgb(h, s, l)

			return {
				type: 'hsl',
				h,
				s,
				l,
				r: rgb.r,
				g: rgb.g,
				b: rgb.b,
				a: a,
				color: `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`,
				alpha: a
			}
		}

		// 处理颜色名称
		const namedColors = {
			red: '#ff0000',
			green: '#00ff00',
			blue: '#0000ff',
			black: '#000000',
			white: '#ffffff',
			yellow: '#ffff00',
			cyan: '#00ffff',
			magenta: '#ff00ff',
			transparent: 'rgba(0,0,0,0)'
		}

		if (namedColors[colorString.toLowerCase()]) {
			return parseColor(namedColors[colorString.toLowerCase()])
		}

		return parseColor('#fff')
	}
	// 将 0-255 的数字转换为十六进制
	function toHex(num) {
		// 确保数字在 0-255 范围内
		num = Math.min(255, Math.max(0, num))
		// 转换为十六进制，并确保两位数
		return num.toString(16).padStart(2, '0').toUpperCase()
	}
	// HSL 转 RGB
	function hslToRgb(h, s, l) {
		h = h / 360
		s = s / 100
		l = l / 100

		let r, g, b

		if (s === 0) {
			r = g = b = l
		} else {
			const hue2rgb = (p, q, t) => {
				if (t < 0) t += 1
				if (t > 1) t -= 1
				if (t < 1 / 6) return p + (q - p) * 6 * t
				if (t < 1 / 2) return q
				if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6
				return p
			}

			const q = l < 0.5 ? l * (1 + s) : l + s - l * s
			const p = 2 * l - q

			r = hue2rgb(p, q, h + 1 / 3)
			g = hue2rgb(p, q, h)
			b = hue2rgb(p, q, h - 1 / 3)
		}

		return {
			r: Math.round(r * 255),
			g: Math.round(g * 255),
			b: Math.round(b * 255)
		}
	}
</script>
<style scoped lang="less">
	.depth-input {
		display: flex;
		align-items: center;
		width: 100%;
		border: 0.1rem solid var(--depth-input-border-color, rgba(230, 230, 231, 1));
		border-radius: 0.2rem;
		height: var(--depth-input-height, 2rem);
		background-color: var(--depth-input-bg-color, #fff);
		padding: 0 0.4rem 0 0.2rem;
		&.disabled,
		&.disabled * {
			cursor: not-allowed;
		}
		&.color {
			--depth-input-decorate-margin-right: 1rem;
			--depth-input-input-margin-right: 1rem;
			--depth-input-input-font-align: left;
			// --depth-input-after-color: rgba(181, 181, 181, 1);
		}
		> .decorate {
			width: 0.2rem;
			background-color: var(--depth-input-decorate-color, rgba(230, 230, 231, 1));
			border-radius: 0.2rem;
			height: 75%;
			margin-right: var(--depth-input-decorate-margin-right, 0.4rem);
		}
		> .iconfont {
			font-size: 1.2rem;
			color: #000;
			margin-right: 0.4rem;
		}
		> .before {
			font-size: 1.2rem;
			color: #000;
			margin-right: 0.4rem;
		}
		> .after {
			font-size: 1.2rem;
			color: var(--depth-input-after-color, #000);
			margin-left: 0.2rem;
		}
		> input {
			font-size: 1.2rem;
			width: 0;
			height: 100%;
			flex: 1;
			margin-right: var(--depth-input-input-margin-right, 0rem);
			text-align: var(--depth-input-input-font-align, right);
			outline: none;
			border: none;
			background-color: transparent;
			padding: 0;
			-moz-appearance: textfield; /* Firefox */
			&::-webkit-outer-spin-button,
			&::-webkit-inner-spin-button {
				-webkit-appearance: none;
				margin: 0;
			}
			&.alpha {
				flex: 0.4;
				text-align: right;
				margin-right: 0;
			}
			&[type='color'] {
				flex: 0.5;
				border-radius: 0.2rem;
				height: 70%;
				border: 0.1rem solid rgb(42, 42, 42);
				display: block;
				&::-webkit-color-swatch-wrapper {
					padding: 0;
				}

				&::-webkit-color-swatch {
					border: none;
					border-radius: 0;
					width: 100%;
					height: 100%;
				}
			}
		}
	}
</style>
