<template>
  <el-dialog
    v-model="visible"
    title="正则脚本编辑器"
    width="1200px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div class="regex-editor">
      <div class="toolbar">
        <el-button type="primary" size="small" @click="addScript">
          <el-icon><Plus /></el-icon>
          添加脚本
        </el-button>
        <el-button type="success" size="small" @click="importScripts">
          <el-icon><Upload /></el-icon>
          导入脚本
        </el-button>
        <el-button type="warning" size="small" @click="testRegex" :disabled="!currentScript">
          <el-icon><View /></el-icon>
          测试当前脚本
        </el-button>
      </div>

      <div class="editor-content">
        <div class="script-list">
          <div class="list-header">
            <span>脚本列表 ({{ scripts.length }})</span>
          </div>
          <el-scrollbar height="500px">
            <div
              v-for="(script, index) in scripts"
              :key="script.id || index"
              :class="['script-item', { active: currentIndex === index, disabled: script.disabled }]"
              @click="selectScript(index)"
            >
              <div class="script-info">
                <div class="script-name">
                  <el-icon v-if="script.disabled"><CircleClose /></el-icon>
                  <el-icon v-else><CircleCheck /></el-icon>
                  {{ script.scriptName || '未命名脚本' }}
                </div>
                <div class="script-placement">
                  <el-tag v-if="script.placement?.includes(1)" size="small" type="info">输入前</el-tag>
                  <el-tag v-if="script.placement?.includes(2)" size="small" type="success">输出后</el-tag>
                </div>
              </div>
              <div class="script-actions">
                <el-button
                  type="primary"
                  link
                  size="small"
                  @click.stop="duplicateScript(index)"
                >
                  <el-icon><CopyDocument /></el-icon>
                </el-button>
                <el-button
                  type="danger"
                  link
                  size="small"
                  @click.stop="deleteScript(index)"
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </div>
          </el-scrollbar>
        </div>

        <div class="script-editor" v-if="currentScript">
          <el-form :model="currentScript" label-width="120px" label-position="left">
            <el-form-item label="脚本名称">
              <el-input v-model="currentScript.scriptName" placeholder="请输入脚本名称" />
            </el-form-item>

            <el-form-item label="正则表达式">
              <el-input
                v-model="currentScript.findRegex"
                type="textarea"
                :rows="3"
                placeholder="请输入正则表达式，如: /<pattern>/flags"
              />
              <div class="hint">支持 JavaScript 正则表达式格式，如: /pattern/gi</div>
            </el-form-item>

            <el-form-item label="替换字符串">
              <el-input
                v-model="currentScript.replaceString"
                type="textarea"
                :rows="2"
                placeholder="替换内容，支持 $1, $2 等捕获组引用"
              />
            </el-form-item>

            <el-form-item label="执行位置">
              <el-checkbox-group v-model="currentScript.placement">
                <el-checkbox :value="1">用户输入前处理</el-checkbox>
                <el-checkbox :value="2">AI输出后处理</el-checkbox>
              </el-checkbox-group>
            </el-form-item>

            <el-form-item label="应用深度">
              <el-row :gutter="10">
                <el-col :span="12">
                  <el-input-number
                    v-model="currentScript.minDepth"
                    placeholder="最小深度"
                    :min="0"
                    style="width: 100%"
                  />
                  <div class="hint">最小深度 (null=不限制)</div>
                </el-col>
                <el-col :span="12">
                  <el-input-number
                    v-model="currentScript.maxDepth"
                    placeholder="最大深度"
                    :min="0"
                    style="width: 100%"
                  />
                  <div class="hint">最大深度 (null=不限制)</div>
                </el-col>
              </el-row>
            </el-form-item>

            <el-form-item label="选项">
              <el-checkbox v-model="currentScript.disabled">禁用此脚本</el-checkbox>
              <el-checkbox v-model="currentScript.markdownOnly">仅处理 Markdown</el-checkbox>
              <el-checkbox v-model="currentScript.promptOnly">仅处理提示词</el-checkbox>
              <el-checkbox v-model="currentScript.runOnEdit">编辑时运行</el-checkbox>
            </el-form-item>

            <el-form-item label="修剪字符串">
              <el-select
                v-model="currentScript.trimStrings"
                multiple
                filterable
                allow-create
                placeholder="输入要修剪的字符串"
                style="width: 100%"
              >
              </el-select>
              <div class="hint">在应用正则前要删除的字符串列表</div>
            </el-form-item>
          </el-form>
        </div>

        <div v-else class="empty-state">
          <el-empty description="请选择或创建一个脚本" />
        </div>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleSave">保存</el-button>
      </div>
    </template>

    <!-- 测试对话框 -->
    <el-dialog v-model="testDialogVisible" title="测试正则脚本" width="800px" append-to-body>
      <el-form label-width="100px">
        <el-form-item label="测试文本">
          <el-input
            v-model="testInput"
            type="textarea"
            :rows="6"
            placeholder="输入要测试的文本"
          />
        </el-form-item>
        <el-form-item label="匹配结果">
          <el-input
            v-model="testOutput"
            type="textarea"
            :rows="6"
            readonly
            placeholder="替换后的结果将显示在这里"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="testDialogVisible = false">关闭</el-button>
        <el-button type="primary" @click="runTest">执行测试</el-button>
      </template>
    </el-dialog>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Plus,
  Upload,
  View,
  Delete,
  CopyDocument,
  CircleCheck,
  CircleClose
} from '@element-plus/icons-vue'

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

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

const visible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

const scripts = ref([])
const currentIndex = ref(-1)
const testDialogVisible = ref(false)
const testInput = ref('')
const testOutput = ref('')

