<template>
  <div class="space-y-6">
    <!-- 主内容区 -->
    <div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
      <!-- 左侧面板 - 常用示例和选项 -->
      <div class="lg:col-span-1 space-y-6">
        <!-- 常用示例 -->
        <div class="card p-4">
          <h2 class="text-md font-medium text-primary mb-4">常用示例</h2>
          <div class="space-y-2">
            <button
              v-for="(example, index) in examples"
              :key="index"
              class="text-left w-full px-3 py-2 rounded-md text-sm text-secondary hover:bg-hover transition-colors"
              @click="() => applyExample(example)"
            >
              {{ example.name }}
            </button>
          </div>
        </div>
        
        <!-- 正则选项 -->
        <div class="card p-4">
          <div class="flex items-center justify-between mb-4">
            <h2 class="text-md font-medium text-primary">选项</h2>
            <button
              class="text-tertiary hover:text-error transition-colors text-sm"
              @click="clearAll"
            >
              <FontAwesomeIcon :icon="['fas', 'trash']" class="mr-1" />
              清空
            </button>
          </div>
          
          <div class="space-y-4">
            <div>
              <label class="block text-sm text-secondary mb-2">标志位</label>
              <div class="flex flex-wrap gap-2">
                <button
                  :class="flags.includes('g') ? 'btn-primary text-xs' : 'btn-secondary text-xs'"
                  @click="() => toggleFlag('g')"
                >
                  g (全局)
                </button>
                <button
                  :class="flags.includes('i') ? 'btn-primary text-xs' : 'btn-secondary text-xs'"
                  @click="() => toggleFlag('i')"
                >
                  i (忽略大小写)
                </button>
                <button
                  :class="flags.includes('m') ? 'btn-primary text-xs' : 'btn-secondary text-xs'"
                  @click="() => toggleFlag('m')"
                >
                  m (多行)
                </button>
                <button
                  :class="flags.includes('s') ? 'btn-primary text-xs' : 'btn-secondary text-xs'"
                  @click="() => toggleFlag('s')"
                >
                  s (单行)
                </button>
              </div>
            </div>
            
            <div>
              <label class="flex items-center text-sm text-secondary">
                <input
                  v-model="showGroups"
                  type="checkbox"
                  class="mr-2"
                />
                显示捕获组
              </label>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 右侧面板 - 测试区域 -->
      <div class="lg:col-span-3 space-y-6">
        <!-- 正则表达式输入 -->
        <div class="card p-4">
          <div class="flex items-center justify-between mb-4">
            <h2 class="text-md font-medium text-primary">正则表达式</h2>
            <button 
              class="text-tertiary hover:text-primary transition-colors text-sm"
              @click="copyRegex"
              :disabled="!regexString"
            >
              <FontAwesomeIcon :icon="copied ? ['fas', 'check'] : ['fas', 'copy']" class="mr-1" />
              {{ copied ? '已复制' : '复制' }}
            </button>
          </div>
          
          <div class="relative">
            <div class="absolute left-3 top-[13px] text-tertiary">/</div>
            <input
              v-model="regexString"
              type="text"
              placeholder="输入正则表达式..."
              class="input-field pl-7 pr-14"
            />
            <div class="absolute right-14 top-[13px] text-tertiary">/</div>
            <input
              v-model="flags"
              type="text"
              placeholder="flags"
              class="absolute right-3 top-[13px] w-8 bg-transparent border-none outline-none text-tertiary"
            />
          </div>
          
          <div v-if="regexError" class="mt-2 text-sm text-error flex items-center gap-2">
            <FontAwesomeIcon :icon="['fas', 'exclamation-triangle']" />
            <span>{{ regexError }}</span>
          </div>
        </div>
        
        <!-- 测试输入 -->
        <div class="card p-4">
          <div class="flex items-center justify-between mb-4">
            <h2 class="text-md font-medium text-primary">测试文本</h2>
            <div class="text-sm text-secondary">
              字符数: <span class="text-primary">{{ testString.length }}</span>
            </div>
          </div>
          
          <textarea
            v-model="testString"
            placeholder="输入要测试的文本..."
            class="textarea-field min-h-[150px] w-full resize-y"
          />
        </div>
        
        <!-- 匹配结果 -->
        <div class="card p-4">
          <div class="flex items-center justify-between mb-4">
            <h2 class="text-md font-medium text-primary">匹配结果</h2>
            <div class="text-sm text-secondary">
              匹配数量: <span class="text-primary">{{ matchCount }}</span>
            </div>
          </div>
          
          <div v-if="testString" class="space-y-4">
            <!-- 高亮显示的匹配文本 -->
            <div class="bg-block rounded-md p-4 whitespace-pre-wrap font-mono text-sm">
              <div v-if="matchCount > 0">
                <div class="mb-3 text-tertiary text-xs flex items-center justify-between">
                  <span>
                    找到 <span class="text-primary font-medium">{{ matchCount }}</span> 个匹配项
                  </span>
                  <span class="text-tertiary text-xs">
                    原文长度: {{ testString.length }} 字符
                  </span>
                </div>
                
                <!-- 使用 v-html 显示高亮结果，但要确保安全 -->
                <div v-html="highlightedText" class="break-all"></div>
              </div>
              <span v-else class="text-tertiary">无匹配项</span>
            </div>
            
            <!-- 捕获组详情 -->
            <div v-if="showGroups && matchCount > 0">
              <h3 class="text-sm font-medium text-primary mb-2">捕获组详情</h3>
              <div class="space-y-2">
                <div
                  v-for="(match, index) in matches"
                  :key="index"
                  class="bg-block rounded-md p-3"
                >
                  <div class="text-xs text-tertiary mb-2">
                    匹配 #{{ index + 1 }} (位置: {{ match.index }})
                  </div>
                  
                  <div class="space-y-1">
                    <div class="flex items-start gap-2">
                      <span class="text-xs text-tertiary min-w-[40px]">完整:</span>
                      <code class="text-sm text-primary bg-primary/10 px-1 rounded break-all">
                        {{ match[0] || '' }}
                      </code>
                    </div>
                    
                    <div
                      v-for="group in Math.max(0, match.length - 1)"
                      :key="group"
                      class="flex items-start gap-2"
                    >
                      <span class="text-xs text-tertiary min-w-[40px]">组 {{ group }}:</span>
                      <code class="text-sm text-primary bg-primary/10 px-1 rounded break-all">
                        {{ match[group] || '(空)' }}
                      </code>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          
          <div v-else class="flex items-center justify-center p-4 text-tertiary">
            <FontAwesomeIcon :icon="['fas', 'info-circle']" class="mr-2" />
            请输入测试文本
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

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

