import { normalizeApplicationPreview } from '../../utils/expenseApplicationPreview.js'
import { fetchStewardRuntimeDecision } from '../../services/steward.js'
import { resolveStewardRuntimeFieldCompletion } from './stewardFieldCompletionModel.js'
import {
  SESSION_TYPE_APPLICATION,
  SESSION_TYPE_EXPENSE,
  SESSION_TYPE_STEWARD
} from './travelReimbursementConversationModel.js'
import {
  isApplicationSubmitConfirmationText,
  isStewardRuntimeCancelText,
  isStewardRuntimeContinueText,
  normalizeStewardRuntimeInputText,
  resolveStewardRuntimeTransportAlias,
  shouldPlanNewStewardTasksLocally
} from './travelReimbursementStewardRuntimeTextModel.js'
import { STEWARD_ASSISTANT_NAME } from './useTravelReimbursementStewardRuntime.js'

export function useTravelReimbursementStewardRuntimeDecision({
  APPLICATION_PREVIEW_FIELD_ACTION_SET,
  activeSessionType,
  adjustComposerTextareaHeight,
  applicationSubmitConfirmDialog,
  attachedFiles,
  composerDraft,
  continueStewardApplicationFieldCompletion,
  conversationId,
  createMessage,
  handleSuggestedAction,
  isStewardSession,
  messages,
  nextTick,
  persistSessionState,
  props,
  reviewActionBusy,
  resolveCurrentUserId,
  scrollToBottom,
  stewardState,
  submitComposer,
  submitComposerInternal,
  submitStewardPlan,
  submitting,
  confirmApplicationSubmit
}) {
    function findLatestApplicationPreviewMessage() {
      for (const message of [...messages.value].reverse()) {
        if (
          message?.role !== 'assistant' ||
          !message.applicationPreview ||
          message.applicationSubmitConfirmed
        ) {
          continue
        }
        return message
      }
      return null
    }

    function findPendingApplicationSubmitMessage() {
      const message = findLatestApplicationPreviewMessage()
      if (!message) {
        return null
      }
      const normalizedPreview = normalizeApplicationPreview(message.applicationPreview)
      if (normalizedPreview.readyToSubmit) {
        message.applicationPreview = normalizedPreview
        return message
      }
      return null
    }

    function pushApplicationSubmitBlockedMessage(userText = '', message = null, options = {}) {
      const normalizedPreview = normalizeApplicationPreview(message?.applicationPreview || {})
      const missingFields = Array.isArray(normalizedPreview.missingFields)
        ? normalizedPreview.missingFields
        : []
      if (userText && !options.userMessageAlreadyAdded) {
        messages.value.push(createMessage('user', userText))
      }
      messages.value.push(createMessage(
        'assistant',
        [
          '我理解您是在确认当前申请单，但这张申请单还不能提交。',
          '',
          missingFields.length
            ? `还需要先补充：**${missingFields.join('、')}**。`
            : '请先把申请核对表中的待补充信息补齐。',
          '',
          '补齐后再输入“确认”，我会继续提交至审批流程。'
        ].join('\n'),
        [],
        {
          assistantName: String(message?.assistantName || '').trim() || undefined,
          meta: ['等待补充']
        }
      ))
      composerDraft.value = ''
      persistSessionState()
      nextTick(() => {
        adjustComposerTextareaHeight()
        scrollToBottom()
      })
    }

    async function handleApplicationSubmitConfirmationText(options = {}) {
      const rawText = String(options.rawText ?? composerDraft.value ?? '').trim()
      const files = Array.from(options.files ?? attachedFiles.value ?? [])
      if (!isApplicationSubmitConfirmationText(rawText) || files.length) {
        return false
      }
      const latestApplicationMessage = findLatestApplicationPreviewMessage()
      if (!latestApplicationMessage) {
        return false
      }
      const targetMessage = findPendingApplicationSubmitMessage()
      if (!targetMessage) {
        pushApplicationSubmitBlockedMessage(rawText, latestApplicationMessage)
        return true
      }
      applicationSubmitConfirmDialog.value = {
        open: true,
        message: targetMessage
      }
      await confirmApplicationSubmit({ userText: rawText })
      return true
    }

    function findPendingStewardSuggestedActionContext(decision = null) {
      const targetMessageId = String(decision?.target_message_id || decision?.targetMessageId || '').trim()
      const targetTaskId = String(decision?.target_task_id || decision?.targetTaskId || '').trim()
      for (const message of [...messages.value].reverse()) {
        if (
          message?.role !== 'assistant' ||
          message.suggestedActionsLocked ||
          !Array.isArray(message.suggestedActions) ||
          !message.suggestedActions.length
        ) {
          continue
        }
        if (targetMessageId && String(message.id || '') !== targetMessageId) {
          continue
        }
        const action = message.suggestedActions.find((item) => {
          if (String(item?.action_type || '').trim() === APPLICATION_PREVIEW_FIELD_ACTION_SET) {
            return false
          }
          const payload = item?.payload && typeof item.payload === 'object' ? item.payload : {}
          return !targetTaskId ||
            String(payload.steward_next_task_id || payload.target_task_id || '').trim() === targetTaskId
        }) || message.suggestedActions[0]
        if (action) {
          return { message, action }
        }
      }
      return null
    }

    function findPendingSlotSuggestedActionContext(decision = null) {
      const fieldKey = String(decision?.field_key || decision?.fieldKey || '').trim()
      const fieldValue = String(decision?.field_value || decision?.fieldValue || '').trim()
      for (const message of [...messages.value].reverse()) {
        if (
          message?.role !== 'assistant' ||
          message.suggestedActionsLocked ||
          !Array.isArray(message.suggestedActions) ||
          !message.suggestedActions.length
        ) {
          continue
        }
        const action = message.suggestedActions.find((item) => {
          if (String(item?.action_type || '').trim() !== APPLICATION_PREVIEW_FIELD_ACTION_SET) {
            return false
          }
          const payload = item?.payload && typeof item.payload === 'object' ? item.payload : {}
          const payloadField = String(payload.field_key || payload.fieldKey || '').trim()
          const payloadValue = String(payload.value || item?.label || '').trim()
          return payloadField && (!fieldKey || payloadField === fieldKey) && (!fieldValue || payloadValue === fieldValue)
        })
        if (action) {
          return { message, action }
        }
      }
      return null
    }

    function findPendingSlotSuggestedActionContextByInput(rawText = '') {
      const normalizedInput = normalizeStewardRuntimeInputText(rawText)
      if (!normalizedInput) {
        return null
      }
      const transportAlias = resolveStewardRuntimeTransportAlias(normalizedInput)
      for (const message of [...messages.value].reverse()) {
        if (
          message?.role !== 'assistant' ||
          message.suggestedActionsLocked ||
          !Array.isArray(message.suggestedActions) ||
          !message.suggestedActions.length
        ) {
          continue
        }

        const exactMatches = []
        const fuzzyMatches = []
        message.suggestedActions.forEach((action) => {
          if (String(action?.action_type || '').trim() !== APPLICATION_PREVIEW_FIELD_ACTION_SET) {
            return
          }
          const payload = action?.payload && typeof action.payload === 'object' ? action.payload : {}
          const fieldKey = String(payload.field_key || payload.fieldKey || '').trim()
          const value = String(payload.value || action?.label || '').trim()
          const label = String(action?.label || value).trim()
          const tokens = [value, label]
            .map((item) => normalizeStewardRuntimeInputText(item))
            .filter(Boolean)
          if (!fieldKey || !value || !tokens.length) {
            return
          }
          if (tokens.includes(normalizedInput)) {
            exactMatches.push({ message, action })
            return
          }
          const actionTransportAlias = resolveStewardRuntimeTransportAlias(`${value}${label}`)
          if (
            transportAlias &&
            (
              tokens.includes(normalizeStewardRuntimeInputText(transportAlias)) ||
              actionTransportAlias === transportAlias
            )
          ) {
            fuzzyMatches.push({ message, action })
            return
          }
          if (tokens.some((token) => token.length >= 2 && normalizedInput.includes(token))) {
            fuzzyMatches.push({ message, action })
          }
        })

        if (exactMatches.length === 1) {
          return exactMatches[0]
        }
        if (exactMatches.length > 1) {
          return null
        }
        const uniqueFuzzyMatches = fuzzyMatches.filter((item, index, list) =>
          list.findIndex((candidate) => candidate.action === item.action) === index
        )
        if (uniqueFuzzyMatches.length === 1) {
          return uniqueFuzzyMatches[0]
        }
        if (uniqueFuzzyMatches.length > 1) {
          return null
        }
      }
      return null
    }

    function buildStewardRuntimeState() {
      const latestApplicationMessage = findLatestApplicationPreviewMessage()
      const applicationPreview = latestApplicationMessage?.applicationPreview
        ? normalizeApplicationPreview(latestApplicationMessage.applicationPreview)
        : null
      const applicationContinuation = latestApplicationMessage?.stewardContinuation || null
      const pendingSlotContext = findPendingSlotSuggestedActionContext()
      const pendingStewardContext = pendingSlotContext ? null : findPendingStewardSuggestedActionContext()
      const pendingActionPayload = pendingStewardContext?.action?.payload && typeof pendingStewardContext.action.payload === 'object'
        ? pendingStewardContext.action.payload
        : {}
      const pendingSlotPayload = pendingSlotContext?.action?.payload && typeof pendingSlotContext.action.payload === 'object'
        ? pendingSlotContext.action.payload
        : {}
      const continuation = applicationContinuation || pendingStewardContext?.message?.stewardContinuation || null
      const remainingTasks = Array.isArray(continuation?.remainingTasks)
        ? continuation.remainingTasks
        : []
      const pendingApplication = latestApplicationMessage && applicationPreview
        ? {
            message_id: String(latestApplicationMessage.id || '').trim(),
            task_id: String(
              applicationContinuation?.currentTaskId ||
              applicationContinuation?.current_task_id ||
              applicationContinuation?.currentTask?.task_id ||
              applicationContinuation?.currentTask?.taskId ||
              ''
            ).trim(),
            ready_to_submit: Boolean(applicationPreview.readyToSubmit),
            missing_fields: Array.isArray(applicationPreview.missingFields) ? applicationPreview.missingFields : [],
            fields: applicationPreview.fields || {}
          }
        : null
      return {
        waiting_for: pendingApplication
          ? (pendingApplication.ready_to_submit ? 'application_submit_confirmation' : 'application_field_completion')
          : pendingSlotContext
            ? 'application_field_completion'
          : pendingStewardContext
            ? 'steward_next_task_confirmation'
            : '',
        current_task: continuation?.currentTask || continuation?.current_task || null,
        remaining_tasks: remainingTasks,
        completed_tasks: messages.value
          .filter((message) => message?.applicationSubmitConfirmed)
          .map((message) => ({
            message_id: String(message.id || '').trim(),
            task_type: 'expense_application'
          })),
        pending_application: pendingApplication,
        pending_steward_action: pendingStewardContext
          ? {
              message_id: String(pendingStewardContext.message?.id || '').trim(),
              action_type: String(pendingStewardContext.action?.action_type || '').trim(),
              label: String(pendingStewardContext.action?.label || '').trim(),
              target_task_id: String(pendingActionPayload.steward_next_task_id || pendingActionPayload.target_task_id || '').trim(),
              payload: pendingActionPayload
            }
          : null,
        pending_slot_action: pendingSlotContext
          ? {
              message_id: String(pendingSlotContext.message?.id || '').trim(),
              field_key: String(pendingSlotPayload.field_key || pendingSlotPayload.fieldKey || '').trim(),
              label: String(pendingSlotContext.action?.label || '').trim(),
              payload: pendingSlotPayload
            }
          : null,
        steward_state: stewardState.value || null
      }
    }

    function hasActiveStewardRuntimeDecisionContext(runtimeState = {}) {
      return Boolean(
        String(runtimeState?.waiting_for || '').trim() ||
        runtimeState?.pending_application ||
        runtimeState?.pending_steward_action ||
        runtimeState?.pending_slot_action ||
        runtimeState?.current_task ||
        runtimeState?.steward_state ||
        (Array.isArray(runtimeState?.remaining_tasks) && runtimeState.remaining_tasks.length > 0) ||
        (Array.isArray(runtimeState?.completed_tasks) && runtimeState.completed_tasks.length > 0)
      )
    }

    function resolveStewardStateFlow(state = {}, flowId = '') {
      const flows = state?.flows && typeof state.flows === 'object' ? state.flows : {}
      const flow = flows[String(flowId || '').trim()]
      return flow && typeof flow === 'object' ? flow : null
    }

    function buildSelectedStewardFlowTaskPayload(flowId = '', flow = {}) {
      return {
        task_id: String(flowId || '').trim(),
        task_type: flowId === 'travel_application' ? 'expense_application' : 'reimbursement',
        title: flowId === 'travel_application' ? '补办出差申请' : '发起费用报销',
        summary: buildSelectedStewardFlowSummary(flow),
        assigned_agent: flowId === 'travel_application' ? 'application_assistant' : 'reimbursement_assistant',
        ontology_fields: flow?.fields || {},
        missing_fields: Array.isArray(flow?.missing_fields || flow?.missingFields)
          ? flow.missing_fields || flow.missingFields
          : []
      }
    }

    function buildSelectedStewardFlowCarryText(flowId = '', flow = {}, state = {}) {
      const label = flowId === 'travel_application' ? '补办出差申请' : '发起费用报销'
      const fields = flow?.fields && typeof flow.fields === 'object' ? flow.fields : {}
      const fieldLines = [
        fields.time_range ? `时间：${fields.time_range}` : '',
        fields.location ? `地点：${fields.location}` : '',
        fields.expense_type ? `费用类型：${fields.expense_type}` : '',
        fields.reason ? `事由：${fields.reason}` : ''
      ].filter(Boolean)
      const missingFields = Array.isArray(flow?.missing_fields || flow?.missingFields)
        ? flow.missing_fields || flow.missingFields
        : []
      const sourceMessage = String(state?.pending_flow_confirmation?.source_message || '').trim()
      return [
        `小财管家已确认本次按“${label}”继续处理。`,
        sourceMessage ? `用户原始描述：${sourceMessage}` : '',
        fieldLines.length ? `已识别信息：${fieldLines.join('；')}` : '',
        missingFields.length ? `还需要补充：${missingFields.join('、')}` : '',
        flowId === 'travel_application'
          ? '请进入申请流程继续核对出差申请材料；如果仍缺关键字段，请先追问用户。'
          : '请进入报销流程继续核对报销材料、票据和金额；创建草稿或提交前仍需用户确认。'
      ].filter(Boolean).join('\n')
    }

    function buildSelectedStewardFlowSummary(flow = {}) {
      const fields = flow?.fields && typeof flow.fields === 'object' ? flow.fields : {}
      return [
        fields.time_range ? `时间：${fields.time_range}` : '',
        fields.location ? `地点：${fields.location}` : '',
        fields.reason ? `事由：${fields.reason}` : ''
      ].filter(Boolean).join('；')
    }

    function pushStewardRuntimeUserMessage(userText = '') {
      const normalizedText = String(userText || '').trim()
      if (!normalizedText) {
        return false
      }
      messages.value.push(createMessage('user', normalizedText))
      composerDraft.value = ''
      persistSessionState()
      nextTick(() => {
        adjustComposerTextareaHeight()
        scrollToBottom()
      })
      return true
    }

    function pushStewardRuntimeResponse(userText = '', decision = null, options = {}) {
      if (userText && !options.userMessageAlreadyAdded) {
        messages.value.push(createMessage('user', userText))
      }
      const text = String(decision?.question || decision?.response_text || decision?.responseText || decision?.rationale || '').trim()
      if (text) {
        messages.value.push(createMessage('assistant', text, [], {
          assistantName: STEWARD_ASSISTANT_NAME,
          meta: [STEWARD_ASSISTANT_NAME]
        }))
      }
      composerDraft.value = ''
      persistSessionState()
      nextTick(() => {
        adjustComposerTextareaHeight()
        scrollToBottom()
      })
    }

    function buildStewardRuntimeFastPathDecision(rawText = '', runtimeState = {}) {
      const normalizedText = String(rawText || '').trim()
      if (!normalizedText) {
        return null
      }
      if (shouldPlanNewStewardTasksLocally(normalizedText, runtimeState)) {
        return {
          next_action: 'plan_new_tasks'
        }
      }
      if (isStewardRuntimeCancelText(normalizedText)) {
        return {
          next_action: 'cancel_current_action',
          response_text: '已暂停当前等待动作。我不会继续提交或进入下一步；如果您要重新规划，请直接告诉我新的财务事项。'
        }
      }
      const slotContext = findPendingSlotSuggestedActionContextByInput(normalizedText)
      const payload = slotContext?.action?.payload && typeof slotContext.action.payload === 'object'
        ? slotContext.action.payload
        : {}
      if (slotContext) {
        return {
          next_action: 'fill_current_slot',
          target_message_id: String(slotContext.message?.id || '').trim(),
          field_key: String(payload.field_key || payload.fieldKey || '').trim(),
          field_value: String(payload.value || slotContext.action?.label || normalizedText).trim()
        }
      }
      if (isApplicationSubmitConfirmationText(normalizedText) || isStewardRuntimeContinueText(normalizedText)) {
        if (runtimeState?.pending_application?.ready_to_submit) {
          return {
            next_action: 'submit_current_application',
            target_message_id: runtimeState.pending_application.message_id || ''
          }
        }
        if (runtimeState?.pending_steward_action) {
          return {
            next_action: 'continue_next_task',
            target_message_id: runtimeState.pending_steward_action.message_id || '',
            target_task_id: runtimeState.pending_steward_action.target_task_id || ''
          }
        }
      }
      if (String(runtimeState?.waiting_for || '').trim() === 'application_field_completion') {
        if (isApplicationSubmitConfirmationText(normalizedText) || isStewardRuntimeContinueText(normalizedText)) {
          const missingFields = Array.isArray(runtimeState?.pending_application?.missing_fields)
            ? runtimeState.pending_application.missing_fields
            : []
          return {
            next_action: 'ask_user',
            response_text: missingFields.length
              ? `当前申请还不能继续提交，请先补充：${missingFields.join('、')}。您可以直接回复对应选项或填写具体内容。`
              : '当前申请还有信息需要先补充。请先回复系统刚刚追问的内容，我再继续生成核对结果。'
          }
        }
        const fieldCompletionDecision = resolveStewardRuntimeFieldCompletion(normalizedText, runtimeState)
        if (fieldCompletionDecision) {
          return fieldCompletionDecision
        }
      }
      return null
    }

    function shouldUseStewardRuntimeLlmDecision(rawText = '', runtimeState = {}) {
      if (shouldPlanNewStewardTasksLocally(rawText, runtimeState)) {
        return false
      }
      const normalizedText = normalizeStewardRuntimeInputText(rawText)
      if (!normalizedText) {
        return false
      }
      if (
        isApplicationSubmitConfirmationText(normalizedText) ||
        isStewardRuntimeContinueText(normalizedText) ||
        isStewardRuntimeCancelText(normalizedText)
      ) {
        return false
      }
      if (
        findPendingSlotSuggestedActionContextByInput(normalizedText)
      ) {
        return false
      }
      return true
    }

    async function executeStewardRuntimeDecision(decision = null, rawText = '', options = {}) {
      const nextAction = String(decision?.next_action || decision?.nextAction || '').trim()
      const userMessageAlreadyAdded = Boolean(options.userMessageAlreadyAdded)
      if (nextAction === 'submit_current_application') {
        const targetMessageId = String(decision?.target_message_id || decision?.targetMessageId || '').trim()
        const targetMessage = targetMessageId
          ? messages.value.find((message) => String(message.id || '') === targetMessageId)
          : findPendingApplicationSubmitMessage()
        if (!targetMessage?.applicationPreview) {
          return false
        }
        const normalizedPreview = normalizeApplicationPreview(targetMessage.applicationPreview)
        if (!normalizedPreview.readyToSubmit) {
          pushApplicationSubmitBlockedMessage(rawText, targetMessage, { userMessageAlreadyAdded })
          return true
        }
        targetMessage.applicationPreview = normalizedPreview
        applicationSubmitConfirmDialog.value = { open: true, message: targetMessage }
        await confirmApplicationSubmit({ userText: rawText, skipUserMessage: userMessageAlreadyAdded })
        return true
      }
      if (nextAction === 'continue_next_task') {
        const context = findPendingStewardSuggestedActionContext(decision)
        if (!context) {
          return false
        }
        if (rawText && !userMessageAlreadyAdded) {
          messages.value.push(createMessage('user', rawText))
        }
        context.action.confirmedByText = true
        composerDraft.value = ''
        persistSessionState()
        nextTick(() => {
          adjustComposerTextareaHeight()
          scrollToBottom()
        })
        await handleSuggestedAction(context.message, context.action)
        return true
      }
      if (nextAction === 'continue_selected_flow') {
        const selectedState = decision?.steward_state || decision?.stewardState || stewardState.value || {}
        const flowId = String(
          decision?.target_task_id ||
          decision?.targetTaskId ||
          selectedState?.active_flow ||
          selectedState?.activeFlow ||
          ''
        ).trim()
        const flow = resolveStewardStateFlow(selectedState, flowId)
        if (!flowId || !flow) {
          pushStewardRuntimeResponse(rawText, decision, { userMessageAlreadyAdded })
          return true
        }
        const targetSessionType = flowId === 'travel_application'
          ? SESSION_TYPE_APPLICATION
          : SESSION_TYPE_EXPENSE
        await submitComposerInternal({
          rawText: buildSelectedStewardFlowCarryText(flowId, flow, selectedState),
          userText: rawText || (flowId === 'travel_application' ? '补办出差申请' : '发起费用报销'),
          pendingText: targetSessionType === SESSION_TYPE_APPLICATION
            ? '小财管家正在按申请流程整理出差材料...'
            : '小财管家正在按报销流程整理票据和费用材料...',
          files: [],
          skipScopeGuard: true,
          skipApplicationModelReview: targetSessionType === SESSION_TYPE_APPLICATION,
          skipStewardSlotDecision: targetSessionType === SESSION_TYPE_APPLICATION,
          skipStewardPlan: true,
          skipUserMessage: userMessageAlreadyAdded,
          sessionTypeOverride: targetSessionType,
          stewardContinuation: {
            planId: 'steward_selected_flow',
            currentTaskId: flowId,
            currentTask: buildSelectedStewardFlowTaskPayload(flowId, flow),
            remainingTasks: []
          }
        })
        return true
      }
      if (nextAction === 'fill_current_slot') {
        const context = findPendingSlotSuggestedActionContext(decision)
        if (!context) {
          return false
        }
        await handleSuggestedAction(context.message, {
          ...context.action,
          label: String(decision?.field_value || decision?.fieldValue || context.action.label || '').trim(),
          suppressUserEcho: userMessageAlreadyAdded
        })
        return true
      }
      if (nextAction === 'fill_current_application_field') {
        const targetMessageId = String(decision?.target_message_id || decision?.targetMessageId || '').trim()
        const targetMessage = targetMessageId
          ? messages.value.find((message) => String(message.id || '') === targetMessageId)
          : findLatestApplicationPreviewMessage()
        if (!targetMessage?.applicationPreview) {
          return false
        }
        const fieldKey = String(decision?.field_key || decision?.fieldKey || '').trim()
        const fieldLabel = String(decision?.field_label || decision?.fieldLabel || '').trim()
        const fieldValue = String(decision?.field_value || decision?.fieldValue || rawText).trim()
        if (!fieldKey || !fieldValue) {
          return false
        }
        await continueStewardApplicationFieldCompletion({
          targetMessage,
          action: {
            label: fieldValue,
            suppressUserEcho: userMessageAlreadyAdded,
            payload: {
              steward_delegated_field_completion: true,
              field_key: fieldKey,
              field_label: fieldLabel,
              value: fieldValue
            }
          },
          sourcePreview: targetMessage.applicationPreview,
          fieldKey,
          fieldLabel,
          value: fieldValue
        })
        return true
      }
      if (nextAction === 'ask_user' || nextAction === 'cancel_current_action' || nextAction === 'no_op') {
        pushStewardRuntimeResponse(rawText, decision, { userMessageAlreadyAdded })
        return true
      }
      return false
    }

    async function handleStewardRuntimeDecision(options = {}) {
      if (!isStewardSession.value || options.skipStewardPlan) {
        return false
      }
      const rawText = String(options.rawText ?? composerDraft.value ?? '').trim()
      const files = Array.from(options.files ?? attachedFiles.value ?? [])
      if (!rawText || files.length) {
        return false
      }
      const runtimeState = buildStewardRuntimeState()
      if (!hasActiveStewardRuntimeDecisionContext(runtimeState)) {
        return false
      }
      const userMessageAlreadyAdded = options.skipUserMessage
        ? false
        : pushStewardRuntimeUserMessage(rawText)
      try {
        const fastDecision = buildStewardRuntimeFastPathDecision(rawText, runtimeState)
        if (fastDecision) {
          if (String(fastDecision.next_action || fastDecision.nextAction || '').trim() === 'plan_new_tasks') {
            await submitStewardPlan({
              ...options,
              rawText,
              userText: rawText,
              skipUserMessage: userMessageAlreadyAdded || options.skipUserMessage
            })
            return true
          }
          const fastExecuted = await executeStewardRuntimeDecision(fastDecision, rawText, { userMessageAlreadyAdded })
          if (fastExecuted) {
            return true
          }
        }
        if (!shouldUseStewardRuntimeLlmDecision(rawText, runtimeState)) {
          if (userMessageAlreadyAdded) {
            pushStewardRuntimeResponse('', {
              response_text: '我还需要先确认当前等待项。请回复系统刚刚追问的选项或具体补充内容。'
            }, { userMessageAlreadyAdded: true })
            return true
          }
          return false
        }
        const decision = await fetchStewardRuntimeDecision({
          user_message: rawText,
          session_type: SESSION_TYPE_STEWARD,
          runtime_state: runtimeState,
          context_json: {
            entry_source: props.entrySource,
            user_id: resolveCurrentUserId(),
            conversation_id: conversationId.value || '',
            steward_state: stewardState.value || null
          }
        }, {
          timeoutMs: 45000,
          timeoutMessage: '小财管家运行时决策超时，已回到当前上下文兜底处理。'
        })
        const nextStewardState = decision?.steward_state || decision?.stewardState || null
        if (nextStewardState && typeof nextStewardState === 'object') {
          stewardState.value = nextStewardState
        }
        if (String(decision?.next_action || decision?.nextAction || '').trim() === 'plan_new_tasks') {
          await submitStewardPlan({
            ...options,
            rawText,
            userText: rawText,
            skipUserMessage: userMessageAlreadyAdded || options.skipUserMessage
          })
          return true
        }
        const executed = await executeStewardRuntimeDecision(decision, rawText, { userMessageAlreadyAdded })
        if (executed) {
          return true
        }
        if (userMessageAlreadyAdded) {
          await submitStewardPlan({
            ...options,
            rawText,
            userText: rawText,
            skipUserMessage: true
          })
          return true
        }
        return false
      } catch (error) {
        console.warn('Steward runtime decision failed:', error)
        if (userMessageAlreadyAdded) {
          await submitStewardPlan({
            ...options,
            rawText,
            userText: rawText,
            skipUserMessage: true
          })
          return true
        }
        return false
      }
    }



    return {
      handleApplicationSubmitConfirmationText,
      handleStewardRuntimeDecision
    }
}
