/**
 * Behavioral Rule Extractor — detects correction and confirmation patterns
 * in user messages and extracts structured rules.
 */

import type { Message } from '../../types/message.js'
import { logForDebugging } from '../../utils/debug.js'
import { addRule } from './rules.js'
import type { BehaviorRule } from './types.js'

// Patterns that indicate a user correction
const CORRECTION_PATTERNS = [
  /(?:no,?\s*)?don'?t\s+(.+)/i,
  /(?:no,?\s*)?never\s+(.+)/i,
  /stop\s+(?:doing\s+)?(.+)/i,
  /always\s+(?:make\s+sure\s+to\s+)?(.+)/i,
  /(?:please\s+)?use\s+(.+?)\s+instead\s+of\s+(.+)/i,
  /(?:please\s+)?prefer\s+(.+?)\s+(?:over|instead\s+of)\s+(.+)/i,
  /that'?s\s+(?:not\s+)?(?:right|correct|wrong)[,.]?\s*(.+)/i,
  /(?:I\s+)?(?:told|said|asked)\s+you\s+(?:to\s+)?(.+)/i,
]

// Patterns that indicate user confirmation of an approach
const CONFIRMATION_PATTERNS = [
  /(?:yes|yeah|yep),?\s+(?:exactly|perfect|that'?s?\s+(?:right|correct|it))/i,
  /(?:good|great|nice)\s+(?:approach|choice|decision|call)/i,
  /keep\s+(?:doing|using)\s+(?:that|this)/i,
]

/**
 * Analyze user messages for correction/confirmation patterns.
 * Call this after each conversation turn.
 */
export async function extractBehaviorRules(
  messages: Message[],
): Promise<BehaviorRule[]> {
  const extracted: BehaviorRule[] = []

  // Only look at the most recent user message
  const recentUserMessages = messages
    .filter((m) => m.type === 'user')
    .slice(-2) // Last 2 user messages for context

  for (const msg of recentUserMessages) {
    const text = extractUserText(msg)
    if (!text || text.length < 10) continue

    // Check for corrections
    for (const pattern of CORRECTION_PATTERNS) {
      const match = text.match(pattern)
      if (match) {
        const ruleContent = match[1]?.trim()
        if (!ruleContent || ruleContent.length < 5) continue

        const rule = await addRule({
          trigger: inferTrigger(text, messages),
          action: ruleContent,
          context: inferContext(messages),
          confidence: 0.7,
          source: 'correction',
        })

        extracted.push(rule)
        logForDebugging(`Extracted correction rule: ${rule.action}`)
        break // One rule per message
      }
    }

    // Check for confirmations (lower confidence)
    if (extracted.length === 0) {
      for (const pattern of CONFIRMATION_PATTERNS) {
        if (pattern.test(text)) {
          // Look at what the assistant did in the previous turn
          const approach = extractRecentApproach(messages)
          if (approach) {
            const rule = await addRule({
              trigger: inferTrigger(text, messages),
              action: approach,
              context: inferContext(messages),
              confidence: 0.5,
              source: 'confirmation',
            })
            extracted.push(rule)
            logForDebugging(`Extracted confirmation rule: ${rule.action}`)
          }
          break
        }
      }
    }
  }

  return extracted
}

/**
 * Extract plain text from a user message.
 */
function extractUserText(msg: Message): string | null {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const m = msg as any
  const content = m.message?.content
  if (typeof content === 'string') return content
  if (Array.isArray(content)) {
    return content
      .filter((b: { type: string }) => b.type === 'text')
      .map((b: { text: string }) => b.text)
      .join(' ')
  }
  return null
}

/**
 * Infer a trigger context from the conversation.
 */
function inferTrigger(_text: string, _messages: Message[]): string {
  // Simple heuristic: use "when working in this project" as default
  return 'when working in this project'
}

/**
 * Infer the scope context from recent file operations.
 */
function inferContext(messages: Message[]): string {
  // Look at recent tool uses for file paths
  const recentAssistant = messages
    .filter((m) => m.type === 'assistant')
    .slice(-3)

  for (const msg of recentAssistant) {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const content = (msg as any).message?.content
    if (!Array.isArray(content)) continue

    for (const block of content) {
      if (block.type === 'tool_use' && block.input?.file_path) {
        const filePath = block.input.file_path as string
        // Extract the directory as scope
        const parts = filePath.split(/[/\\]/)
        if (parts.length >= 2) {
          return parts.slice(0, -1).join('/')
        }
      }
    }
  }

  return 'global'
}

/**
 * Extract a description of what the assistant recently did.
 */
function extractRecentApproach(messages: Message[]): string | null {
  const lastAssistant = messages
    .filter((m) => m.type === 'assistant')
    .at(-1)

  if (!lastAssistant) return null

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const content = (lastAssistant as any).message?.content
  if (!Array.isArray(content)) return null

  const toolUses = content.filter(
    (b: { type: string }) => b.type === 'tool_use',
  )

  if (toolUses.length > 0) {
    const toolNames = toolUses
      .map((t: { name: string }) => t.name)
      .join(', ')
    return `approach using ${toolNames}`
  }

  // Extract first text block as approach description
  const textBlock = content.find(
    (b: { type: string }) => b.type === 'text',
  )
  if (textBlock?.text) {
    return textBlock.text.slice(0, 80)
  }

  return null
}
