<template>
  <div class="param-item" :class="{ disabled: disabled, error: hasError }">
    <!-- 只读模式 -->
    <div v-if="!isEditing" class="read-mode" @mouseenter="showEdit = true" @mouseleave="showEdit = false">
      <div class="param-label" v-html="highlightedLabel"></div>
      <div class="param-value">
        <span v-if="type === 'switch'" class="switch-value">
          <i :class="value ? 'el-icon-check' : 'el-icon-close'" :style="{ color: value ? '#67C23A' : '#F56C6C' }"></i>
          {{ value ? '已启用' : '已禁用' }}
        </span>
        <span v-else-if="type === 'textarea'" class="textarea-value" :class="{ 'monospace': type === 'textarea' }">{{ displayValue }}</span>
        <span v-else-if="type === 'select'" class="text-value">{{ displayValue }}</span>
        <span v-else-if="type === 'number'" class="text-value">{{ displayValue }}</span>
        <span v-else class="text-value">{{ displayValue }}</span>
      </div>
      <div class="param-actions">
        <!-- 复制按钮 -->
        <el-button
          v-if="showCopyButton && !disabled"
          v-show="showEdit"
          type="text"
          size="mini"
          icon="el-icon-document-copy"
          @click="handleCopy"
          :aria-label="`复制${label}值`"
          class="copy-btn"
        >
        </el-button>
        <el-button
          v-show="!disabled && showEdit"
          type="text"
          size="mini"
          icon="el-icon-edit"
          @click="startEdit"
          :aria-label="`编辑${label}`"
        >
          编辑
        </el-button>
      </div>
    </div>

    <!-- 编辑模式 -->
    <div v-else class="edit-mode" @keydown="handleKeyDown">
      <div class="param-label">{{ label }}</div>
      <div class="param-input">
        <!-- 开关类型 -->
        <el-switch
          v-if="type === 'switch'"
          v-model="editValue"
          active-text="启用"
          inactive-text="禁用"
          :disabled="saving"
          ref="editInput"
        />
        <!-- 文本域类型 -->
        <div v-else-if="type === 'textarea'" class="textarea-container">
          <el-input
            v-model="editValue"
            type="textarea"
            :rows="3"
            :placeholder="placeholder"
            :disabled="saving"
            ref="editInput"
            class="monospace-input"
          />
          <!-- 过滤规则示例 -->
          <el-popover
            v-if="label.includes('过滤规则')"
            placement="top"
            width="300"
            trigger="click"
          >
            <div class="filter-examples">
              <p><strong>常见过滤规则示例：</strong></p>
              <div class="example-item" v-for="example in filterExamples" :key="example.rule">
                <code>{{ example.rule }}</code>
                <span class="example-desc">{{ example.desc }}</span>
              </div>
            </div>
            <el-button slot="reference" type="text" size="mini" class="example-btn">
              <i class="el-icon-question"></i>
              示例
            </el-button>
          </el-popover>
        </div>
        <!-- 数字输入类型 -->
        <el-input
          v-else-if="type === 'number'"
          v-model="editValue"
          :placeholder="placeholder"
          :disabled="saving"
          ref="editInput"
          @input="handleNumberInput"
        />
        <!-- 下拉选择类型 -->
        <el-select
          v-else-if="type === 'select'"
          v-model="editValue"
          :placeholder="placeholder"
          :disabled="saving"
          ref="editInput"
        >
          <el-option
            v-for="option in options"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
        <!-- 其他输入类型 -->
        <el-input
          v-else
          v-model="editValue"
          :placeholder="placeholder"
          :disabled="saving"
          ref="editInput"
        />
      </div>
      <div class="param-actions">
        <el-button
          type="primary"
          size="mini"
          :loading="saving"
          @click="handleSave"
          :aria-label="`保存${label}`"
        >
          保存
        </el-button>
        <el-button
          type="text"
          size="mini"
          :disabled="saving"
          @click="handleCancel"
          :aria-label="`取消编辑${label}`"
        >
          取消
        </el-button>
      </div>
    </div>

    <!-- 错误提示 -->
    <div v-if="hasError" class="error-message">{{ errorMessage }}</div>

    <!-- 保存成功图标 -->
    <transition name="save-success">
      <div v-if="showSaveSuccess" class="save-success-icon">
        <i class="el-icon-check"></i>
      </div>
    </transition>
  </div>
