import assert from 'node:assert/strict'
import test from 'node:test'

import { useWorkbenchAiApplicationPreviewFlow } from '../src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js'

function createRef(value) {
  return { value }
}

function createInlineMessage(role, content, options = {}) {
  return {
    id: options.id || `msg-${Math.random().toString(16).slice(2)}`,
    role,
    content,
    text: content,
    paragraphs: String(content || '').split(/\n+/).filter(Boolean),
    pending: Boolean(options.pending),
    ...options
  }
}

function buildApplicationPreviewFlowHarness(messages, options = {}) {
  const conversationMessages = createRef(messages)
  const applicationSubmitConfirmOpen = createRef(false)
  const applicationSubmitConfirmContext = createRef(null)
  const persisted = createRef(0)

  const flow = useWorkbenchAiApplicationPreviewFlow({
    activateInlineConversation: () => {},
    applicationPreviewEditor: createRef({}),
    applicationSubmitConfirmContext,
    applicationSubmitConfirmOpen,
    assistantDraft: createRef(''),
    cancelApplicationPreviewEditor: () => {},
    clearAiModeFiles: () => {},
    closeWorkbenchDatePicker: () => {},
    commitApplicationPreviewEditor: async () => true,
    conversationId: createRef('conversation-context-submit'),
    conversationMessages,
    conversationStarted: createRef(true),
    createInlineMessage,
    currentUser: createRef({ username: 'zhangsan@example.com', name: '张三' }),
    handleApplicationPreviewEditorKeydown: () => {},
    inlineConversationAutoScrollPinned: createRef(true),
    isApplicationPreviewEditing: createRef(false),
    openApplicationPreviewEditor: () => {},
    persistCurrentConversation: () => { persisted.value += 1 },
    pushInlineApplicationActionUserMessage: (text) => {
      conversationMessages.value.push(createInlineMessage('user', text))
    },
    pushInlineUserMessage: (text) => {
      conversationMessages.value.push(createInlineMessage('user', text))
    },
    refreshApplicationPreviewEstimate: async (preview) => preview,
    removeWorkbenchDateTag: () => {},
    replaceInlineMessage: (id, nextMessage) => {
      const index = conversationMessages.value.findIndex((item) => item.id === id)
      if (index >= 0) {
        conversationMessages.value.splice(index, 1, nextMessage)
      } else {
        conversationMessages.value.push(nextMessage)
      }
    },
    resolveApplicationPreviewEditorDateMax: () => '',
    resolveApplicationPreviewEditorDateMin: () => '',
    resolveApplicationPreviewEditorControl: () => null,
    resolveApplicationPreviewEditorOptions: () => [],
    resolveInlineThinkingEvents: (message) => message?.stewardPlan?.thinkingEvents || [],
    resolveLatestInlineUserPrompt: () => '2026-02-20 至 2026-02-23，去上海出差，交通火车，保存草稿',
    scrollInlineConversationToBottom: () => {},
    sending: createRef(false),
    toast: () => {},
    onApplicationActionCompleted: options.onApplicationActionCompleted
  })

  return {
    applicationSubmitConfirmOpen,
    conversationMessages,
    flow,
    persisted
  }
}

