<template>
  <div>
    <vxe-drawer
      v-model="drawerVisible"
      placement="right"
      @show="handleValidationDrawerShow"
      title="校验结果"
      width="55%"
      :footer="{ show: true }"
    >
      <template #default>
        <div class="validation-results">
          <div class="result-summary">
            <div class="summary-item">
              <span class="summary-label">校验字段数：</span>
              <span class="summary-value">{{ validationResultsList.length }}</span>
            </div>
            <div class="summary-item">
              <span class="summary-label">通过：</span>
              <span class="summary-value success">{{ validationResultsList.filter(item => item.isValid).length }}</span>
            </div>
            <div class="summary-item">
              <span class="summary-label">失败：</span>
              <span class="summary-value error">{{ validationResultsList.filter(item => !item.isValid).length }}</span>
            </div>
          </div>
          <div class="process-log" v-if="showProcessLog && validationProcess.length > 0">
            <h4>执行过程：</h4>
            <div class="process-content">
              <div v-for="(log, index) in validationProcess" :key="index" class="process-item">
                {{ log }}
              </div>
            </div>
          </div>
          <div class="results-list">
            <div
              v-for="(result, index) in validationResultsList"
              :key="index"
              class="result-item"
              :class="{ success: result.isValid, error: !result.isValid }"
              @click="handleValidationResultClick(result)"
            >
              <div class="result-field">{{ result.field }}</div>
              <div class="result-desc">{{ result.description }}</div>
              <div class="result-formula">公式：{{ result.formula }}</div>
              <div class="result-value">值：{{ formatFieldValue(result.fieldValue) }}</div>
              <div v-if="!result.isValid" class="result-error">失败原因：{{ result.description }}</div>
            </div>
          </div>
        </div>
      </template>
      <template #footer>
        <div class="drawer-footer">
          <vxe-button @click="toggleProcessLog">
            {{ showProcessLog ? '隐藏' : '显示' }}执行过程
          </vxe-button>
          <vxe-button status="primary" @click="drawerVisible = false">关闭</vxe-button>
        </div>
      </template>
    </vxe-drawer>

    <!-- 验证公式帮助提示 -->
    <div
      v-if="validationTooltipVisible"
      class="validation-tooltip"
      :style="{ left: validationTooltipPosition.left + 'px', top: validationTooltipPosition.top + 'px' }"
      @mouseleave="closeTooltip"
    >
      <pre class="tooltip-content">{{ validationTooltipContent }}</pre>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch } from 'vue'

interface ValidationResult {
  field: string
  description: string
  formula: string
  isValid: boolean
  fieldValue: any
  rowCode: string
}

interface ValidationFormula {
  formula: string
  des: string
}

interface TableRow {
  code: string
  content: Array<{
    field: string
    [key: string]: any
  }>
}

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  tableFormData: {
    type: Array as () => TableRow[],
    default: () => []
  },
})

const emit = defineEmits(['update:modelValue', 'validationResultClick', 'showValidationHelp'])

const drawerVisible = ref(false)
const validationResultsList = ref<ValidationResult[]>([])
const validationProcess = ref<string[]>([])
const showProcessLog = ref(false)
const validationTooltipVisible = ref(false)
const validationTooltipPosition = ref({ left: 0, top: 0 })
const validationTooltipContent = ref('')

// 通过外部传入的数据
const validFormula = ref<ValidationFormula[]>([])
const formData = ref<Record<string, any>>({})

watch(() => props.modelValue, (newVal) => {
  drawerVisible.value = newVal
})

watch(drawerVisible, (newVal) => {
  emit('update:modelValue', newVal)
})

const handleValidationDrawerShow = () => {
  performValidation()
}

const performValidation = () => {
  validationResultsList.value = []
  validationProcess.value = []
  
  validationProcess.value.push('开始校验')
  validationProcess.value.push(`找到 ${validFormula.value.length} 个验证公式`)

  validFormula.value.forEach((formulaItem: ValidationFormula) => {
    validationProcess.value.push(`开始校验公式: ${formulaItem.des}`)
    const result = evaluateFormula(formulaItem.formula, formulaItem.des)
    
    if (result) {
      validationResultsList.value.push(result)
    }
  })
  
  validationProcess.value.push('校验完成')
  validationProcess.value.push(`总计处理: ${validationResultsList.value.length} 条结果`)
}

const evaluateFormula = (formula: string, description: string): ValidationResult | null => {
  try {
    // 修复正则表达式 - $$需要转义
    const fieldMatch = formula.match(/([A-Za-z_]\w*)/)
    if (!fieldMatch) {
      validationProcess.value.push(`跳过: 无法解析公式字段 ${formula}`)
      return null
    }

    const fieldName = fieldMatch[1]
    validationProcess.value.push(`解析到字段: ${fieldName}`)

    // 查找字段所在行
    const row = props.tableFormData.find((r: TableRow) => 
      r.content?.some((c: any) => c.field === fieldName)
    )
    
    if (!row) {
      validationProcess.value.push(`跳过: 未找到字段 ${fieldName} 所在的行`)
      return null
    }

    validationProcess.value.push(`找到字段所在行: ${row.code}`)

    const fieldItem = row.content.find((c: any) => c.field === fieldName)
    if (!fieldItem) {
      validationProcess.value.push(`跳过: 未找到字段 ${fieldName}`)
      return null
    }

    const strKey = `${row.code}_${fieldName}`
    const fieldValue = formData.value[strKey]
    
    validationProcess.value.push(`字段值: ${fieldValue} (key: ${strKey})`)

    // 检查空字段规则
    const emptyFieldRule = validFormula.value.find((f: ValidationFormula) =>
      f.formula.includes(fieldName) && f.des.includes('空字段')
    )

    if (emptyFieldRule && (!fieldValue || fieldValue === '')) {
      validationProcess.value.push(`跳过: 字段 ${fieldName} 为空，跳过空字段规则`)
      return null
    }

    // 构建表达式 - 修复变量引用问题
    const expression = formula.replace(/\$\$(\w+)\$\$/g, (_, field) => {
      const key = `${row.code}_${field}`
      const value = formData.value[key]
      return value !== undefined && value !== '' ? `Number(${value})` : '0'
    })

    validationProcess.value.push(`执行公式: ${expression}`)
    
    // 安全地执行表达式
    const isValid = safeEvalExpression(expression)
    validationProcess.value.push(`校验结果: ${isValid ? '通过' : '失败'}`)

    return {
      field: fieldName,
      description: description,
      formula: formula,
      isValid: isValid,
      fieldValue: fieldValue,
      rowCode: row.code
    }
  } catch (error) {
    validationProcess.value.push(`公式执行错误: ${error instanceof Error ? error.message : String(error)}`)
    return null
  }
}

