import { describe, it, expect } from 'vitest'
import {
  parseAiSlashCommand,
  isAiSlashCommandInput,
  orderedAiActions,
} from '../../lib/slash-command.js'

describe('parseAiSlashCommand', () => {
  it('parses /ai rewrite <text>', () => {
    expect(parseAiSlashCommand('/ai rewrite hello world')).toEqual({
      action: 'rewrite',
      text: 'hello world',
    })
  })

  it('parses every canonical action', () => {
    expect(parseAiSlashCommand('/ai expand foo')).toEqual({ action: 'expand', text: 'foo' })
    expect(parseAiSlashCommand('/ai compress bar')).toEqual({ action: 'compress', text: 'bar' })
    expect(parseAiSlashCommand('/ai proofread baz')).toEqual({ action: 'proofread', text: 'baz' })
  })

  it('is case-insensitive on both prefix and action', () => {
    expect(parseAiSlashCommand('/AI Rewrite ALL CAPS')).toEqual({
      action: 'rewrite',
      text: 'ALL CAPS',
    })
    expect(parseAiSlashCommand('/Ai PROOFREAD x')).toEqual({ action: 'proofread', text: 'x' })
  })

  it('tolerates leading whitespace', () => {
    expect(parseAiSlashCommand('   /ai rewrite x')).toEqual({ action: 'rewrite', text: 'x' })
  })

  it('returns empty text when nothing follows the action', () => {
    expect(parseAiSlashCommand('/ai rewrite')).toEqual({ action: 'rewrite', text: '' })
    expect(parseAiSlashCommand('/ai rewrite   ')).toEqual({ action: 'rewrite', text: '' })
  })

  it('trims surrounding whitespace from the payload', () => {
    expect(parseAiSlashCommand('/ai rewrite   hello   ')).toEqual({
      action: 'rewrite',
      text: 'hello',
    })
  })

  it('preserves interior whitespace in the payload', () => {
    expect(parseAiSlashCommand('/ai rewrite hello   world')).toEqual({
      action: 'rewrite',
      text: 'hello   world',
    })
  })

  it('returns null for unknown actions', () => {
    expect(parseAiSlashCommand('/ai summarize foo')).toBeNull()
    expect(parseAiSlashCommand('/ai delete foo')).toBeNull()
  })

  it('returns null for non-AI slash commands', () => {
    expect(parseAiSlashCommand('/help')).toBeNull()
    expect(parseAiSlashCommand('/admin x')).toBeNull()
  })

  it('returns null for plain input without a slash', () => {
    expect(parseAiSlashCommand('ai rewrite hello')).toBeNull()
    expect(parseAiSlashCommand('hello world')).toBeNull()
    expect(parseAiSlashCommand('')).toBeNull()
  })

  it('returns null when /ai is the entire input', () => {
    expect(parseAiSlashCommand('/ai')).toBeNull()
    expect(parseAiSlashCommand('/ai   ')).toBeNull()
  })

  it('returns null for non-string inputs', () => {
    // @ts-expect-error — runtime guard
    expect(parseAiSlashCommand(null)).toBeNull()
    // @ts-expect-error — runtime guard
    expect(parseAiSlashCommand(undefined)).toBeNull()
    // @ts-expect-error — runtime guard
    expect(parseAiSlashCommand(42)).toBeNull()
  })
})

describe('isAiSlashCommandInput', () => {
  it('returns true while the user is mid-typing the prefix', () => {
    expect(isAiSlashCommandInput('/')).toBe(true)
    expect(isAiSlashCommandInput('/a')).toBe(true)
    expect(isAiSlashCommandInput('/ai')).toBe(true)
    expect(isAiSlashCommandInput('/ai ')).toBe(true)
    expect(isAiSlashCommandInput('/ai re')).toBe(true)
    expect(isAiSlashCommandInput('/ai rewrite something')).toBe(true)
  })

  it('returns true when the user typed AI with capitals', () => {
    expect(isAiSlashCommandInput('/AI')).toBe(true)
    expect(isAiSlashCommandInput('/Ai rew')).toBe(true)
  })

  it('returns false for ordinary text', () => {
    expect(isAiSlashCommandInput('')).toBe(false)
    expect(isAiSlashCommandInput('hello')).toBe(false)
    expect(isAiSlashCommandInput('ai rewrite')).toBe(false)
  })

  it('returns false for non-AI slash inputs', () => {
    expect(isAiSlashCommandInput('/help')).toBe(false)
    expect(isAiSlashCommandInput('/bots')).toBe(false)
  })
})

describe('orderedAiActions', () => {
  it('returns the canonical order when nothing is parsed', () => {
    expect(orderedAiActions('')).toEqual(['rewrite', 'expand', 'compress', 'proofread'])
    expect(orderedAiActions('/ai')).toEqual(['rewrite', 'expand', 'compress', 'proofread'])
  })

  it('hoists the matched action to the front', () => {
    expect(orderedAiActions('/ai compress foo')).toEqual([
      'compress',
      'rewrite',
      'expand',
      'proofread',
    ])
    expect(orderedAiActions('/ai proofread bar')).toEqual([
      'proofread',
      'rewrite',
      'expand',
      'compress',
    ])
  })

  it('returns canonical order for an unknown action', () => {
    expect(orderedAiActions('/ai summarize foo')).toEqual([
      'rewrite',
      'expand',
      'compress',
      'proofread',
    ])
  })

  it('contains every canonical action exactly once', () => {
    const result = orderedAiActions('/ai rewrite x')
    expect(result.length).toBe(4)
    expect(new Set(result).size).toBe(4)
  })
})
