import {
  buildOperationFeedbackPayload,
  normalizeOperationFeedbackContext
} from '../../composables/useOperationFeedback.js'
import { createOperationFeedback } from '../../services/operationFeedback.js'
import {
  buildApplicationPreviewFooterMessage,
  normalizeApplicationPreview
} from '../../utils/expenseApplicationPreview.js'
import { STEWARD_ASSISTANT_NAME } from './useTravelReimbursementStewardRuntime.js'
import {
  buildReviewNextStepRichCopy,
  buildReviewRiskLevelCounts,
  resolveReviewNextStepAction
} from './travelReimbursementReviewModel.js'
import { buildReviewRiskConversationText } from './travelReimbursementReviewPanelModel.js'

export function useTravelReimbursementMessageActions({
  activeSessionType,
  buildMessageActionRows,
  conversationId,
  createMessage,
  currentInsight,
  currentUser,
  draftClaimId,
  emit,
  getHandleReviewActionInternal,
  latestReviewMessage,
  linkedRequest,
  messages,
  nextStepConfirmDialog,
  nextTick,
  persistSessionState,
  props,
  resolveActiveClaimId,
  resolveCurrentUserId,
  reviewActionBusy,
  router,
  scrollToBottom,
  submitComposer,
  submitting,
  toast
}) {
  function queryDraftByClaimNo(claimNo) {
    const normalized = String(claimNo || '').trim()
    if (!normalized || submitting.value || reviewActionBusy.value) return
    submitComposer({
      rawText: `查看报销草稿 ${normalized} 的当前信息`,
      userText: `查看草稿 ${normalized}`,
      systemGenerated: true
    })
  }

  function appendReviewRiskBriefToConversation(item) {
    if (!item) return
    messages.value.push(createMessage('assistant', buildReviewRiskConversationText(item, resolveReviewRiskDetailTarget()), [], {
      meta: [item.sourceLabel || item.levelLabel || '风险提示'],
      metaTone: item.level || 'low'
    }))
    nextTick(scrollToBottom)
  }

  function appendExpenseQueryRiskToConversation(record, risk) {
    if (!record || !risk) return
    const claimId = String(record.claimId || '').trim()
    const claimNo = String(record.claimNo || '该单据').trim()
    const route = claimId
      ? router.resolve({
          name: 'app-document-detail',
          params: { requestId: claimId }
        })
      : null
    messages.value.push(createMessage(
      'assistant',
      buildReviewRiskConversationText(
        {
          title: `${claimNo} ${risk.levelLabel || '风险提示'}：${risk.title || '风险提示'}`,
          summary: risk.summary,
          detail: risk.detail,
          suggestion: '请进入单据详情核对费用明细、票据附件和附加说明；如属于合理例外，请补充业务说明后再继续流程。',
          sourceLabel: risk.levelLabel,
          level: risk.level
        },
        route?.href
          ? {
              href: route.href,
              label: `进入 ${claimNo} 详情重新填写`
            }
          : {}
      ),
      [],
      {
        meta: [`${claimNo} 风险详情`],
        metaTone: risk.level || 'medium'
      }
    ))
    nextTick(scrollToBottom)
  }

  function resolveReviewDetailTarget(message = null) {
    const latestDraftMessage = [...messages.value].reverse().find((item) => item?.draftPayload)
    const candidates = [
      message?.draftPayload,
      currentInsight.value.agent?.draftPayload,
      latestReviewMessage.value?.draftPayload,
      latestDraftMessage?.draftPayload,
      linkedRequest.value
    ].filter(Boolean)
    const claimTarget = candidates.find((item) => String(item?.claim_id || item?.claimId || item?.id || '').trim())
    const claimId = String(claimTarget?.claim_id || claimTarget?.claimId || claimTarget?.id || draftClaimId.value || resolveActiveClaimId() || '').trim()
    if (!claimId) {
      return {}
    }
    const claimNoTarget = candidates.find((item) => String(item?.claim_no || item?.claimNo || item?.documentNo || '').trim())
    const claimNo = String(claimNoTarget?.claim_no || claimNoTarget?.claimNo || claimNoTarget?.documentNo || '').trim()
    const route = router.resolve({
      name: 'app-document-detail',
      params: { requestId: claimId }
    })
    return {
      href: route.href,
      label: claimNo ? `进入 ${claimNo} 详情重新填写` : '进入该单据详情重新填写'
    }
  }

  function resolveReviewRiskDetailTarget() {
    return resolveReviewDetailTarget()
  }

  function buildReviewNextStepRichCopyForMessage(message) {
    const target = resolveReviewDetailTarget(message)
    return buildReviewNextStepRichCopy(message?.reviewPayload, {
      detailHref: target.href || ''
    })
  }

  function buildMessageBubbleClass(message) {
    if (message?.role === 'assistant' && message?.budgetReport) {
      return 'message-bubble-budget-report'
    }
    if (message?.role === 'assistant' && message?.applicationPreview) {
      return 'message-bubble-application-preview'
    }
    if (message?.role !== 'assistant' || !resolveReviewNextStepAction(message?.reviewPayload)) {
      return ''
    }
    const counts = buildReviewRiskLevelCounts(message.reviewPayload)
    if (counts.high > 0) {
      return 'message-bubble-review-risk-high'
    }
    if (counts.medium > 0) {
      return 'message-bubble-review-risk-medium'
    }
    if (counts.low > 0) {
      return 'message-bubble-review-risk-low'
    }
    return ''
  }

  function openReviewNextStepConfirm(message) {
    const action = resolveReviewNextStepAction(message?.reviewPayload)
    if (!action) {
      return
    }
    nextStepConfirmDialog.value = {
      open: true,
      message,
      action
    }
  }

  function closeReviewNextStepConfirm() {
    if (reviewActionBusy.value) {
      return
    }
    nextStepConfirmDialog.value = {
      open: false,
      message: null,
      action: null
    }
  }

  async function confirmReviewNextStepSubmit() {
    const message = nextStepConfirmDialog.value.message
    const action = nextStepConfirmDialog.value.action
    const handleReviewActionInternal = getHandleReviewActionInternal()
    if (!message || !action || reviewActionBusy.value || !handleReviewActionInternal) {
      return
    }
    try {
      await handleReviewActionInternal(message, action)
    } finally {
      nextStepConfirmDialog.value = {
        open: false,
        message: null,
        action: null
      }
    }
  }

  function buildApplicationPreviewFooterText(message) {
    if (!message?.applicationPreview) {
      return ''
    }
    return buildApplicationPreviewFooterMessage(message.applicationPreview)
  }

  function isApplicationDraftPayload(draftPayload) {
    return String(draftPayload?.draft_type || '').trim() === 'expense_application'
  }

  function resolveDraftPayloadBodyField(draftPayload, label) {
    const body = String(draftPayload?.body || '')
    const pattern = new RegExp(`^${label}：(.+)$`, 'm')
    return String(body.match(pattern)?.[1] || '').trim()
  }

  function resolveApplicationDraftStatusLabel(draftPayload) {
    const status = String(draftPayload?.status || '').trim()
    if (status === 'submitted') return '审批中'
    return status || '已生成'
  }

  function buildApplicationDraftSummaryItems(draftPayload) {
    if (!isApplicationDraftPayload(draftPayload)) {
      return []
    }
    return [
      { label: '单号', value: String(draftPayload?.claim_no || '').trim() || '待生成' },
      { label: '类型', value: String(draftPayload?.title || '').trim() || '费用申请' },
      { label: '节点', value: String(draftPayload?.approval_stage || '').trim() || '直属领导审批' },
      { label: '时间', value: resolveDraftPayloadBodyField(draftPayload, '发生时间') },
      { label: '费用', value: resolveDraftPayloadBodyField(draftPayload, '用户预估费用') }
    ].filter((item) => String(item.value || '').trim() && item.value !== '待补充')
  }

  function shouldShowDraftSavedCard(message) {
    const draftPayload = message?.draftPayload || null
    return Boolean(
      draftPayload
        && (
          String(draftPayload.claim_id || draftPayload.claimId || '').trim()
          || String(draftPayload.claim_no || draftPayload.claimNo || '').trim()
          || String(draftPayload.title || '').trim()
          || String(draftPayload.body || '').trim()
        )
    )
  }

  function canOpenDraftDetail(message) {
    const draftPayload = message?.draftPayload || {}
    return Boolean(String(draftPayload.claim_id || draftPayload.claimId || '').trim())
  }

  function resolveReimbursementDraftClaimNo(draftPayload) {
    return String(
      draftPayload?.claim_no
      || draftPayload?.claimNo
      || draftPayload?.claim_id
      || draftPayload?.claimId
      || ''
    ).trim() || '保存后生成'
  }

  function updateMessageOperationFeedback(message, patch = {}) {
    if (!message?.id) {
      return
    }
    messages.value = messages.value.map((item) => (
      item.id === message.id
        ? {
            ...item,
            operationFeedback: {
              ...(item.operationFeedback || {}),
              ...patch
            }
          }
        : item
    ))
  }

  function shouldShowAssistantMessageActions(message) {
    return Boolean(
      message?.role === 'assistant'
        && (
          String(message.text || '').trim()
          || message.applicationPreview
          || message.reviewPayload
          || message.queryPayload
          || message.draftPayload
          || message.budgetReport
        )
        && !(message.stewardPlan?.streamStatus === 'streaming' && !String(message.text || '').trim())
    )
  }

  function buildMessageActionText(message) {
    const parts = []
    const text = String(message?.text || '').trim()
    if (text) {
      parts.push(text)
    }
    const actionRows = buildMessageActionRows(message)
    if (actionRows.length) {
      parts.push(actionRows.join('\n'))
    }
    if (message?.draftPayload) {
      const claimNo = resolveReimbursementDraftClaimNo(message.draftPayload)
      if (claimNo) {
        parts.push(`单据：${claimNo}`)
      }
    }
    return parts.join('\n\n').trim()
  }

  async function copyAssistantMessage(message) {
    const text = buildMessageActionText(message)
    if (!text) {
      toast('当前消息没有可复制的内容。')
      return
    }
    try {
      if (globalThis.navigator?.clipboard?.writeText) {
        await globalThis.navigator.clipboard.writeText(text)
      } else {
        const textarea = globalThis.document.createElement('textarea')
        textarea.value = text
        textarea.setAttribute('readonly', 'readonly')
        textarea.style.position = 'fixed'
        textarea.style.opacity = '0'
        globalThis.document.body.appendChild(textarea)
        textarea.select()
        globalThis.document.execCommand('copy')
        globalThis.document.body.removeChild(textarea)
      }
      toast('已复制。')
    } catch (error) {
      console.warn('Failed to copy assistant message:', error)
      toast('复制失败，请稍后重试。')
    }
  }

  function speakAssistantMessage(message) {
    const text = buildMessageActionText(message)
    if (!text) {
      toast('当前消息没有可播报的内容。')
      return
    }
    const speech = globalThis.speechSynthesis
    if (!speech || typeof globalThis.SpeechSynthesisUtterance === 'undefined') {
      toast('当前浏览器不支持语音播报。')
      return
    }
    speech.cancel()
    const utterance = new globalThis.SpeechSynthesisUtterance(text.slice(0, 1200))
    utterance.lang = 'zh-CN'
    utterance.rate = 1
    speech.speak(utterance)
  }

  function buildMessageOperationFeedbackContext(message) {
    const existingContext = message?.operationFeedback?.context || null
    if (existingContext) {
      return existingContext
    }
    const messageId = String(message?.id || '').trim()
    const assistantName = String(message?.assistantName || '').trim()
    return normalizeOperationFeedbackContext({
      run_id: messageId.slice(0, 50) || null,
      conversation_id: String(conversationId.value || '').trim(),
      user_id: resolveCurrentUserId(),
      selected_agent: assistantName || (message?.stewardPlan ? STEWARD_ASSISTANT_NAME : 'user_agent'),
      source: 'assistant_message_action',
      session_type: activeSessionType.value,
      operation_type: message?.stewardPlan ? 'steward_message' : 'assistant_message',
      operation_status: 'succeeded',
      status: 'succeeded',
      entry_source: props.entrySource,
      result_summary: buildMessageActionText(message).slice(0, 500)
    }, currentUser.value || {})
  }

  async function submitOperationFeedbackForMessage(message, feedback = {}) {
    const rating = Number(feedback.rating || 0)
    if (!Number.isInteger(rating) || rating < 1 || rating > 5) {
      updateMessageOperationFeedback(message, { error: '请选择 1 到 5 星评分。' })
      return
    }

    const context = buildMessageOperationFeedbackContext(message)
    if (!context) {
      return
    }

    updateMessageOperationFeedback(message, {
      submitting: true,
      rating,
      reason: String(feedback.reason || '').trim(),
      context,
      error: ''
    })
    try {
      await createOperationFeedback(
        buildOperationFeedbackPayload(context, feedback, currentUser.value || {})
      )
      updateMessageOperationFeedback(message, {
        submitting: false,
        submitted: true,
        dismissed: false,
        rating,
        reason: String(feedback.reason || '').trim(),
        error: ''
      })
      persistSessionState()
    } catch (error) {
      updateMessageOperationFeedback(message, {
        submitting: false,
        error: error?.message || '评价提交失败，请稍后重试。'
      })
    }
  }

  function isMessageFeedbackSelected(message, rating) {
    return Boolean(
      message?.operationFeedback?.submitted
        && Number(message.operationFeedback.rating || 0) === Number(rating || 0)
    )
  }

  async function openApplicationDraftDetail(message) {
    const draftPayload = message?.draftPayload || {}
    const claimId = String(draftPayload.claim_id || draftPayload.claimId || '').trim()
    if (!claimId) {
      toast('暂未获取到单据 ID，稍后可在单据中心查看。')
      return
    }
    await router.push({
      name: 'app-document-detail',
      params: { requestId: claimId }
    })
    emit('close')
  }

  function resolveApplicationPreviewMissingFields(message) {
    if (!message?.applicationPreview) {
      return []
    }
    const normalizedPreview = normalizeApplicationPreview(message.applicationPreview)
    return Array.isArray(normalizedPreview.missingFields) ? normalizedPreview.missingFields : []
  }

  return {
    appendExpenseQueryRiskToConversation,
    appendReviewRiskBriefToConversation,
    buildApplicationDraftSummaryItems,
    buildApplicationPreviewFooterText,
    buildMessageBubbleClass,
    buildReviewNextStepRichCopyForMessage,
    canOpenDraftDetail,
    closeReviewNextStepConfirm,
    confirmReviewNextStepSubmit,
    copyAssistantMessage,
    isApplicationDraftPayload,
    isMessageFeedbackSelected,
    openApplicationDraftDetail,
    openReviewNextStepConfirm,
    queryDraftByClaimNo,
    resolveApplicationDraftStatusLabel,
    resolveApplicationPreviewMissingFields,
    resolveReimbursementDraftClaimNo,
    shouldShowAssistantMessageActions,
    shouldShowDraftSavedCard,
    speakAssistantMessage,
    submitOperationFeedbackForMessage
  }
}
