<template>
	<!-- App 平台：使用原生视图渲染 SVG，性能最佳 -->
	<!-- #ifdef APP -->
	<!-- @vue-ignore -->
	<native-view @init="onInit"></native-view>
	<!-- #endif -->

	<!-- 小程序平台：使用 image 标签显示 SVG -->
	<!-- #ifdef MP -->
	<!-- @vue-ignore -->
	<image class="cl-svg" :src="svgSrc"></image>
	<!-- #endif -->

	<!-- Web 平台：使用 object 标签以支持 SVG 交互和样式控制 -->
	<!-- #ifdef WEB -->
	<object :id="svgId" :data="svgSrc" type="image/svg+xml" class="cl-svg"></object>
	<!-- #endif -->
</template>

<script lang="ts" setup>
import { computed, watch, onMounted } from "vue";
import { getColor, isDark } from "@/cool";

// #ifdef APP
// @ts-ignore
import { CoolSvg } from "@/uni_modules/cool-svg";
// #endif

// 组件属性定义
const props = defineProps({
	/**
	 * SVG 数据源
	 * 支持格式：
	 * - 文件路径：'/static/icon.svg'
	 * - base64 数据：'data:image/svg+xml;base64,PHN2Zw...'
	 * - 标签 SVG：'<svg>...</svg>'
	 */
	src: {
		type: String,
		default: ""
	},
	/**
	 * SVG 填充颜色
	 * 支持格式：#hex、rgb()、rgba()、颜色名称
	 * 会自动替换 SVG 中 path 元素的 fill 属性
	 */
	color: {
		type: String,
		default: ""
	}
});

// 颜色值
const color = computed(() => {
	if (props.color == "none") {
		return "";
	}

	if (props.color != "") {
		if (props.color == "primary") {
			return getColor("primary-500");
		}

		return props.color;
	} else {
		return isDark.value ? "white" : "black";
	}
});

/**
 * 将 SVG 字符串转换为数据 URL
 * @param svgString 原始 SVG 字符串
 * @returns 转换后的数据 URL
 */
function svgToDataUrl(svgString: string): string {
	// 如果指定了颜色，替换 SVG 中所有 path 元素的 fill 属性
	if (color.value != "") {
		svgString = svgString.replace(
			/(<path\b[^>]*\bfill=")[^"]*("[^>]*>)/g,
			`$1${color.value}$2`
		);
	}

	let encodedSvg: string;
	// #ifdef APP
	// App 平台：简单的空格替换即可，无需完整 URL 编码
	encodedSvg = svgString.replace(/\+/g, "%20");
	// #endif
	// #ifndef APP
	// 非 App 平台：使用标准 URL 编码
	encodedSvg = encodeURIComponent(svgString)!.replace(/\+/g, "%20");
	// #endif

	// 确保返回完整的数据 URL 格式
	return encodedSvg.startsWith("data:image/svg+xml,")
		? encodedSvg
		: `data:image/svg+xml,${encodedSvg}`;
}

/**
 * 计算最终的 SVG 数据源
 * 自动判断数据类型并进行相应处理
 */
const svgSrc = computed((): string => {
	let val = props.src;

	if (val == "") {
		return "";
	}

	// 判断是否为 标签 SVG（以 <svg 开头）
	if (val.startsWith("<svg")) {
		return svgToDataUrl(val);
	}

	// #ifdef MP
	if (val.includes("fill")) {
		val = val.replace(/fill="[^"]*"/g, `fill="${color.value}"`);
	} else {
		val = val.replace("<svg ", `<svg fill="${color.value}" `);
	}
	// #endif

	// 其他情况直接返回原始数据源（文件路径、base64 等）
	return val;
});

/**
 * 生成符合 RFC4122 标准的 UUID v4
 * 用于 Web 平台创建唯一的元素 ID
 * @returns UUID 字符串
 */
function generateUuid(): string {
	const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
	const uuid: string[] = [];

	// 生成 36 位字符
	for (let i = 0; i < 36; i++) {
		const randomIndex = Math.floor(Math.random() * 16);
		const char = chars[i == 19 ? (randomIndex & 0x3) | 0x8 : randomIndex];
		uuid.push(char);
	}

	// 设置 RFC4122 标准要求的固定位
	uuid[8] = "-"; // 第一个连字符
	uuid[13] = "-"; // 第二个连字符
	uuid[18] = "-"; // 第三个连字符
	uuid[23] = "-"; // 第四个连字符
	uuid[14] = "4"; // 版本号 v4

	return uuid.join("");
}

// Web 平台使用的唯一元素 ID
const svgId = `cool-svg-${generateUuid()}`;

// #ifdef APP
// App 平台 SVG 渲染器实例
let svgRenderer: CoolSvg | null = null;

/**
 * App 平台原生视图初始化回调
 * @param e 原生视图初始化事件
 */
function onInit(e: UniNativeViewInitEvent) {
	svgRenderer = new CoolSvg(e.detail.element);

	// 立即加载 SVG 内容
	if (svgRenderer != null) {
		svgRenderer!.load(svgSrc.value, color.value);
	}
}

/**
 * 监听 SVG 数据源变化，重新渲染
 */
watch(svgSrc, (newSrc: string) => {
	if (svgRenderer != null && newSrc != "") {
		svgRenderer!.load(newSrc, color.value);
	}
});
// #endif

/**
 * 设置颜色
 */
function setColor() {
	if (color.value == "") {
		return;
	}

	// #ifdef WEB
	const element = document.getElementById(svgId) as HTMLObjectElement;
	if (element != null) {
		const set = () => {
			const svgDoc = element.getSVGDocument();

			if (svgDoc != null) {
				// 查找所有 path 元素并应用颜色
				const paths = svgDoc.querySelectorAll("path");
				paths?.forEach((path) => {
					path.setAttribute("fill", color.value);
				});
			}
		};

		if (element.getSVGDocument() != null) {
			set();
		} else {
			element.addEventListener("load", set);
		}
	}
	// #endif

	// #ifdef APP
	if (svgRenderer != null && svgSrc.value != "") {
		svgRenderer!.load(svgSrc.value, color.value);
	}
	// #endif
}

/**
 * 监听颜色变化，重新渲染
 */
watch(
	computed(() => [props.color, isDark.value]),
	() => {
		setColor();
	}
);

onMounted(() => {
	setColor();
});
</script>
