<template>
	<text class="cl-icon" :class="[ptClassName]" :style="iconStyle" :key="cache.key">
		{{ icon.text }}
	</text>
</template>

<script setup lang="ts">
import { computed, type PropType } from "vue";
import {
	forInObject,
	get,
	has,
	parsePt,
	useCache,
	isDark,
	ctx,
	hasTextColor,
	isNull
} from "@/cool";
import { icons } from "@/icons";
import { useSize } from "../../hooks";

defineOptions({
	name: "cl-icon"
});

// 定义组件属性
const props = defineProps({
	// 透传样式
	pt: {
		type: Object,
		default: () => ({})
	},
	// 图标名称
	name: {
		type: String,
		default: ""
	},
	// 图标大小
	size: {
		type: [String, Number] as PropType<string | number>,
		default: 32
	},
	// 图标高度
	height: {
		type: [String, Number] as PropType<string | number>,
		default: null
	},
	// 图标宽度
	width: {
		type: [String, Number] as PropType<string | number>,
		default: null
	},
	// 图标颜色
	color: {
		type: String,
		default: ""
	}
});

// 透传样式类型定义
type PassThrough = {
	className?: string;
};

// 解析透传样式
const pt = computed(() => parsePt<PassThrough>(props.pt));

// 缓存
const { cache } = useCache(() => [props.color]);

// 字号
const { getRpx, ptClassName } = useSize(() => pt.value.className ?? "");

// 图标类型定义
type Icon = {
	font: string; // 字体名称
	text: string; // 图标文本
};

// 图标信息
const icon = computed<Icon>(() => {
	let font = "";
	let text = "";

	try {
		let code = "";

		// 遍历字体库查找对应图标
		forInObject(icons, (value, key) => {
			if (has(value, props.name)) {
				font = key;
				code = get(value, props.name) as string;
			}
		});

		text = String.fromCharCode(parseInt(code, 16));
	} catch (e) {
		console.error(`图标 ${props.name} 不存在`, e);
	}

	return {
		font,
		text
	};
});

// 图标颜色
const color = computed(() => {
	if (props.color != "" && !isNull(props.color)) {
		switch (props.color) {
			case "primary":
				return ctx.color["primary-500"] as string;
			case "success":
				return "#22c55e";
			case "warn":
				return "#eab308";
			case "error":
				return "#ef4444";
			case "info":
				return ctx.color["surface-500"] as string;
			case "dark":
				return ctx.color["surface-700"] as string;
			case "light":
				return ctx.color["surface-50"] as string;
			case "disabled":
				return ctx.color["surface-300"] as string;
			default:
				return props.color;
		}
	}

	return isDark.value ? "white" : (ctx.color["surface-700"] as string);
});

// 图标样式
const iconStyle = computed(() => {
	const style = {};

	// 判断是不是有颜色样式
	if (!hasTextColor(ptClassName.value)) {
		style["color"] = color.value;
	}

	// 设置字体
	if (icon.value.font != "") {
		style["fontFamily"] = icon.value.font;
	}

	// 设置字体大小
	style["fontSize"] = getRpx(props.size!);

	// 设置高度
	style["height"] = getRpx(props.height ?? props.size!);
	style["lineHeight"] = getRpx(props.size!);

	// 设置宽度
	style["width"] = getRpx(props.width ?? props.size!);

	return style;
});
</script>
