import { flushPromises, mount } from '@vue/test-utils'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { createI18n } from 'vue-i18n'

import zhCN from '@/i18n/locales/zh-CN'
import { DebugEmlUploadError } from '@/services/debugEmlService'
import DebugEmlSuperAgentRunView from '@/views/debug/DebugEmlSuperAgentRunView.vue'

vi.mock('@/services/debugEmlService', async (importOriginal) => {
  const actual = await importOriginal<typeof import('@/services/debugEmlService')>()
  return {
    ...actual,
    uploadDebugEmlSuperAgentRun: vi.fn(),
    uploadDebugEmlSuperAgentRunStream: vi.fn(),
  }
})

const service = await import('@/services/debugEmlService')

function mountView() {
  const i18n = createI18n({
    legacy: false,
    locale: 'zh-CN',
    messages: {
      'zh-CN': zhCN,
    },
  })

  return mount(DebugEmlSuperAgentRunView, {
    global: {
      plugins: [i18n],
    },
  })
}

function createResult() {
  return {
    debug_run_id: '90001',
    source_message_id: '30001',
    source_provider: 'DEBUG_EML_UPLOAD',
    external_message_id: 'debug-eml-run-90001-abcdef123456',
    external_conversation_id: 'debug-thread-90001',
    original_eml_oss_url: 'https://oss.example/raw.eml',
    original_eml_sha256: 'sha256',
    uploaded_media: [
      {
        media_type: 'ORIGINAL_EMAIL',
        file_name: 'booking.eml',
        content_type: 'message/rfc822',
        size_bytes: 1200,
        external_url: 'https://oss.example/raw.eml',
        external_media_id: 'raw',
        object_key: 'debug/eml/raw/booking.eml',
      },
    ],
    html_body_with_oss_urls: '<script>alert("raw")</script><strong onclick="bad()">原始 HTML</strong>',
    html_body_sanitized: '<strong>安全正文</strong>',
    html_sanitize_required: true,
    html_render_mode: 'SANITIZED_HTML',
    agentbus_like_payload: {
      schema_version: 'debug-eml-upload-v1',
      source: {
        original_message_id: '<original@example.test>',
      },
    },
    superagent_session_id: 'session-1',
    superagent_run_id: 'run-1',
    superagent_raw_answer: '{"ok":true}',
    superagent_parsed_json: { ok: true },
    superagent_trace_events: [
      {
        event: 'reasoning.summary',
        run_id: 'run-1',
        message_id: null,
        tool_call_id: null,
        tool_name: null,
        text: '正在分析 Debug 邮件。',
        input_summary: null,
        output_summary: null,
        status: null,
        ts: '2026-07-11T10:00:01Z',
      },
    ],
    warnings: ['SuperAgent 返回非 JSON 时会展示原始回答'],
    status: 'SUPERAGENT_SUCCEEDED',
  }
}

async function chooseFile(wrapper: ReturnType<typeof mountView>) {
  const file = new File(['From: guest@example.test'], 'booking.eml', { type: 'message/rfc822' })
  const input = wrapper.find('input[type="file"]')
  Object.defineProperty(input.element, 'files', {
    value: [file],
    configurable: true,
  })
  await input.trigger('change')
  return file
}