</template>

<script>
export default {
  name: 'XtParamItem',
  
  props: {
    label: {
      type: String,
      required: true
    },
    value: {
      type: [String, Number, Boolean],
      default: ''
    },
    type: {
      type: String,
      default: 'text',
      validator: value => ['text', 'url', 'ip', 'switch', 'textarea', 'number', 'select'].includes(value)
    },
    placeholder: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    searchKeyword: {
      type: String,
      default: ''
    },
    // 数字类型相关属性
    unit: {
      type: String,
      default: ''
    },
    min: {
      type: Number,
      default: undefined
    },
    max: {
      type: Number,
      default: undefined
    },
    step: {
      type: Number,
      default: 0.01
    },
    precision: {
      type: Number,
      default: 2
    },
    // 选择类型相关属性
    options: {
      type: Array,
      default: () => []
    }
  },

  data() {
    return {
      isEditing: false,
      editValue: '',
      showEdit: false,
      saving: false,
      hasError: false,
      errorMessage: '',
      showSaveSuccess: false,
      filterExamples: [
        { rule: 'tcp and (port 80 or port 443)', desc: 'HTTP/HTTPS 流量' },
        { rule: 'udp and port 53', desc: 'DNS 查询' },
        { rule: 'icmp', desc: 'ICMP 协议（ping）' },
        { rule: 'host 192.168.1.100', desc: '特定主机流量' },
        { rule: 'src net 192.168.0.0/16', desc: '来源网段过滤' }
      ]
    }
  },

  computed: {
    // 是否显示复制按钮
    showCopyButton() {
      return ['ip', 'url', 'text', 'number', 'textarea', 'select'].includes(this.type) && this.value && this.value.toString().trim()
    },

    // 显示值
    displayValue() {
      if (this.type === 'switch') {
        return this.value ? '已启用' : '已禁用'
      } else if (this.type === 'select') {
        const option = this.options.find(opt => opt.value === this.value)
        return option ? option.label : this.value
      } else if (this.type === 'number' && this.unit) {
        return this.value !== null && this.value !== undefined ? `${this.value} ${this.unit}` : (this.placeholder || '未设置')
      }
      return this.value || this.placeholder || '未设置'
    },

    // 高亮标签
    highlightedLabel() {
      if (!this.searchKeyword.trim()) {
        return this.label
      }
      
      const keyword = this.searchKeyword.toLowerCase()
      const labelLower = this.label.toLowerCase()
      const index = labelLower.indexOf(keyword)
      
      if (index === -1) {
        return this.label
      }
      
      const before = this.label.substring(0, index)
      const match = this.label.substring(index, index + keyword.length)
      const after = this.label.substring(index + keyword.length)
      
      return `${before}<mark class="search-highlight">${match}</mark>${after}`
    }
  },

  methods: {
    startEdit() {
      if (this.disabled) return
      
      this.isEditing = true
      this.editValue = this.value
      this.hasError = false
      this.errorMessage = ''
      
      this.$nextTick(() => {
        if (this.$refs.editInput) {
          if (this.type === 'switch') {
            this.$refs.editInput.$el.focus()
          } else {
            this.$refs.editInput.focus()
          }
        }
      })
    },

    async handleSave() {
      if (this.saving) return

      // 验证数字输入
      if (this.type === 'number') {
        const validation = this.validateNumber(this.editValue)
        if (!validation.valid) {
          this.hasError = true
          this.errorMessage = validation.message
          return
        }
        
        // 转换为数字类型
        this.editValue = this.editValue === '' ? null : parseFloat(this.editValue)
      }

      // 校验
      const validation = this.validateValue(this.editValue)
      if (!validation.valid) {
        this.hasError = true
        this.errorMessage = validation.message
        return
      }

      this.saving = true
      this.hasError = false

      try {
        await this.$emit('save', this.editValue)
        
        // 保存成功
        this.isEditing = false
        this.showSaveSuccess = true
        
        // 1.2秒后隐藏成功图标
        setTimeout(() => {
          this.showSaveSuccess = false
        }, 1200)
        
      } catch (error) {
        this.hasError = true
        this.errorMessage = error.message || '保存失败'
      } finally {
        this.saving = false
      }
    },

    handleCancel() {
      if (this.saving) return
      
      this.isEditing = false
      this.editValue = ''
      this.hasError = false
      this.errorMessage = ''
      this.$emit('cancel')
    },

    // 复制功能
    async handleCopy() {
      try {
        const copyValue = this.type === 'select' ? this.displayValue : this.value.toString()
        await navigator.clipboard.writeText(copyValue)
        this.$message.success('已复制')
      } catch (error) {
        // Fallback for older browsers
        const copyValue = this.type === 'select' ? this.displayValue : this.value.toString()
        const textArea = document.createElement('textarea')
        textArea.value = copyValue
        document.body.appendChild(textArea)
        textArea.select()
        document.execCommand('copy')
        document.body.removeChild(textArea)
        this.$message.success('已复制')
      }
    },

    // 键盘事件处理
    handleKeyDown(event) {
      if (event.key === 'Enter' && !event.shiftKey) {
        event.preventDefault()
        this.handleSave()
      } else if (event.key === 'Escape') {
        event.preventDefault()
        this.handleCancel()
      } else if (event.key === 'Tab') {
        // Tab 键在卡片内循环 - 这里可以根据需要实现特定逻辑
        // 现在让浏览器默认处理 Tab 键
      }
    },

    // 数字输入处理
    handleNumberInput(value) {
      if (this.type !== 'number') return
      
      // 允许输入负号、小数点和数字
      const numericValue = value.replace(/[^-0-9.]/g, '')
      
      // 确保只有一个负号且在开头
      let cleanValue = numericValue.replace(/-/g, '')
      if (numericValue.indexOf('-') === 0) {
        cleanValue = '-' + cleanValue
      }
      
      // 确保只有一个小数点
      const parts = cleanValue.split('.')
      if (parts.length > 2) {
        cleanValue = parts[0] + '.' + parts.slice(1).join('')
      }
      
      this.editValue = cleanValue
    },

    // 验证数字值
    validateNumber(value) {
      if (this.type !== 'number') return { valid: true }
      
      // 空值检查
      if (value === '' || value === null || value === undefined) {
        return { valid: true } // 允许空值
      }
      
      const numValue = parseFloat(value)
      
      // 检查是否为有效数字
      if (isNaN(numValue)) {
        return { valid: false, message: '请输入有效的数字' }
      }
      
      // 检查范围
      if (this.min !== undefined && numValue < this.min) {
        return { valid: false, message: `值不能小于 ${this.min}` }
      }
      
      if (this.max !== undefined && numValue > this.max) {
        return { valid: false, message: `值不能大于 ${this.max}` }
      }
      
      return { valid: true }
    },

    validateValue(value) {
      if (this.type === 'switch') {
        return { valid: true }
      }
      
      // 空值检查（可选，根据需求调整）
      if (!value && value !== 0 && value !== false) {
        return { valid: true } // 允许空值
      }

      switch (this.type) {
        case 'ip':
          return this.validateIP(value)
        case 'url':
          return this.validateURL(value)
        case 'text':
        case 'textarea':
        case 'number':
        case 'select':
        default:
          return { valid: true }
      }
    },

    validateIP(value) {
      const ipRegex = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/
      if (!ipRegex.test(value)) {
        return { valid: false, message: '请输入正确的IP地址格式' }
      }
      return { valid: true }
    },

    validateURL(value) {
      const urlRegex = /^(https?|wss?|mqtt|tcp):\/\/.+/i
      if (!urlRegex.test(value)) {
        return { valid: false, message: '请输入正确的URL格式（支持http/https/ws/wss/mqtt/tcp协议）' }
      }
      return { valid: true }
    }
  }
}
</script>