// 定义匹配结果类型
interface MatchResult extends RegExpExecArray {
  index: number
}

// 响应式状态
const regexString = ref('')
const flags = ref('g')
const testString = ref('')
const matches = ref<MatchResult[]>([])
const matchCount = ref(0)
const showGroups = ref(true)
const regexError = ref<string | null>(null)
const copied = ref(false)

// 常用正则表达式示例
const examples = [
  {
    name: '邮箱地址',
    pattern: '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}',
    flags: 'g',
    testText: 'test@example.com, invalid-email, another.email@domain.co.uk'
  },
  {
    name: '手机号码',
    pattern: '1[3-9]\\d{9}',
    flags: 'g',
    testText: '我的手机号是13812345678，她的是15987654321，座机010-12345678'
  },
  {
    name: 'URL地址',
    pattern: 'https?://[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&//=]*)',
    flags: 'g',
    testText: '访问 https://www.example.com 或 http://test.org/path?query=1'
  },
  {
    name: 'IP地址',
    pattern: '\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b',
    flags: 'g',
    testText: '服务器IP: 192.168.1.1, 公网IP: 8.8.8.8, 错误格式: 999.999.999.999'
  },
  {
    name: '中文字符',
    pattern: '[\\u4e00-\\u9fa5]',
    flags: 'g',
    testText: 'Hello 世界! This is 中文 mixed with English.'
  }
]

