import {
  APPLICATION_TRANSPORT_MODE_OPTIONS,
  normalizeApplicationPreview,
  normalizeTransportModeOption
} from '../../utils/expenseApplicationPreview.js'
import {
  mergeComposerPrefill,
  resolveSuggestedActionPrefill
} from '../../utils/assistantSuggestedActionPrefill.js'
import { ASSISTANT_SCOPE_ACTION_SWITCH } from '../../utils/assistantSessionScope.js'
import { buildSuggestedActionKey } from '../../utils/suggestedActionKey.js'
import {
  TRAVEL_PLANNING_ACTION_GENERATE,
  TRAVEL_PLANNING_ACTION_SKIP,
  buildTravelPlanningRecommendation
} from '../../utils/travelApplicationPlanning.js'
import {
  SESSION_TYPE_APPLICATION,
  SESSION_TYPE_BUDGET,
  SESSION_TYPE_EXPENSE,
  canUseBudgetAssistantSession
} from './travelReimbursementConversationModel.js'
import {
  CANCEL_STANDALONE_REIMBURSEMENT_DRAFT_ACTION,
  CONTINUE_REIMBURSEMENT_DRAFT_ACTION,
  CREATE_STANDALONE_REIMBURSEMENT_DRAFT_ACTION,
  SKIP_REQUIRED_APPLICATION_LINK_ACTION,
  SKIP_REIMBURSEMENT_DRAFT_CHECK_ACTION,
  buildReimbursementDraftContinuationText,
  buildReimbursementAssociationSubmitOptions,
  buildStandaloneReimbursementDraftConfirmationActions,
  buildStandaloneReimbursementDraftConfirmationText,
  buildViewReimbursementDraftAction,
  pushReimbursementAssociationPromptMessage
} from './travelReimbursementAssociationGateModel.js'
import { STEWARD_ASSISTANT_NAME } from './useTravelReimbursementStewardRuntime.js'
import {
  buildStewardFieldCompletionContinuation,
  buildStewardFieldCompletionRawText
} from './stewardFieldCompletionModel.js'
import { MAX_ATTACHMENTS, VISIBLE_ATTACHMENT_CHIPS } from './travelReimbursementAttachmentModel.js'

export const APPLICATION_PREVIEW_FIELD_ACTION_SET = 'set_application_preview_field'

