<template>
	<p class="p-regular-rereg">
		<span class="text-regular" v-for="(segment, index) in processedText" :key="index">
			<span
				v-if="segment.isEntity"
				@click="$emit('onEntityClick', segment.entity)"
				:class="['entity-link', { 'keyword-highlight': segment.isKeywordHit }]"
			>
				{{ segment.entity?.text_span }}
				<img :src="SearchIcon" :width="10" :height="10" alt="search" />
			</span>
			<span v-else>
				<span :class="{ 'keyword-highlight': segment.isKeywordHit }">{{ segment.text }}</span>
			</span>
		</span>
	</p>
</template>
<script lang="ts" setup>
import { TextEntity } from "@/api/intelligent";
import { ref, watch, onMounted } from "vue";
import SearchIcon from "./images/search.png";

export interface ProcessedTextSegment {
	text: string;
	isEntity: boolean;
	entity?: TextEntity;
	isKeywordHit?: boolean;
}
const props = defineProps({
	text: {
		type: String,
		default: ""
	},
	entities: {
		type: Array<TextEntity>,
		default: () => []
	},
	highlight: {
		type: String,
		default: ""
	}
});
const emit = defineEmits(["onEntityClick"]);
// 处理后的文本段
const processedText = ref<ProcessedTextSegment[]>([]);

const normalizeKeyword = (value: unknown) => String(value ?? "").trim();

const getKeywordMatches = (text: string, keyword: string) => {
	if (!keyword) return [{ text, isKeywordHit: false }];
	const lowerText = text.toLowerCase();
	const lowerKeyword = keyword.toLowerCase();
	if (!lowerKeyword) return [{ text, isKeywordHit: false }];
	const parts: Array<{ text: string; isKeywordHit: boolean }> = [];
	let start = 0;
	while (start < text.length) {
		const index = lowerText.indexOf(lowerKeyword, start);
		if (index === -1) {
			parts.push({ text: text.slice(start), isKeywordHit: false });
			break;
		}
		if (index > start) {
			parts.push({ text: text.slice(start, index), isKeywordHit: false });
		}
		parts.push({ text: text.slice(index, index + keyword.length), isKeywordHit: true });
		start = index + keyword.length;
	}
	return parts.filter(part => part.text);
};

// 处理文本，识别并替换实体
const processText = () => {
	if (!props.text || !props.entities) {
		// console.log('props.text', props.entities.length)
		processedText.value = [{ text: "", isEntity: false }];
		return;
	}

	const result = [];
	let currentPosition = 0;
	const keyword = normalizeKeyword(props.highlight);

	// 按实体文本长度排序，优先匹配长文本
	const sortedEntities = [...props.entities].sort((a, b) => b.text_span.length - a.text_span.length);

	while (currentPosition < props.text.length) {
		let matched = false;

		for (const entity of sortedEntities) {
			const entityText = entity.text_span;
			const endPosition = currentPosition + entityText.length;

			if (props.text.substring(currentPosition, endPosition) === entityText) {
				// 如果当前位置是实体，添加到结果
				result.push({
					isEntity: true,
					entity: { ...entity },
					isKeywordHit: keyword ? entityText.toLowerCase().includes(keyword.toLowerCase()) : false
				});
				currentPosition = endPosition;
				matched = true;
				break;
			}
		}

		if (!matched) {
			// 如果不是实体，收集普通文本
			let nextEntityStart = props.text.length;

			for (const entity of sortedEntities) {
				const pos = props.text.indexOf(entity.text_span, currentPosition);
				if (pos !== -1 && pos < nextEntityStart) {
					nextEntityStart = pos;
				}
			}

			if (nextEntityStart > currentPosition) {
				const plainText = props.text.substring(currentPosition, nextEntityStart);
				const parts = getKeywordMatches(plainText, keyword);
				parts.forEach(part => {
					result.push({
						text: part.text,
						isEntity: false,
						isKeywordHit: part.isKeywordHit
					});
				});
				currentPosition = nextEntityStart;
			} else {
				// 没有更多实体，添加剩余文本
				const remainingText = props.text.substring(currentPosition);
				if (remainingText) {
					const parts = getKeywordMatches(remainingText, keyword);
					parts.forEach(part => {
						result.push({
							text: part.text,
							isEntity: false,
							isKeywordHit: part.isKeywordHit
						});
					});
				}
				currentPosition = props.text.length;
			}
		}
	}

	processedText.value = result;
};
// 监听文本和实体变化
watch(() => props.text, processText);
watch(() => props.entities, processText, { deep: true });
watch(() => props.highlight, processText);

// 初始化处理
onMounted(processText);
</script>
<style lang="scss" scoped>
@use "@/styles/common.scss";

.keyword-highlight {
	background: rgba(255, 199, 0, 0.35);
	border-radius: 2px;
}

.entity-link {
	color: var(--color-primary-100);
	&:hover {
		cursor: pointer;
	}
}

.p-regular-rereg {
	text-indent: 2em;
	margin: 4px 0;
}
</style>