// HTML转义函数
const escapeHtml = (text: string): string => {
  if (!text) return ''
  return String(text)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;')
}

// 计算高亮文本
const highlightedText = computed(() => {
  if (!testString.value || matchCount.value === 0) {
    return escapeHtml(testString.value)
  }
  
  let result = ''
  let lastIndex = 0
  
  // 按索引顺序排序匹配项
  const sortedMatches = [...matches.value].sort((a, b) => a.index - b.index)
  
  // 遍历每个匹配项
  sortedMatches.forEach(match => {
    // 添加匹配前的文本
    result += escapeHtml(testString.value.substring(lastIndex, match.index))
    
    // 添加高亮的匹配内容
    result += `<span style="background-color:rgba(var(--color-primary), 0.3); color:rgb(var(--color-primary)); font-weight:bold; padding:0 4px; border-radius:3px;">${escapeHtml(match[0])}</span>`
    
    // 更新lastIndex
    lastIndex = match.index + match[0].length
  })
  
  // 添加最后一个匹配后的文本
  if (lastIndex < testString.value.length) {
    result += escapeHtml(testString.value.substring(lastIndex))
  }
  
  return result
})

// 测试正则表达式
const testRegex = () => {
  if (!regexString.value || !testString.value) {
    matches.value = []
    matchCount.value = 0
    regexError.value = null
    return
  }
  
  try {
    // 验证正则表达式是否有效
    new RegExp(regexString.value, flags.value)
    regexError.value = null
    
    if (flags.value.includes('g')) {
      // 获取所有匹配
      const allMatches: MatchResult[] = []
      let match: RegExpExecArray | null
      const regexWithGroups = new RegExp(regexString.value, flags.value)
      
      // 收集所有匹配和捕获组
      while ((match = regexWithGroups.exec(testString.value)) !== null) {
        allMatches.push(match as MatchResult)
        
        // 防止无限循环，如果匹配长度为0，手动增加索引
        if (match.index === regexWithGroups.lastIndex) {
          regexWithGroups.lastIndex++
        }
      }
      
      matches.value = allMatches
      matchCount.value = allMatches.length
    } else {
      // 单次匹配模式
      const regexWithoutG = new RegExp(regexString.value, flags.value.replace('g', ''))
      const execMatch = regexWithoutG.exec(testString.value)
      
      if (execMatch) {
        matches.value = [execMatch as MatchResult]
        matchCount.value = 1
      } else {
        matches.value = []
        matchCount.value = 0
      }
    }
  } catch (error) {
    console.error('正则表达式错误:', error)
    regexError.value = (error as Error).message
    matches.value = []
    matchCount.value = 0
  }
}

// 复制正则表达式
const copyRegex = async () => {
  if (!regexString.value) return
  
  try {
    const regexText = `/${regexString.value}/${flags.value}`
    await navigator.clipboard.writeText(regexText)
    copied.value = true
    setTimeout(() => {
      copied.value = false
    }, 2000)
  } catch (error) {
    console.error('复制失败:', error)
  }
}

// 应用示例
const applyExample = (example: { pattern: string; flags: string; testText: string }) => {
  regexString.value = example.pattern
  flags.value = example.flags
  testString.value = example.testText
}

// 清空所有内容
const clearAll = () => {
  regexString.value = ''
  flags.value = 'g'
  testString.value = ''
  matches.value = []
  matchCount.value = 0
  regexError.value = null
}

// 切换标志位
const toggleFlag = (flag: string) => {
  if (flags.value.includes(flag)) {
    flags.value = flags.value.replace(flag, '')
  } else {
    flags.value = flags.value + flag
  }
}

// 监听输入变化，自动测试
watch([regexString, flags, testString, showGroups], () => {
  testRegex()
}, { immediate: true })
</script> 