export type SlotType = 'string' | 'number' | 'boolean' | 'enum' | 'array_enum'
export type ExtractStrategy = 'rule' | 'llm' | 'user_input'
export type SlotSource = 'user_confirmed' | 'rule_extracted' | 'llm_inferred' | 'default'

/**
 * [AC-MRS-07-UPGRADE] 提取失败类型
 */
export type ExtractFailureType = 
  | 'EXTRACT_EMPTY' 
  | 'EXTRACT_PARSE_FAIL' 
  | 'EXTRACT_VALIDATION_FAIL' 
  | 'EXTRACT_RUNTIME_ERROR'

export interface SlotDefinition {
  id: string
  tenant_id: string
  slot_key: string
  display_name?: string
  description?: string
  type: SlotType
  required: boolean
  /**
   * [AC-MRS-07-UPGRADE] 兼容字段：单提取策略，已废弃
   */
  extract_strategy?: ExtractStrategy
  /**
   * [AC-MRS-07-UPGRADE] 提取策略链：有序数组，按顺序执行直到成功
   */
  extract_strategies?: ExtractStrategy[]
  validation_rule?: string
  ask_back_prompt?: string
  default_value?: string | number | boolean | string[]
  linked_field_id?: string
  linked_field?: LinkedField
  created_at?: string
  updated_at?: string
}

export interface LinkedField {
  id: string
  field_key: string
  label: string
  type: string
  field_roles: string[]
}

export interface SlotDefinitionCreateRequest {
  tenant_id?: string
  slot_key: string
  display_name?: string
  description?: string
  type: SlotType
  required: boolean
  /**
   * [AC-MRS-07-UPGRADE] 提取策略链
   */
  extract_strategies?: ExtractStrategy[]
  /**
   * [AC-MRS-07-UPGRADE] 兼容字段
   */
  extract_strategy?: ExtractStrategy
  validation_rule?: string
  ask_back_prompt?: string
  default_value?: string | number | boolean | string[]
  linked_field_id?: string
}

export interface SlotDefinitionUpdateRequest {
  display_name?: string
  description?: string
  type?: SlotType
  required?: boolean
  /**
   * [AC-MRS-07-UPGRADE] 提取策略链
   */
  extract_strategies?: ExtractStrategy[]
  /**
   * [AC-MRS-07-UPGRADE] 兼容字段
   */
  extract_strategy?: ExtractStrategy
  validation_rule?: string
  ask_back_prompt?: string
  default_value?: string | number | boolean | string[]
  linked_field_id?: string
}

export interface RuntimeSlotValue {
  key: string
  value: string | number | boolean | string[] | undefined
  source: SlotSource
  confidence: number
  updated_at?: string
}

/**
 * [AC-MRS-07-UPGRADE] 策略链执行步骤结果
 */
export interface StrategyStepResult {
  strategy: ExtractStrategy
  success: boolean
  value?: string | number | boolean | string[]
  failure_type?: ExtractFailureType
  failure_reason?: string
  execution_time_ms: number
}

/**
 * [AC-MRS-07-UPGRADE] 策略链执行结果
 */
export interface StrategyChainResult {
  slot_key: string
  success: boolean
  final_value?: string | number | boolean | string[]
  final_strategy?: ExtractStrategy
  steps: StrategyStepResult[]
  total_execution_time_ms: number
  ask_back_prompt?: string
}

export const SLOT_TYPE_OPTIONS = [
  { value: 'string', label: '文本' },
  { value: 'number', label: '数字' },
  { value: 'boolean', label: '布尔值' },
  { value: 'enum', label: '单选枚举' },
  { value: 'array_enum', label: '多选枚举' }
]

export const EXTRACT_STRATEGY_OPTIONS = [
  { value: 'rule', label: '规则提取', description: '通过预定义规则从对话中提取' },
  { value: 'llm', label: 'LLM 推断', description: '通过大语言模型推断槽位值' },
  { value: 'user_input', label: '用户输入', description: '通过追问提示语让用户主动输入' }
]

/**
 * [AC-MRS-07-UPGRADE] 提取策略链验证
 */
export function validateExtractStrategies(strategies: ExtractStrategy[]): { valid: boolean; error?: string } {
  if (!strategies || strategies.length === 0) {
    return { valid: true } // 空数组视为有效
  }

  const validStrategies = new Set(['rule', 'llm', 'user_input'])
  
  // 检查重复
  const uniqueStrategies = new Set(strategies)
  if (uniqueStrategies.size !== strategies.length) {
    return { valid: false, error: '提取策略链中不允许重复的策略' }
  }
  
  // 检查有效性
  const invalid = strategies.filter(s => !validStrategies.has(s))
  if (invalid.length > 0) {
    return { valid: false, error: `无效的提取策略: ${invalid.join(', ')}` }
  }
  
  return { valid: true }
}

/**
 * [AC-MRS-07-UPGRADE] 获取有效的策略链
 * 优先使用 extract_strategies，如果不存在则兼容读取 extract_strategy
 */
export function getEffectiveStrategies(slot: SlotDefinition): ExtractStrategy[] {
  if (slot.extract_strategies && slot.extract_strategies.length > 0) {
    return slot.extract_strategies
  }
  if (slot.extract_strategy) {
    return [slot.extract_strategy]
  }
  return []
}