const currentScript = computed(() => {
  if (currentIndex.value >= 0 && currentIndex.value < scripts.value.length) {
    return scripts.value[currentIndex.value]
  }
  return null
})

watch(
  () => props.modelValue,
  (val) => {
    if (val) {
      scripts.value = JSON.parse(JSON.stringify(props.regexScripts || []))
      if (scripts.value.length > 0) {
        currentIndex.value = 0
      } else {
        currentIndex.value = -1
      }
    }
  }
)

const generateId = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    const r = (Math.random() * 16) | 0
    const v = c === 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}

const addScript = () => {
  const newScript = {
    id: generateId(),
    scriptName: '新建脚本',
    findRegex: '',
    replaceString: '',
    trimStrings: [],
    placement: [2],
    disabled: false,
    markdownOnly: false,
    promptOnly: false,
    runOnEdit: false,
    substituteRegex: 0,
    minDepth: null,
    maxDepth: null
  }
  scripts.value.push(newScript)
  currentIndex.value = scripts.value.length - 1
  ElMessage.success('已添加新脚本')
}

const selectScript = (index) => {
  currentIndex.value = index
}

const duplicateScript = (index) => {
  const original = scripts.value[index]
  const duplicate = {
    ...JSON.parse(JSON.stringify(original)),
    id: generateId(),
    scriptName: original.scriptName + ' (副本)'
  }
  scripts.value.splice(index + 1, 0, duplicate)
  currentIndex.value = index + 1
  ElMessage.success('已复制脚本')
}

const deleteScript = (index) => {
  ElMessageBox.confirm('确定要删除这个脚本吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    scripts.value.splice(index, 1)
    if (currentIndex.value >= scripts.value.length) {
      currentIndex.value = scripts.value.length - 1
    }
    ElMessage.success('已删除脚本')
  }).catch(() => {})
}

const importScripts = () => {
  ElMessageBox.prompt('请粘贴正则脚本 JSON 数组', '导入脚本', {
    confirmButtonText: '导入',
    cancelButtonText: '取消',
    inputType: 'textarea'
  }).then(({ value }) => {
    try {
      const imported = JSON.parse(value)
      if (Array.isArray(imported)) {
        imported.forEach(script => {
          if (!script.id) {
            script.id = generateId()
          }
        })
        scripts.value.push(...imported)
        ElMessage.success(`成功导入 ${imported.length} 个脚本`)
      } else {
        ElMessage.error('导入的数据必须是数组格式')
      }
    } catch (error) {
      ElMessage.error('JSON 解析失败: ' + error.message)
    }
  }).catch(() => {})
}

const testRegex = () => {
  if (!currentScript.value) {
    ElMessage.warning('请先选择一个脚本')
    return
  }
  testInput.value = ''
  testOutput.value = ''
  testDialogVisible.value = true
}

const runTest = () => {
  if (!testInput.value) {
    ElMessage.warning('请输入测试文本')
    return
  }

  try {
    let text = testInput.value

    // 应用 trimStrings
    if (currentScript.value.trimStrings && currentScript.value.trimStrings.length > 0) {
      currentScript.value.trimStrings.forEach(trim => {
        text = text.split(trim).join('')
      })
    }

    // 解析正则表达式
    let regex
    const regexStr = currentScript.value.findRegex

    // 尝试解析 /pattern/flags 格式
    const match = regexStr.match(/^\/(.+)\/([gimsuvy]*)$/)
    if (match) {
      regex = new RegExp(match[1], match[2])
    } else {
      // 直接作为正则表达式
      regex = new RegExp(regexStr, 'g')
    }

    // 执行替换
    testOutput.value = text.replace(regex, currentScript.value.replaceString || '')

    ElMessage.success('测试完成')
  } catch (error) {
    ElMessage.error('正则表达式错误: ' + error.message)
    testOutput.value = '错误: ' + error.message
  }
}

const handleClose = () => {
  visible.value = false
}

const handleSave = () => {
  // 验证脚本
  for (let i = 0; i < scripts.value.length; i++) {
    const script = scripts.value[i]
    if (!script.scriptName) {
      ElMessage.warning(`第 ${i + 1} 个脚本缺少名称`)
      currentIndex.value = i
      return
    }
    if (!script.findRegex) {
      ElMessage.warning(`脚本 "${script.scriptName}" 缺少正则表达式`)
      currentIndex.value = i
      return
    }
  }

  emit('save', scripts.value)
  visible.value = false
}
</script>

<style scoped>
.regex-editor {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.toolbar {
  display: flex;
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.editor-content {
  display: flex;
  gap: 15px;
  height: 550px;
}

.script-list {
  width: 280px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.list-header {
  padding: 10px 15px;
  background: #f5f7fa;
  border-bottom: 1px solid #ebeef5;
  font-weight: 500;
  font-size: 14px;
}

.script-item {
  padding: 12px 15px;
  border-bottom: 1px solid #ebeef5;
  cursor: pointer;
  transition: all 0.2s;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.script-item:hover {
  background: #f5f7fa;
}

.script-item.active {
  background: #ecf5ff;
  border-left: 3px solid #409eff;
}

.script-item.disabled {
  opacity: 0.6;
}

.script-info {
  flex: 1;
  min-width: 0;
}

.script-name {
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 5px;
  display: flex;
  align-items: center;
  gap: 5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.script-placement {
  display: flex;
  gap: 5px;
}

.script-actions {
  display: flex;
  gap: 5px;
  opacity: 0;
  transition: opacity 0.2s;
}

.script-item:hover .script-actions {
  opacity: 1;
}

.script-editor {
  flex: 1;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 20px;
  overflow-y: auto;
}

.empty-state {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed #dcdfe6;
  border-radius: 4px;
}

.hint {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>
