import useXComponentConfig from "../_utils/hooks/use-x-component-config.js";
import localeValues from "../locale/en_US.js";
import useLocale from "../locale/useLocale.js";
import FolderDirectoryTree from "./DirectoryTree.js";
import style_default from "./style/index.js";
import FilePreview from "./FilePreview.js";
import { computed, createVNode, defineComponent, mergeProps, ref, useAttrs, watch } from "vue";
import { useConfig } from "antdv-next/config-provider/context";
import { Flex, Splitter, SplitterPanel } from "antdv-next";
//#region components/folder/Folder.tsx
function findNode(nodes, segments, index = 0) {
	if (index >= segments.length) return void 0;
	const current = segments[index];
	for (const node of nodes) if (node.path === current) {
		if (index === segments.length - 1) return node;
		return node.children ? findNode(node.children, segments, index + 1) : void 0;
	}
}
function findNodeAndValidate(treeData, path, validateAsFile = false) {
	if (!path) return {
		node: void 0,
		isValid: false
	};
	const segments = Array.isArray(path) ? path.filter(Boolean) : path.split("/").filter(Boolean);
	if (segments.length === 0) return {
		node: void 0,
		isValid: false
	};
	const node = findNode(treeData, segments);
	return {
		node,
		isValid: validateAsFile ? !!node && (!node?.children || node.children.length === 0) : !!node
	};
}
var XFolder = /* @__PURE__ */ defineComponent({
	name: "AxFolder",
	inheritAttrs: false,
	props: {
		prefixCls: {
			type: String,
			default: "antd-folder"
		},
		rootClass: {
			type: String,
			default: ""
		},
		class: {
			type: [
				String,
				Array,
				Object
			],
			default: void 0
		},
		style: {
			type: [
				String,
				Object,
				Array
			],
			default: void 0
		},
		classes: {
			type: Object,
			default: () => ({})
		},
		styles: {
			type: Object,
			default: () => ({})
		},
		treeData: {
			type: Array,
			default: () => []
		},
		directoryIcons: {
			type: [Boolean, Object],
			default: void 0
		},
		selectable: {
			type: Boolean,
			default: true
		},
		selectedFile: {
			type: Array,
			default: void 0
		},
		defaultSelectedFile: {
			type: Array,
			default: void 0
		},
		directoryTreeWith: {
			type: [Number, String],
			default: 278
		},
		emptyRender: {
			type: [
				Boolean,
				String,
				Number,
				Object,
				Array,
				Function
			],
			default: void 0
		},
		previewRender: {
			type: [
				String,
				Number,
				Object,
				Array,
				Function
			],
			default: void 0
		},
		defaultExpandedPaths: {
			type: Array,
			default: void 0
		},
		expandedPaths: {
			type: Array,
			default: void 0
		},
		defaultExpandAll: {
			type: Boolean,
			default: true
		},
		fileContentService: {
			type: Object,
			default: void 0
		},
		directoryTitle: {
			type: [
				Boolean,
				String,
				Number,
				Object,
				Array,
				Function
			],
			default: void 0
		},
		previewTitle: {
			type: [
				Boolean,
				String,
				Number,
				Object,
				Array,
				Function
			],
			default: void 0
		}
	},
	emits: {
		selectedFileChange: (_file) => true,
		fileClick: (_path, _content) => true,
		folderClick: (_path) => true,
		expandedPathsChange: (_paths) => true,
		"update:selectedFile": (_paths) => true,
		"update:expandedPaths": (_paths) => true
	},
	slots: Object,
	setup(props, { emit, expose, slots }) {
		const attrs = useAttrs();
		const configCtx = useConfig();
		const contextConfig = useXComponentConfig("folder");
		const [hashId, cssVarCls] = style_default(computed(() => props.prefixCls));
		const [locale] = useLocale("Folder", localeValues.Folder);
		const rootRef = ref();
		const isValidSelectedFile = (filePath) => !!(filePath && filePath.length > 0 && findNodeAndValidate(props.treeData, filePath, true).isValid);
		const innerSelectedFile = ref(isValidSelectedFile(props.defaultSelectedFile) ? props.defaultSelectedFile ?? [] : []);
		const mergedSelectedFile = computed(() => props.selectedFile !== void 0 ? props.selectedFile : innerSelectedFile.value);
		const validSelectedFile = ref(isValidSelectedFile(props.selectedFile ?? props.defaultSelectedFile));
		watch(() => [
			props.selectedFile,
			props.defaultSelectedFile,
			props.treeData
		], () => {
			validSelectedFile.value = isValidSelectedFile(props.selectedFile ?? props.defaultSelectedFile ?? []);
		}, { deep: true });
		const innerExpandedPaths = ref(props.defaultExpandedPaths);
		const mergedExpandedPaths = computed(() => props.expandedPaths !== void 0 ? props.expandedPaths : innerExpandedPaths.value);
		const fileContent = ref("");
		const loadingContent = ref(false);
		const loadFileContent = async () => {
			if (!validSelectedFile.value || mergedSelectedFile.value.length === 0) {
				fileContent.value = "";
				loadingContent.value = false;
				return;
			}
			const filePath = mergedSelectedFile.value.join("/");
			const segments = filePath.split("/").filter((s) => s !== "");
			const { node } = findNodeAndValidate(props.treeData, segments);
			if (props.fileContentService) {
				loadingContent.value = true;
				try {
					fileContent.value = await props.fileContentService.loadFileContent(filePath);
				} catch (error) {
					fileContent.value = `// ${locale.value.loadError}: ${error instanceof Error ? error.message : "Unknown error"}`;
				} finally {
					loadingContent.value = false;
				}
				return;
			}
			if (node?.content) {
				fileContent.value = node.content;
				loadingContent.value = false;
				return;
			}
			fileContent.value = `// ${locale.value.noService}`;
			loadingContent.value = false;
		};
		watch([
			validSelectedFile,
			mergedSelectedFile,
			() => props.treeData,
			() => props.fileContentService
		], () => {
			loadFileContent();
		}, {
			immediate: true,
			deep: true
		});
		const handleSelect = (keys, info) => {
			const nodes = Array.isArray(info?.selectedNodes) ? info.selectedNodes : info?.selectedNodes ? [info.selectedNodes] : [];
			if (nodes.some((node) => !node?.isLeaf)) {
				if (nodes.length === 1) emit("folderClick", nodes[0]?.path ?? "");
				return;
			}
			const pathArray = keys[0]?.split("/").filter(Boolean) ?? [];
			if (pathArray.length === 0) return;
			const selectedNode = nodes[0];
			const fileName = selectedNode?.title;
			const fileContentValue = selectedNode?.content;
			emit("selectedFileChange", {
				path: pathArray,
				title: fileName,
				content: fileContentValue
			});
			if (!(props.selectedFile !== void 0)) {
				validSelectedFile.value = true;
				innerSelectedFile.value = pathArray;
				emit("update:selectedFile", pathArray);
			}
			if (nodes.length === 1) {
				const node = nodes[0];
				emit("fileClick", node?.path ?? "", node?.content);
			}
		};
		const handleExpand = (keys) => {
			const newPaths = keys ?? [];
			if (props.expandedPaths === void 0) innerExpandedPaths.value = newPaths;
			emit("update:expandedPaths", newPaths);
			emit("expandedPathsChange", newPaths);
		};
		const domAttrs = computed(() => {
			const { class: _c, style: _s, ...rest } = attrs;
			return rest;
		});
		expose({ get nativeElement() {
			return rootRef.value;
		} });
		const mergedDirectoryTitle = computed(() => slots.directoryTitle ?? props.directoryTitle);
		const mergedPreviewTitle = computed(() => slots.previewTitle ?? props.previewTitle);
		const mergedPreviewRender = computed(() => {
			if (slots.previewRender) return (file, info) => slots.previewRender({
				file,
				originNode: info.originNode
			});
			return props.previewRender;
		});
		const mergedEmptyRender = computed(() => slots.emptyRender ?? props.emptyRender);
		return () => {
			const prefixCls = props.prefixCls;
			return createVNode("div", mergeProps({ "ref": rootRef }, domAttrs.value, {
				"class": [
					prefixCls,
					contextConfig.value.classes?.root,
					props.rootClass,
					props.classes?.root,
					hashId.value,
					cssVarCls.value,
					attrs.class,
					props.class,
					{
						[`${prefixCls}-rtl`]: configCtx.value.direction === "rtl",
						[`${prefixCls}-selectable`]: props.selectable
					}
				],
				"style": [
					contextConfig.value.style,
					contextConfig.value.styles?.root,
					props.styles?.root,
					attrs.style,
					props.style
				]
			}), [createVNode(Flex, { "class": `${prefixCls}-container` }, { default: () => [createVNode(Splitter, null, { default: () => [createVNode(SplitterPanel, { "defaultSize": props.directoryTreeWith }, { default: () => [createVNode("div", {
				"class": [`${prefixCls}-directory-tree`, props.classes?.directoryTree],
				"style": [contextConfig.value.styles?.directoryTree, props.styles?.directoryTree]
			}, [createVNode(FolderDirectoryTree, {
				"prefixCls": prefixCls,
				"directoryIcons": props.directoryIcons,
				"treeData": props.treeData,
				"selectedKeys": props.selectable && mergedSelectedFile.value && validSelectedFile.value ? [mergedSelectedFile.value.join("/")] : [],
				"classes": props.classes,
				"styles": props.styles,
				"expandedKeys": mergedExpandedPaths.value,
				"defaultExpandAll": props.defaultExpandAll,
				"directoryTitle": mergedDirectoryTitle.value,
				"onSelect": handleSelect,
				"onExpand": handleExpand
			}, null)])] }), createVNode(SplitterPanel, null, { default: () => [createVNode(FilePreview, {
				"prefixCls": prefixCls,
				"classes": props.classes,
				"styles": props.styles,
				"selectedFile": validSelectedFile.value ? mergedSelectedFile.value : [],
				"fileContent": fileContent.value,
				"loading": loadingContent.value,
				"previewTitle": mergedPreviewTitle.value,
				"previewRender": mergedPreviewRender.value,
				"emptyRender": mergedEmptyRender.value,
				"getFileNode": (path) => {
					if (!path || path.length === 0) return void 0;
					const { node } = findNodeAndValidate(props.treeData, path);
					return node ? {
						title: node.title,
						path: node.path,
						content: node.content
					} : void 0;
				}
			}, null)] })] })] })]);
		};
	}
});
//#endregion
export { XFolder as default };