describe('DebugEmlSuperAgentRunView', () => {
  beforeEach(() => {
    vi.mocked(service.uploadDebugEmlSuperAgentRun).mockReset()
    vi.mocked(service.uploadDebugEmlSuperAgentRunStream).mockReset()
  })

  it('streams the selected eml file and renders stages, trace, and sanitized debug result', async () => {
    vi.mocked(service.uploadDebugEmlSuperAgentRunStream).mockImplementation(async (_input, handlers) => {
      handlers?.onStage?.({
        debug_run_id: '90001',
        status: 'PARSING_EML',
        safe_summary: '阶段：解析 EML 邮件。',
      })
      handlers?.onStage?.({
        debug_run_id: '90001',
        status: 'CALLING_SUPERAGENT',
        safe_summary: '阶段：调用 SuperAgent Open API，source_message_id=30001。',
      })
      handlers?.onTrace?.({
        event: 'reasoning.summary',
        run_id: 'run-1',
        message_id: null,
        tool_call_id: null,
        tool_name: null,
        text: '正在分析 Debug 邮件。',
        input_summary: null,
        output_summary: null,
        status: null,
        ts: '2026-07-11T10:00:01Z',
      })
      handlers?.onTrace?.({
        event: 'tool.call.started',
        run_id: 'run-1',
        message_id: 'ai-1',
        tool_call_id: 'tool-1',
        tool_name: 'th_hotel_query_case_context',
        text: null,
        input_summary: '{"group_code":"G001"}',
        output_summary: null,
        status: null,
        ts: '2026-07-11T10:00:02Z',
      })
      return createResult()
    })
    const wrapper = mountView()

    await wrapper.find('input[name="hotel_id"]').setValue('HOTEL-TEST')
    await wrapper.find('input[name="debug_upload_key"]').setValue('manual-debug-key')
    await wrapper.find('input[name="run_label"]').setValue('frontend-smoke')
    const file = await chooseFile(wrapper)
    await wrapper.find('form').trigger('submit')
    await flushPromises()

    expect(service.uploadDebugEmlSuperAgentRunStream).toHaveBeenCalledWith(
      {
        hotelId: 'HOTEL-TEST',
        debugUploadKey: 'manual-debug-key',
        runLabel: 'frontend-smoke',
        file,
      },
      expect.objectContaining({
        onStage: expect.any(Function),
        onTrace: expect.any(Function),
      }),
    )
    expect(wrapper.text()).toContain('PARSING_EML')
    expect(wrapper.text()).toContain('CALLING_SUPERAGENT')
    expect(wrapper.text()).toContain('阶段：解析 EML 邮件。')
    expect(wrapper.text()).toContain('reasoning.summary')
    expect(wrapper.text()).toContain('正在分析 Debug 邮件。')
    expect(wrapper.text()).toContain('th_hotel_query_case_context')
    expect(wrapper.text()).toContain('90001')
    expect(wrapper.text()).toContain('30001')
    expect(wrapper.text()).toContain('DEBUG_EML_UPLOAD')
    expect(wrapper.find('.debug-eml-html-preview').html()).toContain('<strong>安全正文</strong>')
    expect(wrapper.find('.debug-eml-html-preview').html()).not.toContain('<script>')
    expect(wrapper.find('.debug-eml-html-preview').html()).not.toContain('onclick')
    expect(wrapper.text()).toContain('booking.eml')
    expect(wrapper.text()).toContain('"schema_version": "debug-eml-upload-v1"')
    expect(wrapper.text()).toContain('"ok": true')
  })

  it('does not render raw html with oss urls by default', async () => {
    vi.mocked(service.uploadDebugEmlSuperAgentRunStream).mockResolvedValue(createResult())
    const wrapper = mountView()

    await wrapper.find('input[name="hotel_id"]').setValue('HOTEL-TEST')
    await wrapper.find('input[name="debug_upload_key"]').setValue('manual-debug-key')
    await chooseFile(wrapper)
    await wrapper.find('form').trigger('submit')
    await flushPromises()

    expect(wrapper.find('.debug-eml-html-preview').html()).not.toContain('原始 HTML')
    expect(wrapper.find('details.debug-eml-raw-html').text()).toContain('原始 HTML')
  })

  it('shows mapped error_code messages without exposing the debug key', async () => {
    vi.mocked(service.uploadDebugEmlSuperAgentRunStream).mockRejectedValue(
      new DebugEmlUploadError('Debug 上传访问口令缺失或错误。', 401, 'DEBUG_UPLOAD_KEY_INVALID', {
        error_code: 'DEBUG_UPLOAD_KEY_INVALID',
      }),
    )
    const wrapper = mountView()

    await wrapper.find('input[name="hotel_id"]').setValue('HOTEL-TEST')
    await wrapper.find('input[name="debug_upload_key"]').setValue('manual-debug-key')
    await chooseFile(wrapper)
    await wrapper.find('form').trigger('submit')
    await flushPromises()

    expect(wrapper.text()).toContain('DEBUG_UPLOAD_KEY_INVALID')
    expect(wrapper.text()).toContain('调试上传口令缺失或错误')
    expect(wrapper.text()).not.toContain('manual-debug-key')
  })
})