export function useTravelReimbursementSuggestedActions({
  applicationPreviewEditor,
  attachedFiles,
  buildExpenseSceneSelectionActions,
  buildExpenseSceneSelectionMessage,
  commitApplicationPreviewEditor,
  composerDraft,
  composerFilesExpanded,
  composerTextareaRef,
  composerUploadIntent = { value: '' },
  createMessage,
  currentUser,
  draftClaimId = { value: '' },
  emit,
  fetchExpenseClaims = async () => ({ items: [] }),
  handleGuidedShortcut,
  handleGuidedSuggestedAction,
  handleSceneSelectionApplicationGate,
  lockSuggestedActionMessage,
  mergeFilesWithLimit,
  messages,
  nextTick,
  openApplicationPreviewEditor,
  persistSessionState,
  resolveApplicationPreviewMissingFields,
  reviewActionBusy,
  router,
  scrollToBottom,
  sessionSwitchBusy,
  startExpenseSceneSelectionAfterIntentConfirmation,
  submitComposer,
  submitComposerInternal,
  submitting,
  switchSessionType,
  toast,
  adjustComposerTextareaHeight
}) {
  async function runShortcut(shortcut) {
    if (shortcut?.action === 'switch_view' && shortcut?.targetSessionType) {
      if (shortcut.targetSessionType === SESSION_TYPE_BUDGET && !canUseBudgetAssistantSession(currentUser.value)) {
        toast('目前暂无权限访问预算编制助手')
        return
      }
      if (shortcut.active) {
        return
      }
      await switchSessionType(shortcut.targetSessionType)
      return
    }
    if (await handleGuidedShortcut(shortcut)) {
      return
    }

    const prompt = String(shortcut?.prompt || '').trim()
    if (!prompt) return
    composerDraft.value = prompt
    submitComposer()
  }

  function isSuggestedActionSelected(message, action) {
    const selectedKey = String(message?.selectedSuggestedActionKey || '').trim()
    return Boolean(selectedKey) && selectedKey === buildSuggestedActionKey(action)
  }

  function buildApplicationPreviewFieldAppliedText(message, fieldLabel = '', value = '') {
    const missingFields = resolveApplicationPreviewMissingFields(message)
    const resolvedFieldLabel = String(fieldLabel || '补充项').trim()
    const resolvedValue = String(value || '').trim()
    if (missingFields.length) {
      return [
        `已更新：**${resolvedFieldLabel}：${resolvedValue}**。`,
        '',
        `我重新检查了一遍，当前还需要补充：**${missingFields.join('、')}**。`,
        '',
        '请继续补齐下方核对表里的待补充项；补齐后我再继续推进申请提交。'
      ].join('\n')
    }
    return [
      `已更新：**${resolvedFieldLabel}：${resolvedValue}**。`,
      '',
      '我已经重新同步下方申请核对表和费用测算。',
      '',
      '请继续核查表格内容；如果信息无误，点击确认进入审批环节。'
    ].join('\n')
  }

  function isStewardApplicationPreviewFieldCompletion(targetMessage, payload = {}) {
    return Boolean(
      payload.steward_delegated_field_completion ||
      String(targetMessage?.assistantName || '').trim() === STEWARD_ASSISTANT_NAME ||
      targetMessage?.stewardPlan
    )
  }

  async function continueStewardApplicationFieldCompletion({
    targetMessage,
    action,
    sourcePreview,
    fieldKey,
    fieldLabel,
    value
  }) {
    if (!lockSuggestedActionMessage(targetMessage, action)) {
      return true
    }

    const continuation = buildStewardFieldCompletionContinuation(
      targetMessage?.stewardContinuation || null,
      fieldKey,
      value
    )
    const userText = `选择${fieldLabel || '补充项'}：${value}`
    const carryText = buildStewardFieldCompletionRawText({
      preview: sourcePreview,
      fieldKey,
      fieldLabel,
      value,
      continuation
    })

    if (!action?.suppressUserEcho) {
      messages.value.push(createMessage('user', userText))
    }
    persistSessionState()
    nextTick(scrollToBottom)

    await submitComposerInternal({
      rawText: carryText,
      userText,
      pendingText: '小财管家正在根据补齐信息查询票据并测算费用...',
      files: [],
      skipScopeGuard: true,
      skipApplicationModelReview: true,
      skipStewardPlan: true,
      skipUserMessage: true,
      sessionTypeOverride: SESSION_TYPE_APPLICATION,
      stewardContinuation: continuation
    })
    return true
  }

  async function applyApplicationPreviewFieldAction(message, action) {
    const payload = action?.payload && typeof action.payload === 'object' ? action.payload : {}
    const fieldKey = String(payload.field_key || payload.fieldKey || '').trim()
    const fieldLabel = String(payload.field_label || payload.fieldLabel || action?.label || '').trim()
    let value = String(payload.value || action?.label || '').trim()
    const targetMessage = messages.value.find((item) => String(item.id || '') === String(message?.id || '')) || message
    const sourcePreview = targetMessage?.applicationPreview ||
      payload.applicationPreview ||
      payload.application_preview ||
      payload.preview ||
      null
    if (!sourcePreview || !fieldKey || !value) {
      return false
    }
    if (fieldKey === 'transportMode') {
      value = normalizeTransportModeOption(value, '')
    }
    if (fieldKey === 'transportMode' && !APPLICATION_TRANSPORT_MODE_OPTIONS.includes(value)) {
      toast('请选择有效的出行方式。')
      return true
    }
    if (isStewardApplicationPreviewFieldCompletion(targetMessage, payload)) {
      return continueStewardApplicationFieldCompletion({
        targetMessage,
        action,
        sourcePreview,
        fieldKey,
        fieldLabel,
        value
      })
    }
    if (!lockSuggestedActionMessage(targetMessage, action)) {
      return true
    }

    targetMessage.applicationPreview = normalizeApplicationPreview(sourcePreview)
    messages.value.push(createMessage('user', `选择${fieldLabel || '补充项'}：${value}`))
    openApplicationPreviewEditor(targetMessage, fieldKey, targetMessage.applicationPreview?.fields?.[fieldKey] || '')
    applicationPreviewEditor.value = {
      ...applicationPreviewEditor.value,
      draftValue: value
    }
    await commitApplicationPreviewEditor(targetMessage)
    if (String(targetMessage.assistantName || '').trim() === STEWARD_ASSISTANT_NAME || targetMessage.stewardPlan) {
      targetMessage.assistantName = STEWARD_ASSISTANT_NAME
      targetMessage.text = buildApplicationPreviewFieldAppliedText(targetMessage, fieldLabel, value)
      const nextMeta = Array.isArray(targetMessage.meta) ? targetMessage.meta : []
      targetMessage.meta = Array.from(new Set([
        STEWARD_ASSISTANT_NAME,
        resolveApplicationPreviewMissingFields(targetMessage).length ? '等待补充' : '等待用户确认',
        ...nextMeta.filter((item) => String(item || '').trim() && item !== STEWARD_ASSISTANT_NAME)
      ])).slice(0, 4)
    }
    persistSessionState()
    nextTick(scrollToBottom)
    return true
  }

  function pushExpenseSceneSelectionPrompt(originalMessage, userEcho = '我要报销') {
    const sourceText = String(originalMessage || '').trim()
    if (!sourceText) {
      return
    }

    startExpenseSceneSelectionAfterIntentConfirmation(sourceText)
    messages.value.push(createMessage('user', String(userEcho || '我要报销').trim() || '我要报销'))
    messages.value.push(createMessage('assistant', buildExpenseSceneSelectionMessage(sourceText), [], {
      meta: ['等待选择场景'],
      suggestedActions: buildExpenseSceneSelectionActions(sourceText)
    }))
    nextTick(scrollToBottom)
    persistSessionState()
  }

  function normalizeDraftActionPayload(payload = {}) {
    return {
      id: String(payload.id || payload.claim_id || payload.claimId || '').trim(),
      claim_no: String(payload.claim_no || payload.claimNo || '').trim(),
      original_message: String(payload.original_message || payload.originalMessage || '我要报销').trim() || '我要报销'
    }
  }

  function pushDraftContinuationPrompt(actionPayload = {}) {
    const draft = normalizeDraftActionPayload(actionPayload)
    const claimNo = draft.claim_no || '当前草稿'
    if (!draft.id) {
      toast('当前没有可继续关联的草稿单据。')
      return
    }

    draftClaimId.value = draft.id
    composerUploadIntent.value = 'continue_existing'
    messages.value.push(createMessage('user', `继续关联草稿 ${claimNo}`))
    messages.value.push(createMessage('assistant', buildReimbursementDraftContinuationText(draft), [], {
      meta: ['等待上传附件或说明'],
      suggestedActions: [buildViewReimbursementDraftAction(draft, draft.original_message)]
    }))
    nextTick(scrollToBottom)
    persistSessionState()
  }

  function pushStandaloneDraftCreationPrompt(originalMessage = '我要报销', selectedLabel = '独立新建报销单') {
    const sourceText = String(originalMessage || '我要报销').trim() || '我要报销'
    const userText = String(selectedLabel || '独立新建报销单').trim() || '独立新建报销单'
    messages.value.push(createMessage('user', userText))
    messages.value.push(createMessage('assistant', buildStandaloneReimbursementDraftConfirmationText(), [], {
      meta: ['等待确认新建草稿'],
      suggestedActions: buildStandaloneReimbursementDraftConfirmationActions(sourceText)
    }))
    nextTick(scrollToBottom)
    persistSessionState()
  }

  function pushStandaloneDraftCreationCancelledPrompt() {
    messages.value.push(createMessage('assistant', '好的，本次先不新建报销草稿。您可以继续查看已有草稿，或补充新的报销说明。', [], {
      meta: ['已取消新建']
    }))
    nextTick(scrollToBottom)
    persistSessionState()
  }

  async function pushExpenseAssociationGatePrompt(originalMessage, options = {}) {
    const sourceText = String(originalMessage || '我要报销').trim() || '我要报销'
    startExpenseSceneSelectionAfterIntentConfirmation(sourceText)
    messages.value.push(createMessage('user', String(options.userText || '我要报销').trim() || '我要报销'))
    await pushReimbursementAssociationPromptMessage({
      rawText: sourceText,
      createMessage,
      messages,
      nextTick,
      scrollToBottom,
      persistSessionState,
      fetchExpenseClaims,
      currentUser,
      skipDraftCheck: Boolean(options.skipDraftCheck)
    })
  }

  function applySuggestedActionPrefill(action) {
    const prefillText = resolveSuggestedActionPrefill(action)
    if (!prefillText) {
      return false
    }

    composerDraft.value = mergeComposerPrefill(composerDraft.value, prefillText)
    nextTick(() => {
      adjustComposerTextareaHeight()
      composerTextareaRef.value?.focus()
    })
    persistSessionState()
    return true
  }

  async function handleSuggestedAction(message, action) {
    const actionType = String(action?.action_type || '').trim()
    if (!actionType || submitting.value || reviewActionBusy.value || sessionSwitchBusy.value) return
    if (message?.suggestedActionsLocked) return
    if (applySuggestedActionPrefill(action)) return
    if (await handleGuidedSuggestedAction(message, action)) return
    if (await handleSceneSelectionApplicationGate(message, action)) return

    if (actionType === CONTINUE_REIMBURSEMENT_DRAFT_ACTION) {
      if (!lockSuggestedActionMessage(message, action)) return
      pushDraftContinuationPrompt(action?.payload || {})
      return
    }

    if (actionType === CREATE_STANDALONE_REIMBURSEMENT_DRAFT_ACTION) {
      const originalMessage = String(action?.payload?.original_message || message?.text || '我要报销').trim() || '我要报销'
      if (!lockSuggestedActionMessage(message, action)) return
      pushStandaloneDraftCreationPrompt(originalMessage, action?.label || '独立新建报销单')
      return
    }

    if (actionType === CANCEL_STANDALONE_REIMBURSEMENT_DRAFT_ACTION) {
      if (!lockSuggestedActionMessage(message, action)) return
      pushStandaloneDraftCreationCancelledPrompt()
      return
    }

    if (actionType === SKIP_REIMBURSEMENT_DRAFT_CHECK_ACTION) {
      const originalMessage = String(action?.payload?.original_message || message?.text || '我要报销').trim() || '我要报销'
      if (!lockSuggestedActionMessage(message, action)) return
      await pushExpenseAssociationGatePrompt(originalMessage, {
        skipDraftCheck: true,
        userText: action?.label || '不用草稿，关联申请单新建报销单'
      })
      return
    }

    if (actionType === SKIP_REQUIRED_APPLICATION_LINK_ACTION) {
      const originalMessage = String(action?.payload?.original_message || message?.text || '我要报销').trim() || '我要报销'
      if (!lockSuggestedActionMessage(message, action)) return
      pushExpenseSceneSelectionPrompt(originalMessage, action?.label || '不关联，单独新建报销单')
      return
    }

    if (actionType === 'select_required_application') {
      const actionPayload = action?.payload && typeof action.payload === 'object' ? action.payload : {}
      const applicationNo = String(actionPayload.application_claim_no || actionPayload.claim_no || '').trim()
      const originalMessage = String(actionPayload.original_message || message?.text || '我要报销').trim() || '我要报销'
      if (!lockSuggestedActionMessage(message, action)) return
      messages.value.push(createMessage('user', `关联申请单 ${applicationNo || ''}`.trim() || '关联申请单'))
      nextTick(scrollToBottom)
      persistSessionState()
      await submitComposer(buildReimbursementAssociationSubmitOptions(actionPayload, originalMessage))
      return
    }

    if (actionType === APPLICATION_PREVIEW_FIELD_ACTION_SET) {
      await applyApplicationPreviewFieldAction(message, action)
      return
    }

    if (actionType === 'open_application_detail') {
      const actionPayload = action?.payload && typeof action.payload === 'object' ? action.payload : {}
      const claimId = String(actionPayload.claim_id || actionPayload.claimId || '').trim()
      if (!claimId) {
        toast('当前没有可查看的申请单据。')
        return
      }
      if (!lockSuggestedActionMessage(message, action)) return
      await router.push({
        name: 'app-document-detail',
        params: { requestId: claimId }
      })
      emit('close')
      return
    }

    if (actionType === 'open_receipt_folder') {
      if (!lockSuggestedActionMessage(message, action)) return
      await router.push({ name: 'app-receiptFolder' })
      emit('close')
      return
    }

    if (actionType === 'continue_upload_with_unlinked_receipts') {
      if (!lockSuggestedActionMessage(message, action)) return
      const actionPayload = action?.payload && typeof action.payload === 'object' ? action.payload : {}
      await submitComposer({
        rawText: String(actionPayload.raw_text || composerDraft.value || '').trim(),
        files: Array.from(attachedFiles.value || []),
        skipReceiptFolderUnlinkedPrompt: true
      })
      return
    }

    if (actionType === TRAVEL_PLANNING_ACTION_GENERATE) {
      if (!lockSuggestedActionMessage(message, action)) return
      const sourcePreview = action?.payload?.applicationPreview || action?.payload?.preview || null
      const sourceDraftPayload = action?.payload?.draftPayload || action?.payload?.draft_payload || null
      const recommendation = buildTravelPlanningRecommendation(sourcePreview, sourceDraftPayload)
      if (recommendation) {
        messages.value.push(createMessage('user', '生成行程规划'))
        messages.value.push(createMessage('assistant', recommendation, [], {
          meta: ['行程规划建议']
        }))
        nextTick(scrollToBottom)
        persistSessionState()
      }
      return
    }

    if (actionType === TRAVEL_PLANNING_ACTION_SKIP) {
      if (!lockSuggestedActionMessage(message, action)) return
      messages.value.push(createMessage('assistant', '好的，本次先保留申请结果。后续需要规划交通或酒店时，可以继续在这里告诉我。', [], {
        meta: ['暂不规划']
      }))
      nextTick(scrollToBottom)
      persistSessionState()
      return
    }

    if (actionType === ASSISTANT_SCOPE_ACTION_SWITCH) {
      const actionPayload = action?.payload && typeof action.payload === 'object' ? action.payload : {}
      const targetSessionType = String(actionPayload.session_type || '').trim()
      if (!targetSessionType) return
      if (targetSessionType === SESSION_TYPE_BUDGET && !canUseBudgetAssistantSession(currentUser.value)) {
        toast('目前暂无权限访问预算编制助手')
        return
      }
      const carryText = String(actionPayload.carry_text || '').trim()
      const carryFiles = actionPayload.carry_files ? Array.from(attachedFiles.value || []) : []
      if (!lockSuggestedActionMessage(message, action)) return
      if (targetSessionType === SESSION_TYPE_EXPENSE && carryText === '我要报销') {
        await pushExpenseAssociationGatePrompt(carryText)
        return
      }
      if (String(actionPayload.steward_plan_id || '').trim()) {
        const confirmedByText = Boolean(action.confirmedByText)
        delete action.confirmedByText
        await submitComposerInternal({
          rawText: carryText,
          userText: action.label || '确定',
          pendingText: targetSessionType === SESSION_TYPE_APPLICATION
            ? '小财管家正在调用申请助手生成申请单核对结果...'
            : '小财管家正在调用报销助手整理报销核对结果...',
          files: carryFiles,
          skipScopeGuard: true,
          skipApplicationModelReview: targetSessionType === SESSION_TYPE_APPLICATION,
          skipStewardSlotDecision: targetSessionType === SESSION_TYPE_APPLICATION,
          skipStewardPlan: true,
          skipUserMessage: confirmedByText,
          sessionTypeOverride: targetSessionType,
          stewardContinuation: {
            planId: String(actionPayload.steward_plan_id || '').trim(),
            currentTaskId: String(actionPayload.steward_next_task_id || '').trim(),
            currentTask: actionPayload.steward_current_task || null,
            remainingTasks: Array.isArray(actionPayload.steward_remaining_tasks)
              ? actionPayload.steward_remaining_tasks
              : []
          }
        })
        return
      }
      await switchSessionType(targetSessionType)
      if (carryText) {
        composerDraft.value = carryText
      }
      if (carryFiles.length) {
        const fileMergeResult = mergeFilesWithLimit([], carryFiles, MAX_ATTACHMENTS)
        attachedFiles.value = fileMergeResult.files
        composerFilesExpanded.value = fileMergeResult.files.length > VISIBLE_ATTACHMENT_CHIPS
      }
      nextTick(() => {
        adjustComposerTextareaHeight()
        scrollToBottom()
      })
      persistSessionState()
      if (actionPayload.auto_submit && carryText) {
        await submitComposer({
          rawText: carryText,
          userText: action.label || '确认继续处理',
          pendingText: '正在按确认内容继续处理...',
          files: carryFiles,
          skipScopeGuard: true
        })
      }
      return
    }

    if (actionType === 'confirm_expense_intent') {
      const originalMessage = String(action?.payload?.original_message || message?.text || '').trim()
      if (!originalMessage) return
      if (!lockSuggestedActionMessage(message, action)) return
      await pushExpenseAssociationGatePrompt(originalMessage)
      return
    }

    if (actionType !== 'select_expense_type') {
      const fallbackText = String(action?.description || action?.label || '').trim()
      if (!fallbackText) return
      if (!lockSuggestedActionMessage(message, action)) return
      await submitComposer({
        rawText: fallbackText,
        userText: fallbackText,
        pendingText: '正在继续处理...'
      })
      return
    }

    const actionPayload = action?.payload && typeof action.payload === 'object' ? action.payload : {}
    const expenseType = String(actionPayload.expense_type || '').trim()
    const expenseTypeLabel = String(actionPayload.expense_type_label || action?.label || '').trim()
    const originalMessage = String(actionPayload.original_message || message?.text || '').trim()
    if (!expenseTypeLabel || !originalMessage) return

    if (!lockSuggestedActionMessage(message, action)) return
    await submitComposer({
      rawText: `${originalMessage}\n用户选择报销场景：${expenseTypeLabel}`,
      userText: `选择${expenseTypeLabel}`,
      pendingText: `已选择${expenseTypeLabel}，正在按该场景识别...`,
      systemGenerated: true,
      extraContext: {
        draft_claim_id: '',
        user_input_text: originalMessage,
        expense_scene_selection: {
          expense_type: expenseType,
          expense_type_label: expenseTypeLabel,
          original_message: originalMessage
        },
        review_form_values: {
          expense_type: expenseTypeLabel
        }
      }
    })
  }

  return {
    continueStewardApplicationFieldCompletion,
    handleSuggestedAction,
    isSuggestedActionSelected,
    runShortcut
  }
}
