<template>
  <el-dialog
    :model-value="visible"
    @update:model-value="$emit('update:visible', $event)"
    title="预览 Prompt 模板"
    width="900px"
    :close-on-click-modal="false"
    destroy-on-close
  >
    <div class="preview-dialog-content">
      <el-row :gutter="20">
        <el-col :span="10">
          <div class="variable-section">
            <h4>变量设置</h4>
            <el-form label-width="100px" size="small">
              <el-form-item
                v-for="variable in allVariables"
                :key="variable.name"
                :label="variable.name"
              >
                <el-input
                  v-model="variableValues[variable.name]"
                  :placeholder="variable.description || variable.default_value"
                  @input="handleVariableChange"
                />
              </el-form-item>
            </el-form>

            <el-divider>测试数据</el-divider>

            <el-form label-width="100px" size="small">
              <el-form-item label="示例消息">
                <el-input
                  v-model="sampleMessage"
                  type="textarea"
                  :rows="2"
                  placeholder="输入示例用户消息"
                  @input="handleVariableChange"
                />
              </el-form-item>
            </el-form>

            <el-button type="primary" :loading="previewing" @click="handlePreview" style="margin-top: 12px;">
              生成预览
            </el-button>
          </div>
        </el-col>

        <el-col :span="14">
          <div class="preview-section">
            <div class="preview-header">
              <h4>渲染结果</h4>
              <div class="token-info">
                <el-tag type="info" size="small">
                  预估 Token: {{ previewResult?.estimatedTokens || 0 }}
                </el-tag>
              </div>
            </div>

            <div v-if="previewResult?.warnings?.length" class="warnings">
              <el-alert
                v-for="(warning, idx) in previewResult.warnings"
                :key="idx"
                :title="warning"
                type="warning"
                :closable="false"
                show-icon
                style="margin-bottom: 8px;"
              />
            </div>

            <div class="token-breakdown">
              <el-descriptions :column="2" border size="small">
                <el-descriptions-item label="系统指令">
                  {{ previewResult?.tokenCount?.systemPrompt || 0 }} tokens
                </el-descriptions-item>
                <el-descriptions-item label="历史消息">
                  {{ previewResult?.tokenCount?.history || 0 }} tokens
                </el-descriptions-item>
                <el-descriptions-item label="当前消息">
                  {{ previewResult?.tokenCount?.currentMessage || 0 }} tokens
                </el-descriptions-item>
                <el-descriptions-item label="总计">
                  <strong>{{ previewResult?.tokenCount?.total || 0 }} tokens</strong>
                </el-descriptions-item>
              </el-descriptions>
            </div>

            <div class="rendered-content">
              <pre>{{ previewResult?.renderedContent || '点击"生成预览"查看渲染结果' }}</pre>
            </div>
          </div>
        </el-col>
      </el-row>
    </div>

    <template #footer>
      <el-button @click="$emit('update:visible', false)">关闭</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import { previewPromptTemplate, type PromptPreviewResponse } from '@/api/monitoring'
import type { PromptVariable } from '@/types/prompt-template'
import { BUILTIN_VARIABLES } from '@/types/prompt-template'

const props = defineProps<{
  visible: boolean
  templateId: string
  templateVariables?: PromptVariable[]
}>()

const emit = defineEmits<{
  'update:visible': [value: boolean]
}>()

const allVariables = computed(() => {
  const builtin = BUILTIN_VARIABLES.map(v => ({
    name: v.name,
    description: v.description,
    default_value: v.default_value || ''
  }))
  const custom = (props.templateVariables || []).map(v => ({
    name: v.name,
    description: v.description,
    default_value: v.default_value || ''
  }))
  return [...builtin, ...custom]
})

const variables = computed(() => props.templateVariables || [])
const variableValues = ref<Record<string, string>>({})
const sampleMessage = ref('')
const previewing = ref(false)
const previewResult = ref<PromptPreviewResponse | null>(null)
let debounceTimer: ReturnType<typeof setTimeout> | null = null

watch(() => props.visible, (val) => {
  if (val) {
    variableValues.value = {}
    sampleMessage.value = ''
    previewResult.value = null

    allVariables.value.forEach(v => {
      variableValues.value[v.name] = v.default_value || ''
    })
  }
})

const handleVariableChange = () => {
  if (debounceTimer) {
    clearTimeout(debounceTimer)
  }
  debounceTimer = setTimeout(() => {
    handlePreview()
  }, 500)
}

const handlePreview = async () => {
  previewing.value = true
  try {
    previewResult.value = await previewPromptTemplate(props.templateId, {
      variables: variableValues.value,
      sampleMessage: sampleMessage.value || undefined
    })
  } catch (error) {
    previewResult.value = null
  } finally {
    previewing.value = false
  }
}
</script>

<style scoped>
.preview-dialog-content {
  min-height: 400px;
}

.variable-section {
  padding: 12px;
  background: var(--el-fill-color-light);
  border-radius: 8px;
}

.variable-section h4 {
  margin: 0 0 16px 0;
  font-size: 14px;
  color: var(--el-text-color-primary);
}

.preview-section {
  padding: 12px;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.preview-header h4 {
  margin: 0;
  font-size: 14px;
  color: var(--el-text-color-primary);
}

.token-info {
  display: flex;
  gap: 8px;
}

.warnings {
  margin-bottom: 16px;
}

.token-breakdown {
  margin-bottom: 16px;
}

.rendered-content {
  background: var(--el-fill-color-lighter);
  border-radius: 8px;
  padding: 16px;
  max-height: 300px;
  overflow-y: auto;
}

.rendered-content pre {
  margin: 0;
  white-space: pre-wrap;
  word-wrap: break-word;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 13px;
  line-height: 1.5;
  color: var(--el-text-color-primary);
}
</style>
