<template v-if="text">
	<div class="cl-code-json__wrap" v-if="popover">
		<el-popover
			width="auto"
			placement="right"
			popper-class="cl-code-json__popper"
			effect="dark"
		>
			<template #reference>
				<span class="cl-code-json__text">{{ text }}</span>
			</template>

			<viewer />
		</el-popover>
	</div>

	<viewer v-else>
		<template #op>
			<slot name="op"> </slot>
		</template>
	</viewer>
</template>

<script lang="tsx" setup>
defineOptions({
	name: 'cl-code-json'
});

import { useClipboard } from '@vueuse/core';
import { ElMessage } from 'element-plus';
import { isObject, isString } from 'lodash-es';
import { computed, defineComponent } from 'vue';
import { useI18n } from 'vue-i18n';

const props = defineProps({
	content: null,
	modelValue: null,
	popover: Boolean,
	height: {
		type: [Number, String],
		default: '100%'
	},
	maxHeight: {
		type: [Number, String],
		default: 300
	},
	title: String
});

const { copy } = useClipboard();
const { t } = useI18n();

// 文本
const text = computed(() => {
	const v = props.modelValue || props.content;

	if (isString(v)) {
		return v;
	} else if (isObject(v)) {
		return JSON.stringify(v, null, 4);
	} else {
		return String(v);
	}
});

// 视图
const viewer = defineComponent({
	setup(_, { slots }) {
		function toCopy() {
			copy(text.value);
			ElMessage.success('复制成功');
		}

		return () => {
			return (
				<div class="cl-code-json">
					<div class="cl-code-json__op">
						{text.value != '{}' && (
							<el-button type="success" size="small" onClick={toCopy}>
								{t('复制')}
							</el-button>
						)}

						{slots.op && slots.op()}
					</div>

					{props.title && <div class="cl-code-json__title">{props.title}</div>}

					<el-scrollbar
						class="cl-code-json__content"
						max-height={props.maxHeight}
						height={props.height}
					>
						<pre>
							<code>{text.value}</code>
						</pre>
					</el-scrollbar>
				</div>
			);
		};
	}
});
</script>

<style lang="scss">
.cl-code-json {
	position: relative;
	min-width: 200px;
	max-width: 500px;
	font-size: 14px;

	&__op {
		position: absolute;
		right: 8px;
		top: 8px;
		z-index: 9;
	}

	&__title {
		padding: 10px;
		font-size: 12px;
		color: var(--el-text-color-regular);

		& + .cl-code-json__content {
			padding-top: 0;
		}
	}

	&__content {
		padding: 10px;

		code {
			white-space: pre-wrap;
		}
	}

	&__wrap {
		.cl-code-json__text {
			display: block;
			text-overflow: ellipsis;
			white-space: nowrap;
			overflow: hidden;
			cursor: pointer;

			&:hover {
				color: var(--el-color-primary);
			}
		}
	}

	&__popper {
		padding: 0 !important;
		border-radius: 8px !important;
	}
}
</style>