test('workbench auto-saved application draft continues remaining steward task', async () => {
  const originalFetch = globalThis.fetch
  const requests = []
  globalThis.fetch = async (url, options = {}) => {
    const normalizedUrl = String(url)
    if (normalizedUrl.includes('/reimbursements/application-preview-action')) {
      const body = JSON.parse(String(options.body || '{}'))
      requests.push({ url: normalizedUrl, body })
      return {
        ok: true,
        async json() {
          return {
            status: 'succeeded',
            result: {
              draft_payload: {
                claim_id: 'claim-auto-saved-draft',
                claim_no: 'AEW2DDAFL',
                status: 'draft'
              }
            }
          }
        }
      }
    }
    throw new Error(`unexpected request: ${normalizedUrl}`)
  }

  try {
    const continuedTasks = []
    const remainingTasks = [{
      task_id: 'task-reimbursement-2',
      task_type: 'reimbursement',
      assigned_agent: 'reimbursement_assistant',
      summary: '报销昨天的业务招待费 2000 元',
      ontology_fields: {
        expense_type: 'entertainment',
        amount: '2000元',
        time_range: '2026-06-25',
        reason: '业务招待费报销'
      }
    }]
    const harness = buildApplicationPreviewFlowHarness([], {
      onApplicationActionCompleted: (tasks, sourceMessage) => {
        continuedTasks.push({ tasks, sourceMessage })
      }
    })

    await harness.flow.startAiApplicationPreview('travel', '差旅费', '2月20-23日去上海出差3天，服务国网服务器部署，并且报销昨天的业务招待费2000元', {
      autoSaveDraft: true,
      stewardRemainingTasks: remainingTasks,
      onApplicationActionCompleted: (tasks, sourceMessage) => {
        continuedTasks.push({ tasks, sourceMessage, fromOptions: true })
      }
    })

    assert.equal(requests.length, 1)
    assert.equal(continuedTasks.length, 1)
    assert.deepEqual(continuedTasks[0].tasks, remainingTasks)
    assert.equal(continuedTasks[0].sourceMessage.stewardRemainingTasks, remainingTasks)
    assert.equal(continuedTasks[0].fromOptions, true)
    assert.doesNotMatch(harness.conversationMessages.value.at(-1).content, /继续处理费用报销/)
  } finally {
    globalThis.fetch = originalFetch
  }
})

test('workbench saved application draft can be submitted by contextual text without re-planning', async () => {
  const originalFetch = globalThis.fetch
  const requests = []
  globalThis.fetch = async (url, options = {}) => {
    const normalizedUrl = String(url)
    if (normalizedUrl.includes('/reimbursements/claims')) {
      return {
        ok: true,
        async json() {
          return { items: [] }
        }
      }
    }
    if (normalizedUrl.includes('/reimbursements/application-preview-action')) {
      const body = JSON.parse(String(options.body || '{}'))
      requests.push({ url: normalizedUrl, body })
      return {
        ok: true,
        async json() {
          return {
            status: 'succeeded',
            result: {
              draft_payload: {
                claim_id: 'claim-saved-draft',
                claim_no: 'A20260220',
                status: 'submitted',
                approval_stage: '直属领导审批'
              }
            }
          }
        }
      }
    }
    throw new Error(`unexpected request: ${normalizedUrl}`)
  }

  try {
    const previewMessage = createInlineMessage('assistant', '申请核对表', {
      id: 'application-preview-1',
      applicationPreview: {
        readyToSubmit: true,
        fields: {
          applicationType: '差旅费用申请',
          time: '2026-02-20 至 2026-02-23',
          location: '上海',
          reason: '辅助国网仿生产服务器部署',
          days: '4天',
          transportMode: '火车',
          amount: '1200元'
        },
        missingFields: [],
        validationIssues: []
      },
      draftPayload: {
        claim_id: 'claim-saved-draft',
        claim_no: 'A20260220',
        status: 'draft'
      }
    })
    const harness = buildApplicationPreviewFlowHarness([
      createInlineMessage('user', '2026-02-20 至 2026-02-23，去上海出差，交通火车，保存草稿'),
      previewMessage,
      createInlineMessage('assistant', '### 申请草稿已保存', {
        draftPayload: previewMessage.draftPayload
      })
    ])

    const handled = harness.flow.handleInlineApplicationPreviewTextAction(
      '提交这个单据',
      createRef(false)
    )
    assert.equal(handled, true)
    await new Promise((resolve) => setTimeout(resolve, 0))

    assert.equal(harness.applicationSubmitConfirmOpen.value, false)
    assert.equal(requests.length, 1)
    assert.equal(requests[0].body.context_json.application_edit_claim_id, 'claim-saved-draft')
    assert.equal(requests[0].body.context_json.application_edit_mode, true)
    assert.match(harness.conversationMessages.value.at(-1).content, /申请单据已生成/)
    assert.ok(harness.persisted.value > 0)
  } finally {
    globalThis.fetch = originalFetch
  }
})
