<template>
  <!-- JSON数据展示弹窗 -->
  <el-dialog
    v-model="dialogVisible"
    title="设备信息详情"
    width="60%"
    class="json-dialog"
    :before-close="handleClose"
  >
    <!-- 操作栏 -->
    <div class="json-toolbar">
      <el-button 
        type="primary" 
        link 
        @click="copyJson"
        :loading="copying"
        :icon="CopyDocument"
      >
        {{ copying ? '复制中...' : '复制JSON' }}
      </el-button>
      <!-- <el-button 
        type="primary" 
        link 
        @click="formatJson"
        :icon="Refresh"
      >
        格式化
      </el-button>
      <el-button 
        type="primary" 
        link 
        @click="compressJson"
        :icon="Minus"
      >
        压缩
      </el-button> -->
    </div>

    <!-- JSON内容展示区 -->
    <div class="json-content-wrapper">
      <pre 
        ref="jsonContentRef"
        class="json-content"
        :class="{ 'compressed': isCompressed }"
      ><code>{{ displayJson }}</code></pre>
    </div>

    <!-- 底部信息 -->
    <template #footer>
      <div class="dialog-footer">
        <span class="json-info">
          数据大小: {{ jsonSize }} | 
          字段数: {{ fieldCount }}
        </span>
        <el-button @click="handleClose">关闭</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue'
import { CopyDocument, Refresh, Minus } from '@element-plus/icons-vue'
import { useMessage } from '/@/hooks/message'

// 弹窗可见性
const dialogVisible = ref(false)

// JSON数据
const jsonData = ref<any>(null)

// 显示的JSON字符串
const displayJson = ref('')

// 是否压缩显示
const isCompressed = ref(false)

// 复制状态
const copying = ref(false)

// JSON内容引用
const jsonContentRef = ref<HTMLElement | null>(null)

// 计算JSON大小
const jsonSize = computed(() => {
  if (!displayJson.value) return '0 B'
  const size = new Blob([displayJson.value]).size
  if (size < 1024) return `${size} B`
  if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} KB`
  return `${(size / (1024 * 1024)).toFixed(2)} MB`
})

// 计算字段数量
const fieldCount = computed(() => {
  if (!jsonData.value) return 0
  try {
    const countFields = (obj: any): number => {
      if (obj === null || typeof obj !== 'object') return 1
      if (Array.isArray(obj)) {
        return obj.reduce((sum, item) => sum + countFields(item), 0)
      }
      return Object.keys(obj).length + 
        Object.values(obj).reduce((sum, value) => sum + countFields(value), 0)
    }
    return countFields(jsonData.value)
  } catch {
    return 0
  }
})

// 打开弹窗方法
const openDialog = (data: any) => {
  dialogVisible.value = true
  jsonData.value = data
  
  try {
    // 初始格式化显示
    // displayJson.value = JSON.stringify(data, null, 2)
    displayJson.value = data
    isCompressed.value = false
  } catch (error) {
    displayJson.value = '无效的JSON数据'
    useMessage().error('无法解析JSON数据')
  }
}

// 关闭弹窗
const handleClose = () => {
  dialogVisible.value = false
  jsonData.value = null
  displayJson.value = ''
}

// 复制JSON到剪贴板
const copyJson = async () => {
  if (!displayJson.value) return
  
  copying.value = true
  try {
    await navigator.clipboard.writeText(displayJson.value)
    useMessage().success('JSON数据已复制到剪贴板')
  } catch (error) {
    // 降级方案
    const textArea = document.createElement('textarea')
    textArea.value = displayJson.value
    document.body.appendChild(textArea)
    textArea.select()
    document.execCommand('copy')
    document.body.removeChild(textArea)
    useMessage().success('JSON数据已复制到剪贴板')
  } finally {
    copying.value = false
  }
}

// 格式化JSON
const formatJson = () => {
  if (!jsonData.value) return
  try {
    displayJson.value = JSON.stringify(jsonData.value, null, 2)
    isCompressed.value = false
    useMessage().success('JSON已格式化')
  } catch (error) {
    useMessage().error('格式化失败')
  }
}

// 压缩JSON
const compressJson = () => {
  if (!jsonData.value) return
  try {
    displayJson.value = JSON.stringify(jsonData.value)
    isCompressed.value = true
    useMessage().success('JSON已压缩')
  } catch (error) {
    useMessage().error('压缩失败')
  }
}

// 暴露方法给父组件
defineExpose({
  openDialog
})
</script>

<style scoped lang="scss">
.json-dialog {
  :deep(.el-dialog__body) {
    padding: 10px 20px;
  }
}

.json-toolbar {
  padding: 10px 0;
  border-bottom: 1px solid #eee;
  margin-bottom: 15px;
  
  .el-button {
    margin-right: 15px;
  }
}

.json-content-wrapper {
  min-height: 300px;
  max-height: 50vh;
  overflow: auto;
  border: 1px solid #eee;
  border-radius: 4px;
  background-color: #f8f9fa;
  
  // 自定义滚动条
  &::-webkit-scrollbar {
    width: 6px;
    height: 6px;
  }
  
  &::-webkit-scrollbar-thumb {
    background-color: #c1c1c1;
    border-radius: 3px;
  }
  
  &::-webkit-scrollbar-track {
    background-color: #f1f1f1;
  }
}

.json-content {
  margin: 0;
  padding: 15px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.5;
  color: #333;
  background-color: transparent;
  white-space: pre-wrap;
  word-break: break-all;
  
  &.compressed {
    line-height: 1.2;
  }
  
  code {
    font-family: inherit;
  }
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 15px;
  border-top: 1px solid #eee;
}

.json-info {
  font-size: 12px;
  color: #999;
}
</style>