<script setup lang="ts">
import { computed } from 'vue';

import { Button, message } from 'ant-design-vue';

/**
 * JSON 实时预览面板
 * - 显示最终生成的 JSON 字符串（语法高亮，简单的 key/string 高亮）
 * - 提供「复制 JSON」按钮（一键拷贝到剪贴板）
 */
const props = defineProps<{
  /** 最终生成的 JSON 数据 */
  value: Record<string, any>;
}>();

const formattedJson = computed(() => {
  try {
    return JSON.stringify(props.value, null, 2);
  } catch {
    return '// JSON 序列化失败';
  }
});

/**
 * 简单的 JSON 语法高亮
 * 匹配 key / string / number / boolean 并套用不同颜色 span
 */
const highlightedHtml = computed(() => {
  const escape = (s: string) =>
    s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  const json = escape(formattedJson.value);
  return json
    .replace(
      /("(?:\\.|[^"\\])*")(\s*:)/g,
      '<span class="json-key">$1</span>$2',
    )
    .replace(
      /:\s*("(?:\\.|[^"\\])*")/g,
      ': <span class="json-string">$1</span>',
    )
    .replace(/:\s*(-?\d+(?:\.\d+)?)/g, ': <span class="json-number">$1</span>')
    .replace(/:\s*(true|false|null)/g, ': <span class="json-bool">$1</span>');
});

async function handleCopy() {
  try {
    await navigator.clipboard.writeText(formattedJson.value);
    message.success('JSON 已复制');
  } catch {
    message.error('复制失败，请手动选择');
  }
}
</script>

<template>
  <div class="json-preview">
    <div class="panel-header">
      <span class="title">JSON 预览</span>
      <Button size="small" type="link" @click="handleCopy">复制 JSON</Button>
    </div>
    <pre class="json-body" v-html="highlightedHtml" />
  </div>
</template>

<style scoped lang="scss">
.json-preview {
  display: flex;
  flex-direction: column;
  width: 280px;
  height: 100%;
  border-left: 1px solid var(--ant-color-border-secondary, #e5e6eb);
  /* JSON 代码面板保留 VS Code Dark+ 风格暗底（无论浅色/暗色主题） */
  background: #1e1e1e;
}

.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  border-bottom: 1px solid #374151;
  font-size: 13px;

  .title {
    font-weight: 600;
    color: #e5e7eb;
  }
}

.json-body {
  flex: 1;
  margin: 0;
  padding: 12px;
  overflow: auto;
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-size: 12px;
  line-height: 1.6;
  color: #d4d4d4;
  white-space: pre-wrap;
  word-break: break-all;
}

/* JSON 语法高亮颜色 */
:deep(.json-key) {
  color: #9cdcfe;
}

:deep(.json-string) {
  color: #ce9178;
}

:deep(.json-number) {
  color: #b5cea8;
}

:deep(.json-bool) {
  color: #569cd6;
}
</style>
