<template>
  <div class="pattern-input">
    <div
      v-for="(pattern, index) in modelValue"
      :key="index"
      class="pattern-item"
    >
      <code class="pattern-code">{{ pattern }}</code>
      <el-button
        type="danger"
        size="small"
        link
        @click="handleRemove(index)"
      >
        <el-icon><Close /></el-icon>
      </el-button>
    </div>
    <div class="input-row">
      <el-input
        v-model="inputValue"
        :placeholder="placeholder"
        size="small"
        @keyup.enter="handleAdd"
        class="input-field"
      />
      <el-button type="primary" size="small" @click="handleAdd">添加</el-button>
    </div>
    <transition name="fade">
      <div v-if="errorMessage" class="error-tip">
        <el-icon><WarningFilled /></el-icon>
        {{ errorMessage }}
      </div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Close, WarningFilled } from '@element-plus/icons-vue'

const props = defineProps<{
  modelValue: string[]
  placeholder?: string
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: string[]): void
}>()

const inputValue = ref('')
const errorMessage = ref('')

const validateRegex = (pattern: string): boolean => {
  try {
    new RegExp(pattern)
    return true
  } catch {
    return false
  }
}

const handleAdd = () => {
  const value = inputValue.value.trim()
  if (!value) return

  if (!validateRegex(value)) {
    errorMessage.value = '无效的正则表达式'
    return
  }

  errorMessage.value = ''

  if (!props.modelValue.includes(value)) {
    emit('update:modelValue', [...props.modelValue, value])
  }
  inputValue.value = ''
}

const handleRemove = (index: number) => {
  const newValue = [...props.modelValue]
  newValue.splice(index, 1)
  emit('update:modelValue', newValue)
}
</script>

<style scoped>
.pattern-input {
  padding: 8px;
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
  min-height: 60px;
}

.pattern-input:focus-within {
  border-color: var(--el-color-primary);
}

.pattern-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 8px;
  margin-bottom: 6px;
  background-color: var(--el-fill-color-light);
  border-radius: 4px;
}

.pattern-code {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 12px;
  color: var(--el-color-primary);
  word-break: break-all;
}

.input-row {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.input-field {
  flex: 1;
}

.error-tip {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 6px;
  font-size: 12px;
  color: var(--el-color-danger);
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
