/**
 * 步骤描述解析工具函数
 *
 * 提供步骤描述到自动化动作的推断转换功能。
 * 根据自然语言步骤描述（如"输入用户名""点击登录按钮"），
 * 自动推断动作类型（action）和动作参数（params）。
 *
 * @module utils/stepParser
 * @author czj
 * @date 2026-07-29
 */

/** 意图步骤数据结构（前端编辑器使用） */
export interface IntentStep {
  order: number
  description: string
  expected: string
  actual: string
  waitAfter: number
  locatorType: string
  locatorValue: string
}

/** 意图步骤编辑器 emit 事件 */
export interface IntentStepEditorEmits {
  (e: 'update:modelValue', value: IntentStep[]): void
  (e: 'locate', index: number): void
}

/**
 * 根据步骤描述自动推断动作类型
 *
 * @param description - 步骤描述文本，如"输入用户名"
 * @returns 动作类型，如 fill / click / navigate 等
 *
 * @example
 * inferAction('输入用户名')   // => 'fill'
 * inferAction('点击登录')     // => 'click'
 * inferAction('打开首页')     // => 'navigate'
 */
export function inferAction(description: string): string {
  const desc = description.toLowerCase()

  if (/打开|导航|访问|进入|跳转|前往/.test(desc)) return 'navigate'
  if (/点击|按下|选择|单击|双击/.test(desc)) return 'click'
  if (/输入|填写|填入|键入|写入/.test(desc)) return 'fill'
  if (/选择|下拉|选取/.test(desc)) return 'select'
  if (/悬停|鼠标移入|hover/.test(desc)) return 'hover'
  if (/等待|延时|等待元素/.test(desc)) return 'wait'
  if (/滚动|滑动|滚到/.test(desc)) return 'scroll'
  if (/按键盘|按|按键|按下.*键/.test(desc)) return 'press'
  if (/勾选|选中|勾上/.test(desc)) return 'check'
  if (/取消勾选|取消选中|取消勾/.test(desc)) return 'uncheck'
  if (/断言|验证|检查|确认|判断|检测/.test(desc)) return 'assert'
  if (/截图|截屏|屏幕截图/.test(desc)) return 'screenshot'

  return 'click' // 默认动作
}

/**
 * 推断动作参数
 *
 * 根据步骤描述和定位值，推断出动作所需的参数。
 * 如 fill 动作需要 selector + value，navigate 需要 url 等。
 *
 * @param description - 步骤描述文本
 * @param locatorValue - 定位值（如 #username）
 * @returns 动作参数字典
 *
 * @example
 * inferParams('输入 admin', '#username')
 * // => { selector: '#username', value: 'admin' }
 */
export function inferParams(description: string, locatorValue: string): Record<string, any> {
  const action = inferAction(description)
  const params: Record<string, any> = {}

  // 需要选择器的动作
  if (['click', 'fill', 'select', 'hover', 'wait', 'check', 'uncheck', 'press'].includes(action)) {
    if (locatorValue) params.selector = locatorValue
  }

  // fill 需要值：从描述提取如"输入 admin" → value="admin"
  if (action === 'fill') {
    const match = description.match(/输入["「『""]?(.+?)["」』""]?$/)
    if (match) params.value = match[1]
  }

  // navigate 需要 URL
  if (action === 'navigate') {
    const match = description.match(/https?:\/\/[^\s]+/)
    if (match) params.url = match[0]
  }

  // assert 需要推断断言类型
  if (action === 'assert') {
    if (/可见|显示|出现/.test(description)) {
      params.type = 'visible'
      params.expected = description.replace(/断言|验证|检查/gi, '').trim()
    } else if (/隐藏|消失|不可见/.test(description)) {
      params.type = 'hidden'
    } else if (/包含|含有/.test(description)) {
      params.type = 'contains'
    } else if (/相等|等于|是/.test(description)) {
      params.type = 'text'
    } else {
      params.type = 'visible' // 默认断言可见
      params.expected = description.replace(/断言|验证|检查/gi, '').trim()
    }
  }

  // scroll 需要方向
  if (action === 'scroll') {
    params.direction = /向上|上滑/.test(description) ? 'up' : 'down'
    params.distance = 300
  }

  return params
}

/**
 * 将意图步骤转换为 StepDefinition 格式
 *
 * 根据步骤描述自动推断 action 和 params，
 * 并将 locator_type / locator_value 同步到 params.selector。
 *
 * @param step - 意图步骤数据
 * @returns 标准 StepDefinition 格式
 *
 * @example
 * toStepDefinition({
 *   order: 1, description: '输入用户名',
 *   expected: '', actual: '', waitAfter: 0,
 *   locatorType: 'css', locatorValue: '#username'
 * })
 * // => { order: 1, name: '输入用户名', action: 'fill', params: { selector: '#username' }, ... }
 */
export function toStepDefinition(step: IntentStep): Record<string, any> {
  const action = inferAction(step.description)
  const params = inferParams(step.description, step.locatorValue)

  // 如果有 locator_value，自动同步到 params.selector
  if (step.locatorValue && !params.selector) {
    params.selector = step.locatorValue
  }

  return {
    order: step.order,
    name: step.description,
    action,
    params,
    expected: step.expected || '',
    actual: step.actual || '',
    waitAfter: step.waitAfter || 0,
    locator_type: step.locatorType || '',
    locator_value: step.locatorValue || '',
  }
}

/**
 * 将后端 StepDefinition 转换为意图步骤格式
 *
 * 用于编辑回显时，将后端存储的步骤数据转换为前端编辑器可用的格式。
 * 如果 locator_type / locator_value 为空，会尝试从 params.selector 自动推断补齐。
 *
 * @param step - 后端返回的 StepDefinition 数据
 * @returns 意图步骤格式
 *
 * @example
 * toIntentStep({ name: '输入用户名', params: { selector: '#username' } })
 * // => { description: '输入用户名', locatorType: 'css', locatorValue: '#username', ... }
 */
export function toIntentStep(step: any): IntentStep {
  const intentStep: IntentStep = {
    order: step.order || 1,
    description: step.name || '',
    expected: step.expected || '',
    actual: step.actual || '',
    waitAfter: step.waitAfter || 0,
    locatorType: step.locator_type || '',
    locatorValue: step.locator_value || '',
  }

  // 自动补齐：如果 locator 为空但 params.selector 有值，从中提取
  if (!intentStep.locatorType && !intentStep.locatorValue && step.params?.selector) {
    const selector = step.params.selector
    if (selector.startsWith('//') || selector.startsWith('(')) {
      intentStep.locatorType = 'xpath'
    } else if (selector.startsWith('#') && !selector.includes(' ')) {
      intentStep.locatorType = 'id'
      intentStep.locatorValue = selector.substring(1)
    } else {
      intentStep.locatorType = 'css'
    }
    intentStep.locatorValue = selector
  }

  return intentStep
}