// 安全的表达式求值函数
const safeEvalExpression = (expression: string): boolean => {
  try {
    // 使用 Function 构造函数创建安全的求值环境
    const func = new Function(`return ${expression}`)
    const result = func()
    
    // 处理布尔值返回
    if (typeof result === 'boolean') {
      return result
    }
    
    // 处理数值比较结果
    if (typeof result === 'number') {
      return Boolean(result)
    }
    
    // 处理字符串
    if (typeof result === 'string') {
      return result.toLowerCase() === 'true'
    }
    
    return Boolean(result)
  } catch (error) {
    validationProcess.value.push(`表达式求值错误: ${error}`)
    return false
  }
}

const formatFieldValue = (value: any): string => {
  if (value === undefined || value === null) {
    return '空'
  }
  if (value === '') {
    return '空字符串'
  }
  return String(value)
}

const handleValidationResultClick = (result: ValidationResult) => {
  emit('validationResultClick', result)
}

const showValidationHelp = (formulaItem: ValidationFormula, event: MouseEvent) => {
  const rect = (event.target as HTMLElement).getBoundingClientRect()
  validationTooltipPosition.value = {
    left: rect.left + rect.width / 2,
    top: rect.top - 10
  }
  validationTooltipContent.value = `验证公式: ${formulaItem.formula}\n说明: ${formulaItem.des}`
  validationTooltipVisible.value = true
}

const closeTooltip = () => {
  validationTooltipVisible.value = false
}

const toggleProcessLog = () => {
  showProcessLog.value = !showProcessLog.value
}

const setValidateData = (formulaData: ValidationFormula[], formDataObj: Record<string, any>) => {
  validFormula.value = formulaData
  formData.value = formDataObj
}

defineExpose({
  performValidation,
  showValidationHelp,
  closeTooltip,
  setValidateData
})
</script>

<style lang="less" scoped>
.validation-results {
  padding: 20px;
  height: 600px;
  overflow-y: auto;
}

.result-summary {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.summary-item {
  display: flex;
  flex-direction: column;
}

.summary-label {
  font-size: 12px;
  color: #666;
}

.summary-value {
  font-size: 16px;
  font-weight: bold;
  color: #333;
}

.summary-value.success {
  color: #52c41a;
}

.summary-value.error {
  color: #ff4d4f;
}

.process-log {
  margin: 15px 0;
  padding: 10px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border-left: 4px solid #1890ff;
  
  h4 {
    margin: 0 0 10px 0;
    color: #1890ff;
    font-size: 14px;
  }
}

.process-content {
  max-height: 200px;
  overflow-y: auto;
  font-family: monospace;
}

.process-item {
  font-size: 12px;
  color: #666;
  padding: 2px 0;
  border-bottom: 1px dashed #eee;
  
  &:last-child {
    border-bottom: none;
  }
}

.results-list {
  margin-top: 10px;
}

.result-item {
  padding: 10px;
  margin-bottom: 8px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  
  &:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }
}

.result-item.success {
  background-color: #f6ffed;
  border-left: 4px solid #52c41a;
  
  &:hover {
    background-color: #e8f7e0;
  }
}

.result-item.error {
  background-color: #fff2f0;
  border-left: 4px solid #ff4d4f;
  
  &:hover {
    background-color: #ffe9e6;
  }
}

.result-field {
  font-weight: bold;
  margin-bottom: 5px;
  color: #333;
}

.result-desc {
  font-size: 12px;
  color: #666;
  margin-bottom: 5px;
}

.result-formula {
  font-size: 12px;
  color: #888;
  font-family: monospace;
  margin-bottom: 5px;
  background-color: rgba(0, 0, 0, 0.02);
  padding: 2px 4px;
  border-radius: 2px;
  word-break: break-all;
}

.result-value {
  font-size: 12px;
  color: #999;
}

.result-error {
  font-size: 12px;
  color: #ff4d4f;
  margin-top: 5px;
  font-weight: bold;
}

.validation-tooltip {
  position: fixed;
  background-color: #333;
  color: #fff;
  padding: 12px;
  border-radius: 6px;
  font-size: 12px;
  z-index: 9999;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  max-width: 400px;
  transform: translateX(-50%);
  
  &::before {
    content: '';
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%);
    border-width: 5px 5px 0;
    border-style: solid;
    border-color: #333 transparent transparent;
  }
}

.tooltip-content {
  margin: 0;
  white-space: pre-wrap;
  line-height: 1.5;
}

.drawer-footer {
  display: flex;
  justify-content: space-between;
  padding: 10px;
  border-top: 1px solid #eee;
}
</style>