import { ATTACHMENT_ASSOCIATION_CONFIRM_HREF } from './travelReimbursementAttachmentModel.js'

export function createSubmitAttachmentAssociationFlow({
  activeReviewPayload,
  buildReviewFormContextFromPayload,
  createMessage,
  draftClaimId,
  emitDraftSaved,
  fetchReceiptFolderItems,
  isKnowledgeSession,
  messages,
  nextTick,
  persistSessionState,
  resetFlowRun,
  reviewInlineForm,
  scrollToBottom,
  sessionSwitchBusy,
  submitComposer,
  submitting,
  toast
}) {
    const pendingAttachmentAssociations = new Map()

    function createPendingAttachmentAssociationId() {
      return `attachment-association-${Date.now()}-${Math.random().toString(16).slice(2)}`
    }

    function emitSavedDraftRefresh(draftPayload) {
      if (!emitDraftSaved || isKnowledgeSession.value || !draftPayload?.claim_no) {
        return
      }
      const draftType = String(draftPayload.draft_type || '').trim()
      emitDraftSaved({
        claimId: String(draftPayload.claim_id || draftPayload.claimId || '').trim(),
        claimNo: String(draftPayload.claim_no || draftPayload.claimNo || '').trim(),
        status: String(draftPayload.status || '').trim(),
        approvalStage: String(draftPayload.approval_stage || draftPayload.approvalStage || '').trim(),
        documentType: draftType === 'expense_application' ? 'application' : 'reimbursement'
      })
    }

    function normalizeRecognizedAttachmentData(data) {
      if (!data || typeof data !== 'object') {
        return null
      }
      const documents = Array.isArray(data.ocrDocuments) ? data.ocrDocuments : []
      if (!documents.length) {
        return null
      }
      return {
        ocrPayload: data.ocrPayload || null,
        ocrSummary: String(data.ocrSummary || '').trim(),
        ocrDocuments: documents,
        ocrFilePreviews: Array.isArray(data.ocrFilePreviews) ? data.ocrFilePreviews : []
      }
    }

    function hasReceiptFolderSourceFile(files) {
      return files.some((file) => String(file?.receiptId || '').trim())
    }

    async function promptUnlinkedReceiptFolderIfNeeded({
      detailScopedClaimId,
      files,
      fileNames,
      options,
      rawText,
      resolvedUploadDisposition,
      reviewAction,
      systemGenerated,
      userText
    }) {
      if (
        isKnowledgeSession.value ||
        systemGenerated ||
        !files.length ||
        detailScopedClaimId ||
        resolvedUploadDisposition ||
        options.skipReceiptFolderUnlinkedPrompt ||
        options.skipDraftAssociationPrompt ||
        reviewAction ||
        hasReceiptFolderSourceFile(files)
      ) {
        return false
      }

      let unlinkedReceipts = []
      try {
        unlinkedReceipts = await fetchReceiptFolderItems('unlinked')
      } catch (error) {
        console.warn('Failed to load unlinked receipt folder items before attachment upload:', error)
        return false
      }
      const count = Array.isArray(unlinkedReceipts) ? unlinkedReceipts.length : 0
      if (!count) {
        return false
      }

      resetFlowRun()
      if (!options.skipUserMessage) {
        messages.value.push(createMessage('user', userText, fileNames))
      }
      messages.value.push(createMessage(
        'assistant',
        `票据夹中还有 ${count} 份未关联票据。建议先处理这些票据再上传新附件，避免重复保存或遗漏关联。`,
        [],
        {
          meta: ['票据夹待关联'],
          suggestedActions: [
            {
              action_type: 'open_receipt_folder',
              label: '去票据夹关联',
              icon: 'mdi mdi-folder-open-outline',
              payload: { target_view: 'receiptFolder' }
            },
            {
              action_type: 'continue_upload_with_unlinked_receipts',
              label: '继续上传新附件',
              icon: 'mdi mdi-upload-outline',
              payload: { raw_text: rawText }
            }
          ]
        }
      ))
      nextTick(scrollToBottom)
      persistSessionState()
      return true
    }

    function buildConfirmedAssociationText(message) {
      return String(message?.text || '')
        .replace(`[确认](${ATTACHMENT_ASSOCIATION_CONFIRM_HREF})`, '已确认')
        .replace(`[确定](${ATTACHMENT_ASSOCIATION_CONFIRM_HREF})`, '已确定')
    }

    function resolveReviewPanelScope({
      reviewPayload = null,
      reviewAction = '',
      fileCount = 0,
      rawText = ''
    } = {}) {
      if (!reviewPayload || typeof reviewPayload !== 'object') {
        return ''
      }

      const normalizedAction = String(reviewAction || '').trim()
      const documentCount = Array.isArray(reviewPayload.document_cards) ? reviewPayload.document_cards.length : 0
      const riskCount = Array.isArray(reviewPayload.risk_briefs) ? reviewPayload.risk_briefs.length : 0
      const asksRisk = /风险|隐患|超标|异常|重复|待整改|风险项|高风险|中风险|低风险/.test(String(rawText || ''))

      if (fileCount > 0 && documentCount > 0) {
        return 'documents'
      }
      if (riskCount > 0 && (asksRisk || ['next_step', 'submit', 'submit_claim'].includes(normalizedAction))) {
        return 'risk'
      }
      if (!normalizedAction && fileCount === 0) {
        return 'overview'
      }
      return ''
    }

    async function confirmPendingAttachmentAssociation(message) {
      if (submitting.value || sessionSwitchBusy.value) return null

      const pending = message?.pendingAttachmentAssociation && typeof message.pendingAttachmentAssociation === 'object'
        ? message.pendingAttachmentAssociation
        : null
      const associationId = String(pending?.id || '').trim()
      if (!associationId || pending?.status === 'confirmed') {
        return null
      }

      const runtime = pendingAttachmentAssociations.get(associationId)
      if (!runtime || !Array.isArray(runtime.files) || !runtime.files.length) {
        toast('当前会话里没有可归集的附件原件，请重新上传票据后再确认。')
        return null
      }

      pending.status = 'confirmed'
      message.pendingAttachmentAssociation = pending
      message.text = buildConfirmedAssociationText(message)
      message.meta = ['已确认归集']
      persistSessionState()

      if (pending.mode === 'save_then_associate') {
        const inheritedReviewContext = buildReviewFormContextFromPayload(
          activeReviewPayload.value,
          reviewInlineForm.value
        )
        const savePayload = await submitComposer({
          rawText: '请先把当前已识别的报销信息保存为草稿，随后继续归集本次上传的附件。',
          userText: '',
          files: [],
          skipUserMessage: true,
          pendingText: '正在先保存未保存单据...',
          systemGenerated: true,
          extraContext: {
            ...runtime.extraContext,
            ...inheritedReviewContext,
            review_action: 'save_draft'
          }
        })
        const savedClaimId = String(savePayload?.result?.draft_payload?.claim_id || draftClaimId.value || '').trim()
        const savedClaimNo = String(savePayload?.result?.draft_payload?.claim_no || '').trim()
        if (!savedClaimId) {
          toast('当前单据还没有保存成功，请稍后重试。')
          return savePayload
        }

        return submitComposer({
          rawText: `确认将本次上传的 ${runtime.fileNames.length} 份票据归集到草稿 ${savedClaimNo || '当前草稿'}`,
          userText: `保存草稿并归集 ${runtime.fileNames.length} 份票据`,
          files: runtime.files,
          uploadDisposition: 'continue_existing',
          skipDraftAssociationPrompt: true,
          skipUserMessage: true,
          appendToCurrentFlow: true,
          systemGenerated: true,
          pendingText: savedClaimNo
            ? `草稿 ${savedClaimNo} 已保存，正在识别并归集附件...`
            : '草稿已保存，正在识别并归集附件...',
          associationConfirmed: true,
          extraContext: {
            ...runtime.extraContext,
            review_action: 'link_to_existing_draft',
            draft_claim_id: savedClaimId,
            selected_claim_id: savedClaimId,
            selected_claim_no: savedClaimNo,
            attachment_association_confirmed: true
          }
        })
      }

      return submitComposer({
        rawText: `确认将本次上传的 ${runtime.fileNames.length} 份票据归集到草稿 ${runtime.claimNo || '当前草稿'}`,
        userText: `确认归集到草稿 ${runtime.claimNo || '当前草稿'}`,
        files: runtime.files,
        uploadDisposition: 'continue_existing',
        skipDraftAssociationPrompt: true,
        pendingText: runtime.claimNo
          ? `正在将票据归集到草稿 ${runtime.claimNo}...`
          : '正在将票据归集到当前草稿...',
        associationConfirmed: true,
        recognizedAttachmentData: {
          ocrPayload: runtime.ocrPayload,
          ocrSummary: runtime.ocrSummary,
          ocrDocuments: runtime.ocrDocuments,
          ocrFilePreviews: runtime.ocrFilePreviews
        },
        extraContext: {
          ...runtime.extraContext,
          review_action: 'link_to_existing_draft',
          draft_claim_id: runtime.claimId,
          selected_claim_id: runtime.claimId,
          selected_claim_no: runtime.claimNo,
          attachment_association_confirmed: true
        }
      })
    }

  return {
    confirmPendingAttachmentAssociation,
    createPendingAttachmentAssociationId,
    emitSavedDraftRefresh,
    normalizeRecognizedAttachmentData,
    pendingAttachmentAssociations,
    promptUnlinkedReceiptFolderIfNeeded,
    resolveReviewPanelScope
  }
}
