import { t as e } from "./utils-C1xOyiTe.js";
import { l as t, r as n, t as r, u as i } from "./dialog-DisDZkkN.js";
import { Fragment as a, createContext as o, forwardRef as s, useCallback as c, useContext as l, useEffect as u, useRef as d, useState as f } from "react";
import { FileText as p, Loader2 as m, Search as h, X as g } from "lucide-react";
import { useNavigate as _ } from "react-router-dom";
import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
import x from "flexsearch";
//#region src/lib/search/runtime/search-engine.ts
var S = 20, C = 150, w = class {
	index;
	sections = /* @__PURE__ */ new Map();
	initialized = !1;
	constructor() {
		this.index = new x.Index({
			tokenize: "full",
			resolution: 9,
			cache: 100
		});
	}
	init(e) {
		this.clear();
		for (let t of e.sections) this.sections.set(t.id, t), this.index.add(t.id, t.tokens.join(" "));
		this.initialized = !0;
	}
	clear() {
		this.sections.clear(), this.index = new x.Index({
			tokenize: "full",
			resolution: 9,
			cache: 100
		}), this.initialized = !1;
	}
	search(e) {
		if (!this.initialized) return [];
		let { query: t, version: n, limit: r = S, snippetLength: i = C } = e, a = t.toLowerCase().trim();
		if (!a) return [];
		let o = Math.max(r * 5, r);
		return this.index.search(a, { limit: o }).map((e) => {
			let t = this.sections.get(e);
			if (!t) return null;
			if (n) {
				if (t.version && t.version !== n) return null;
			} else if (t.version) return null;
			return {
				id: t.id,
				pageTitle: t.pageTitle,
				sectionTitle: t.sectionTitle,
				snippet: this.generateSnippet(t.content, a, i),
				url: t.url,
				score: 1
			};
		}).filter((e) => e !== null).slice(0, r);
	}
	generateSnippet(e, t, n) {
		if (!e) return "";
		let r = e.toLowerCase(), i = t.split(/\s+/).filter(Boolean), a = 0;
		for (let e of i) {
			let t = r.indexOf(e);
			if (t !== -1) {
				a = t;
				break;
			}
		}
		let o = Math.max(0, a - 30), s = Math.min(e.length, o + n), c = e.slice(o, s);
		return o > 0 && (c = "..." + c), s < e.length && (c += "..."), c;
	}
	isInitialized() {
		return this.initialized;
	}
	getSectionCount() {
		return this.sections.size;
	}
}, T = new w();
//#endregion
//#region src/lib/search/runtime/highlighter.ts
function E(e, t) {
	if (!e || t.length === 0) return [{
		text: e,
		highlighted: !1
	}];
	let n = e.toLowerCase(), r = [];
	for (let e of t) {
		let t = e.toLowerCase(), i = 0;
		for (;;) {
			let a = n.indexOf(t, i);
			if (a === -1) break;
			r.push({
				start: a,
				end: a + e.length
			}), i = a + 1;
		}
	}
	if (r.length === 0) return [{
		text: e,
		highlighted: !1
	}];
	let i = O(r), a = [], o = 0;
	for (let t of i) t.start > o && a.push({
		text: e.slice(o, t.start),
		highlighted: !1
	}), a.push({
		text: e.slice(t.start, t.end),
		highlighted: !0
	}), o = t.end;
	return o < e.length && a.push({
		text: e.slice(o),
		highlighted: !1
	}), a;
}
function D(e, t, n = "mark") {
	if (!e || t.length === 0) return e;
	let r = e.toLowerCase(), i = [];
	for (let e of t) {
		let t = e.toLowerCase(), n = 0;
		for (;;) {
			let a = r.indexOf(t, n);
			if (a === -1) break;
			i.push({
				start: a,
				end: a + e.length
			}), n = a + 1;
		}
	}
	if (i.length === 0) return e;
	let a = O(i), o = "", s = 0;
	for (let t of a) o += e.slice(s, t.start), o += `<${n}>`, o += e.slice(t.start, t.end), o += `</${n}>`, s = t.end;
	return o += e.slice(s), o;
}
function O(e) {
	if (e.length === 0) return [];
	let t = [...e].sort((e, t) => e.start - t.start), n = [t[0]];
	for (let e = 1; e < t.length; e++) {
		let r = t[e], i = n[n.length - 1];
		r.start <= i.end ? i.end = Math.max(i.end, r.end) : n.push(r);
	}
	return n;
}
function k(e, t, n = {}) {
	let { maxLength: r = 120, contextBefore: i = 30, contextAfter: a = 80 } = n;
	if (!e) return "";
	if (t.length === 0) return e.slice(0, r) + (e.length > r ? "..." : "");
	let o = e.toLowerCase(), s = -1, c = "";
	for (let e of t) {
		let t = o.indexOf(e.toLowerCase());
		t !== -1 && (s === -1 || t < s) && (s = t, c = e);
	}
	if (s === -1) return e.slice(0, r) + (e.length > r ? "..." : "");
	let l = Math.max(0, s - i), u = Math.min(e.length, s + c.length + a), d = e.slice(l, u);
	return l > 0 && (d = "..." + d), u < e.length && (d += "..."), d;
}
function A(e, t, n = {}) {
	return D(k(e, t, n), t, n.tag || "mark");
}
function j(e, t, n = {}) {
	return E(k(e, t, n), t);
}
function M(e) {
	return e.toLowerCase().split(/[\s\-_]+/).filter((e) => e.length > 0);
}
//#endregion
//#region src/components/search/SearchProvider.tsx
var N = o(null);
function P() {
	let e = l(N);
	if (!e) throw Error("useSearch must be used within a SearchProvider");
	return e;
}
function F({ children: e, lang: t = "zh-cn", version: n, enabled: r = !0, maxResults: i = 20, snippetLength: a, enableHotkeys: o = !0 }) {
	let [s, l] = f(!1), [p, m] = f(!1), [h, g] = f(null), [_, v] = f([]), [b, x] = f(""), [S, C] = f(!1), T = d(null), E = d(null), D = d(null), O = d(!1);
	u(() => (T.current = new w(), () => {
		T.current &&= (T.current.clear(), null);
	}), []), u(() => {
		D.current && D.current !== t && (l(!1), D.current = null, v([]), x(""), T.current && T.current.clear());
	}, [t]), u(() => {
		v([]);
	}, [n]);
	let k = c(async () => {
		if (!(s && D.current === t || O.current || !r)) {
			O.current = !0, m(!0), g(null);
			try {
				let e = await fetch(`/search-index-${t}.json`);
				if (!e.ok) throw Error(`Failed to load search index: ${e.status}`);
				let n = await e.json();
				T.current && T.current.init(n), D.current = t, l(!0);
			} catch (e) {
				g(e instanceof Error ? e.message : "Failed to load search index");
			} finally {
				m(!1), O.current = !1;
			}
		}
	}, [
		t,
		s,
		r
	]), A = c(async (e) => {
		if (!e.trim()) return v([]), [];
		T.current?.isInitialized() || await k();
		let r = {
			query: e,
			lang: t,
			version: n,
			limit: i,
			snippetLength: a
		};
		if (T.current) {
			let e = T.current.search(r);
			return v(e), e;
		}
		return [];
	}, [
		t,
		n,
		k,
		i,
		a
	]);
	u(() => {
		if (!b.trim()) {
			v([]);
			return;
		}
		return E.current && clearTimeout(E.current), E.current = setTimeout(() => {
			A(b);
		}, 150), () => {
			E.current && clearTimeout(E.current);
		};
	}, [b, A]), u(() => {
		S && !s && !O.current && k();
	}, [
		S,
		s,
		k
	]), u(() => {
		if (!o) return;
		let e = (e) => {
			(e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k" && (e.preventDefault(), C((e) => !e)), e.key === "Escape" && S && C(!1);
		};
		return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
	}, [o, S]);
	let j = {
		isLoaded: s,
		isLoading: p,
		error: h,
		search: A,
		results: _,
		query: b,
		setQuery: x,
		open: S,
		setOpen: C,
		loadIndex: k
	};
	return /* @__PURE__ */ y(N.Provider, {
		value: j,
		children: e
	});
}
//#endregion
//#region src/components/search/SearchInput.tsx
var I = s(({ value: t, onChange: n, onClear: r, className: i, placeholder: a, ...o }, s) => /* @__PURE__ */ b("div", {
	className: "flex items-center gap-3 px-4 py-3 border-b",
	children: [
		/* @__PURE__ */ y(h, { className: "h-5 w-5 shrink-0 text-muted-foreground" }),
		/* @__PURE__ */ y("input", {
			ref: s,
			type: "text",
			value: t,
			onChange: (e) => n(e.target.value),
			placeholder: a || "搜索文档...",
			className: e("flex-1 bg-transparent text-base outline-none placeholder:text-muted-foreground", i),
			...o
		}),
		t && r && /* @__PURE__ */ y("button", {
			type: "button",
			onClick: r,
			className: "p-1 rounded hover:bg-muted transition-colors",
			children: /* @__PURE__ */ y(g, { className: "h-4 w-4 text-muted-foreground" })
		})
	]
}));
I.displayName = "SearchInput";
//#endregion
//#region src/components/search/SearchItem.tsx
function L({ segments: e }) {
	return /* @__PURE__ */ y(v, { children: e.map((e, t) => e.highlighted ? /* @__PURE__ */ y("mark", {
		className: "bg-primary/20 text-foreground rounded-sm px-0.5",
		children: e.text
	}, t) : /* @__PURE__ */ y(a, { children: e.text }, t)) });
}
var R = s(({ result: t, query: n, isSelected: r, onClick: i, onMouseEnter: a }, o) => {
	let s = M(n), c = j(t.sectionTitle, s, {
		maxLength: 100,
		contextBefore: 0,
		contextAfter: 0
	}), l = j(t.snippet, s, { maxLength: 150 });
	return /* @__PURE__ */ b("div", {
		ref: o,
		onClick: i,
		onMouseEnter: a,
		className: e("flex items-start gap-3 px-4 py-3 cursor-pointer transition-all duration-200 border-l-2 rounded-r-md mx-2", "hover:shadow-sm hover:translate-x-0.5", r ? "bg-accent/80 border-l-primary shadow-md scale-[1.02] translate-x-1" : "hover:bg-muted/50 border-l-transparent"),
		children: [/* @__PURE__ */ y(p, { className: "h-4 w-4 mt-0.5 shrink-0 text-muted-foreground" }), /* @__PURE__ */ b("div", {
			className: "flex-1 min-w-0",
			children: [
				/* @__PURE__ */ y("div", {
					className: "flex items-center gap-2",
					children: /* @__PURE__ */ y("span", {
						className: "font-medium text-sm truncate",
						children: /* @__PURE__ */ y(L, { segments: c })
					})
				}),
				t.pageTitle !== t.sectionTitle && /* @__PURE__ */ y("div", {
					className: "text-xs text-muted-foreground truncate mt-0.5",
					children: t.pageTitle
				}),
				l.length > 0 && l.some((e) => e.text) && /* @__PURE__ */ y("div", {
					className: "text-xs text-muted-foreground mt-1 line-clamp-2",
					children: /* @__PURE__ */ y(L, { segments: l })
				})
			]
		})]
	});
});
R.displayName = "SearchItem";
//#endregion
//#region src/components/search/SearchResults.tsx
function z({ results: e, query: t, onSelect: n }) {
	let [r, i] = f(0), a = d(null), o = d(null);
	u(() => {
		i(0);
	}, [e]), u(() => {
		if (o.current && a.current) {
			let e = a.current, t = o.current, n = e.getBoundingClientRect(), r = t.getBoundingClientRect();
			(r.bottom > n.bottom || r.top < n.top) && t.scrollIntoView({ block: "nearest" });
		}
	}, [r]), u(() => {
		let t = (t) => {
			if (t.key === "ArrowDown") t.preventDefault(), i((t) => Math.min(t + 1, e.length - 1));
			else if (t.key === "ArrowUp") t.preventDefault(), i((e) => Math.max(e - 1, 0));
			else if (t.key === "Enter") {
				t.preventDefault();
				let i = e[r];
				i && n(i.url);
			}
		};
		return document.addEventListener("keydown", t), () => document.removeEventListener("keydown", t);
	}, [
		e,
		r,
		n
	]);
	let s = (e) => {
		n(e.url);
	};
	return /* @__PURE__ */ y("div", {
		ref: a,
		className: "py-2",
		children: e.map((e, n) => /* @__PURE__ */ y(R, {
			result: e,
			query: t,
			isSelected: n === r,
			ref: n === r ? o : null,
			onClick: () => s(e),
			onMouseEnter: () => i(n)
		}, e.id))
	});
}
//#endregion
//#region src/components/search/SearchDialog.tsx
function B({ placeholder: e }) {
	let { open: a, setOpen: o, query: s, setQuery: c, results: l, isLoading: f, error: p, isLoaded: h } = P(), g = _(), v = d(null);
	return u(() => {
		a && v.current && setTimeout(() => v.current?.focus(), 0);
	}, [a]), u(() => {
		a || c("");
	}, [a, c]), /* @__PURE__ */ y(r, {
		open: a,
		onOpenChange: (e) => {
			o(e);
		},
		children: /* @__PURE__ */ b(n, {
			className: "overflow-hidden p-0 shadow-lg max-w-xl top-[15%] translate-y-0",
			showCloseButton: !1,
			children: [
				/* @__PURE__ */ y(i, { children: "搜索文档" }),
				/* @__PURE__ */ y(t, { children: "搜索文档内容" }),
				/* @__PURE__ */ b("div", {
					className: "flex flex-col",
					children: [
						/* @__PURE__ */ y(I, {
							ref: v,
							value: s,
							onChange: c,
							placeholder: e,
							onClear: () => c("")
						}),
						/* @__PURE__ */ b("div", {
							className: "max-h-[60vh] overflow-y-auto border-t",
							children: [
								f && !h && /* @__PURE__ */ y("div", {
									className: "flex items-center justify-center py-12",
									children: /* @__PURE__ */ y(m, { className: "h-6 w-6 animate-spin text-muted-foreground" })
								}),
								p && /* @__PURE__ */ y("div", {
									className: "px-4 py-8 text-center text-sm text-muted-foreground",
									children: p
								}),
								h && !f && !s && /* @__PURE__ */ y("div", {
									className: "px-4 py-8 text-center text-sm text-muted-foreground",
									children: "输入关键词搜索文档"
								}),
								h && s && l.length === 0 && !f && /* @__PURE__ */ b("div", {
									className: "px-4 py-8 text-center text-sm text-muted-foreground",
									children: [
										"未找到 \"",
										s,
										"\" 相关结果"
									]
								}),
								l.length > 0 && /* @__PURE__ */ y(z, {
									results: l,
									query: s,
									onSelect: (e) => {
										g(e), o(!1);
									}
								})
							]
						}),
						/* @__PURE__ */ b("div", {
							className: "flex items-center justify-between border-t px-4 py-2 text-xs text-muted-foreground bg-muted/30",
							children: [/* @__PURE__ */ b("div", {
								className: "flex items-center gap-4",
								children: [/* @__PURE__ */ b("span", {
									className: "flex items-center gap-1",
									children: [/* @__PURE__ */ y("kbd", {
										className: "px-1.5 py-0.5 rounded bg-muted border text-[10px]",
										children: "↵"
									}), "选择"]
								}), /* @__PURE__ */ b("span", {
									className: "flex items-center gap-1",
									children: [/* @__PURE__ */ y("kbd", {
										className: "px-1.5 py-0.5 rounded bg-muted border text-[10px]",
										children: "↑↓"
									}), "导航"]
								})]
							}), /* @__PURE__ */ b("span", {
								className: "flex items-center gap-1",
								children: [/* @__PURE__ */ y("kbd", {
									className: "px-1.5 py-0.5 rounded bg-muted border text-[10px]",
									children: "esc"
								}), "关闭"]
							})]
						})
					]
				})
			]
		})
	});
}
//#endregion
export { F as a, A as c, w as d, T as f, I as i, D as l, z as n, P as o, R as r, k as s, B as t, M as u };