<style lang="scss" scoped>
.param-item {
  position: relative;
  padding: 12px 0;
  border-bottom: 1px solid var(--color-border-secondary);
  transition: all var(--duration-200) var(--ease-out);

  &:last-child {
    border-bottom: none;
  }

  &.disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  &.error {
    .read-mode,
    .edit-mode {
      border-radius: var(--radius-base);
      border: 1px solid rgba(245, 108, 108, 0.3);
      padding: 8px;
      margin: -8px;
    }
  }

  .read-mode,
  .edit-mode {
    display: flex;
    align-items: flex-start;
    gap: var(--spacing-4);
    min-height: 36px;
  }

  .param-label {
    flex: 0 0 180px;
    color: var(--color-text-primary);
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-sm);
    line-height: 36px;
    padding-right: var(--spacing-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .param-value {
    flex: 1;
    min-width: 0;
    line-height: 36px;

    .switch-value {
      display: flex;
      align-items: center;
      gap: var(--spacing-2);
      color: var(--color-text-secondary);
      font-size: var(--font-size-sm);

      i {
        font-size: var(--font-size-base);
      }
    }

    .textarea-value {
      color: var(--color-text-secondary);
      font-size: var(--font-size-sm);
      line-height: var(--line-height-normal);
      white-space: pre-wrap;
      word-break: break-word;
    }

    .text-value {
      color: var(--color-text-secondary);
      font-size: var(--font-size-sm);
      word-break: break-all;
    }
  }

  .param-input {
    flex: 1;
    min-width: 0;

    .el-input,
    .el-switch,
    .el-select {
      width: 100%;
    }

    .el-input {
      ::v-deep .el-input__inner {
        height: 36px;
        border-radius: var(--radius-base);
        border: 1px solid var(--color-border-primary);
        background: var(--color-bg-card);
        transition: all var(--duration-200) var(--ease-out);

        &:focus {
          border-color: var(--color-primary);
          box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.15);
        }
      }

      &.is-disabled {
        ::v-deep .el-input__inner {
          background: var(--color-bg-secondary);
          color: var(--color-text-quaternary);
        }
      }
    }

    .el-switch {
      ::v-deep .el-switch__core {
        border-radius: var(--radius-full);
      }
    }

    .el-select {
      ::v-deep .el-input__inner {
        height: 36px;
        border-radius: var(--radius-base);
        border: 1px solid var(--color-border-primary);
        background: var(--color-bg-card);
        transition: all var(--duration-200) var(--ease-out);

        &:focus {
          border-color: var(--color-primary);
          box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.15);
        }
      }
    }

    ::v-deep .el-textarea {
      .el-textarea__inner {
        border-radius: var(--radius-base);
        border: 1px solid var(--color-border-primary);
        background: var(--color-bg-card);
        resize: vertical;
        min-height: 72px;
        transition: all var(--duration-200) var(--ease-out);

        &:focus {
          border-color: var(--color-primary);
          box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.15);
        }
      }
    }
  }

  .param-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--spacing-2);
    height: 36px;

    .el-button {
      height: 28px;
      padding: 0 var(--spacing-3);
      border-radius: var(--radius-base);
      font-size: var(--font-size-xs);
      
      &.el-button--text {
        color: var(--color-text-tertiary);
        
        &:hover {
          color: var(--color-primary);
          background: rgba(64, 158, 255, 0.08);
        }
      }

      &.el-button--primary {
        background: var(--color-primary);
        border-color: var(--color-primary);
        
        &:hover {
          background: var(--color-primary-light);
          border-color: var(--color-primary-light);
        }
      }
    }
  }

  .error-message {
    color: var(--color-danger);
    font-size: var(--font-size-xs);
    line-height: var(--line-height-normal);
    margin-top: var(--spacing-2);
    margin-left: 184px;
    opacity: 0.8;
  }

  .save-success-icon {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 24px;
    height: 24px;
    background: var(--color-success);
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10;
    box-shadow: var(--shadow-sm);
    
    i {
      font-size: var(--font-size-sm);
      font-weight: bold;
    }
  }

  // 保存成功动画
  .save-success-enter-active,
  .save-success-leave-active {
    transition: all 0.3s ease;
  }

  .save-success-enter,
  .save-success-leave-to {
    opacity: 0;
    transform: scale(0.8) translateY(-4px);
  }

  // 复制按钮样式
  .copy-btn {
    margin-right: var(--spacing-1);
    
    &:hover {
      color: var(--color-primary) !important;
    }
  }

  // 搜索高亮样式
  ::v-deep .search-highlight {
    background: rgba(64, 158, 255, 0.15);
    border-radius: 3px;
    padding: 0 2px;
    color: var(--color-primary);
    font-weight: var(--font-weight-medium);
  }

  // 等宽字体样式
  .monospace,
  .monospace-input {
    font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
  }

  // 文本域容器
  .textarea-container {
    position: relative;
    
    .example-btn {
      position: absolute;
      top: 8px;
      right: 8px;
      z-index: 2;
      opacity: 0.7;
      
      &:hover {
        opacity: 1;
        color: var(--color-primary);
      }
    }
  }

  // 过滤规则示例
  .filter-examples {
    .example-item {
      margin-bottom: var(--spacing-3);
      
      &:last-child {
        margin-bottom: 0;
      }
      
      code {
        display: block;
        background: var(--color-bg-secondary);
        padding: var(--spacing-1) var(--spacing-2);
        border-radius: var(--radius-base);
        font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
        font-size: var(--font-size-xs);
        color: var(--color-text-primary);
        margin-bottom: var(--spacing-1);
      }
      
      .example-desc {
        font-size: var(--font-size-xs);
        color: var(--color-text-secondary);
      }
    }
  }
}

