import { describe, expect, it } from 'vitest'
import type { Message } from '#cli/core/model'
import { createUiThemeContext, resolveUiThemeForMode } from '../theme'
import { renderAssistantMessageLines } from './renderers'

describe('renderAssistantMessageLines', () => {
  it('does not render attach-text tool calls or results', () => {
    const message: Extract<Message, { role: 'assistant' }> = {
      id: 'msg-1',
      role: 'assistant',
      parts: [
        {
          type: 'tool_call',
          call: {
            id: 'call-1',
            name: 'attach-text',
            arguments: {
              path: 'report.md',
              content:
                '{"kind":"respond","text":"# Best-Agent 仓库深度分析报告"}',
            },
          },
        },
        {
          type: 'tool_result',
          result: {
            toolCallId: 'call-1',
            output: 'attachment report.md saved',
            status: 'success',
          },
        },
      ],
    }

    const lines = renderAssistantMessageLines({
      message,
      width: 120,
      contentIndent: 0,
      selectedToolCallId: null,
      expandedBashOutputs: new Set(),
      collapsedToolCallIds: new Set(),
      expandToolCallsAndThinking: true,
      theme: { mode: 'monokai-dark' },
      ui: createUiThemeContext(resolveUiThemeForMode('monokai-dark'), {
        mode: 'truecolor',
        level: 256,
      }),
    })

    expect(lines).toEqual([])
  })

  it('unwraps fenced strict-respond markdown into assistant text instead of rendering a json code block', () => {
    const message: Extract<Message, { role: 'assistant' }> = {
      id: 'msg-2',
      role: 'assistant',
      parts: [
        {
          type: 'markdown',
          markdown:
            '```json\n{"kind":"respond","text":"# Best-Agent 仓库深度分析报告"}\n```',
        },
      ],
    }

    const lines = renderAssistantMessageLines({
      message,
      width: 120,
      contentIndent: 0,
      selectedToolCallId: null,
      expandedBashOutputs: new Set(),
      collapsedToolCallIds: new Set(),
      expandToolCallsAndThinking: true,
      theme: { mode: 'monokai-dark' },
      ui: createUiThemeContext(resolveUiThemeForMode('monokai-dark'), {
        mode: 'truecolor',
        level: 256,
      }),
    })

    expect(lines.some(line => line.text.includes('Best-Agent 仓库深度分析报告'))).toBe(true)
    expect(lines.some(line => line.text.includes('"kind":"respond"'))).toBe(false)
    expect(lines.some(line => line.text.trim() === 'json')).toBe(false)
  })

  it('unwraps JSON-stringified strict-respond markdown into assistant text', () => {
    const message: Extract<Message, { role: 'assistant' }> = {
      id: 'msg-3',
      role: 'assistant',
      parts: [
        {
          type: 'markdown',
          markdown: JSON.stringify('{"kind":"respond","text":"Visible hydrated reply"}'),
        },
      ],
    }

    const lines = renderAssistantMessageLines({
      message,
      width: 120,
      contentIndent: 0,
      selectedToolCallId: null,
      expandedBashOutputs: new Set(),
      collapsedToolCallIds: new Set(),
      expandToolCallsAndThinking: true,
      theme: { mode: 'monokai-dark' },
      ui: createUiThemeContext(resolveUiThemeForMode('monokai-dark'), {
        mode: 'truecolor',
        level: 256,
      }),
    })

    expect(lines.some(line => line.text.includes('Visible hydrated reply'))).toBe(true)
    expect(lines.some(line => line.text.includes('"kind":"respond"'))).toBe(false)
  })

  it('wraps long info notices instead of rendering them as one clipped line', () => {
    const text
      = 'Auto-compaction completed but the estimated input changed from 2363 to 2363 tokens, so this did not reduce request size.'
    const message: Extract<Message, { role: 'assistant' }> = {
      id: 'msg-4',
      role: 'assistant',
      parts: [
        {
          type: 'info',
          text,
        },
      ],
    }

    const lines = renderAssistantMessageLines({
      message,
      width: 36,
      contentIndent: 0,
      selectedToolCallId: null,
      expandedBashOutputs: new Set(),
      collapsedToolCallIds: new Set(),
      expandToolCallsAndThinking: true,
      theme: { mode: 'monokai-dark' },
      ui: createUiThemeContext(resolveUiThemeForMode('monokai-dark'), {
        mode: 'truecolor',
        level: 256,
      }),
    })

    expect(lines.length).toBeGreaterThan(1)
    expect(
      lines.map(line => line.text.trim()).join(' ').replace(/\s+/g, ' '),
    ).toBe(text)
  })
})