// 暗色主题适配
html.dark {
  .param-item {
    .param-input {
      .el-input {
        ::v-deep .el-input__inner {
          background: var(--color-bg-tertiary);
          border-color: var(--color-border-tertiary);
          color: var(--color-text-primary);
        }
      }

      .el-select {
        ::v-deep .el-input__inner {
          background: var(--color-bg-tertiary);
          border-color: var(--color-border-tertiary);
          color: var(--color-text-primary);
        }
      }

      ::v-deep .el-textarea {
        .el-textarea__inner {
          background: var(--color-bg-tertiary);
          border-color: var(--color-border-tertiary);
          color: var(--color-text-primary);
        }
      }
    }

    .filter-examples {
      .example-item {
        code {
          background: var(--color-bg-quaternary);
          color: var(--color-text-primary);
        }
      }
    }

    ::v-deep .search-highlight {
      background: rgba(64, 158, 255, 0.25);
    }
  }
}

// 大屏优化
@media (min-width: 1280px) {
  .param-item {
    .param-label {
      flex: 0 0 220px; // 大屏下给更多空间
    }

    .error-message {
      margin-left: 224px;
    }
  }
}

// 移动端适配
@media (max-width: 768px) {
  .param-item {
    .read-mode,
    .edit-mode {
      flex-direction: column;
      gap: var(--spacing-2);
    }

    .param-label {
      flex: none;
      line-height: var(--line-height-normal);
    }

    .param-value {
      line-height: var(--line-height-normal);
    }

    .param-actions {
      justify-content: flex-end;
      height: auto;
    }

    .error-message {
      margin-left: 0;
    }
  }
}
</style>
