import { computed, ref } from 'vue'

import {
  DATE_INPUT_FORMAT,
  REVIEW_CATEGORY_PRESET_OPTIONS,
  REVIEW_OTHER_CATEGORY_OPTIONS,
  REVIEW_SCENE_OTHER_OPTION,
  buildInlineReviewChangedLines,
  buildInlineReviewState,
  buildReviewCategoryOptions,
  buildReviewDocumentDrafts,
  buildReviewDocumentSummaries,
  buildReviewPanelConfidence,
  buildReviewRecognitionNotes,
  buildReviewRecognizedLines,
  cloneReviewDocumentDrafts,
  cloneReviewEditFields,
  createEmptyInlineReviewState,
  extractAmountInputValue,
  formatConfidenceLabel,
  isValidIsoDateString,
  normalizeAmountValue,
  normalizeReviewDocumentComparableValue,
  resolveReviewCategoryConfidenceScore
} from './travelReimbursementReviewModel.js'

export function useTravelReimbursementReviewDrawer({
  activeReviewPayload,
  activeReviewPanelScope,
  reviewFilePreviews,
  flowSteps,
  submitting,
  reviewActionBusy,
  triggerFileUpload,
  resolveDocumentPreview,
  buildReviewFactCards,
  buildReviewRiskItems,
  buildReviewRiskSummary,
  buildReviewIntentText,
  resolveReviewRiskBriefs,
  reviewDrawerMode: externalReviewDrawerMode,
  REVIEW_DRAWER_MODE_REVIEW,
  REVIEW_DRAWER_MODE_DOCUMENTS,
  REVIEW_DRAWER_MODE_RISK,
  REVIEW_DRAWER_MODE_FLOW
}) {
  const reviewInlineForm = ref(createEmptyInlineReviewState())
  const reviewInlineBaseForm = ref(createEmptyInlineReviewState())
  const reviewInlineBaseFields = ref([])
  const reviewInlinePendingFiles = ref([])
  const reviewInlineEditorKey = ref('')
  const reviewInlineErrors = ref({})
  const reviewOtherCategoryOpen = ref(false)
  const reviewDocumentDrafts = ref([])
  const reviewDocumentBaseDrafts = ref([])
  const activeReviewDocumentIndex = ref(0)
  const reviewDrawerMode = externalReviewDrawerMode || ref(REVIEW_DRAWER_MODE_REVIEW)
  const documentPreviewDialog = ref({
    open: false,
    filename: '',
    kind: 'file',
    url: '',
    renderKey: ''
  })

  const activeReviewFilePreviews = computed(() => reviewFilePreviews.value)
  const reviewIntentText = computed(() => buildReviewIntentText(activeReviewPayload.value))
  const reviewFactCards = computed(() => buildReviewFactCards(activeReviewPayload.value, reviewInlineForm.value))
  const reviewCategoryOptions = computed(() =>
    buildReviewCategoryOptions(activeReviewPayload.value, reviewInlineForm.value.expense_type, reviewInlineForm.value)
  )
  const reviewOtherCategoryOptions = computed(() =>
    REVIEW_OTHER_CATEGORY_OPTIONS.map((item) => ({
      ...item,
      confidenceLabel: formatConfidenceLabel(
        resolveReviewCategoryConfidenceScore(activeReviewPayload.value, item.label, reviewInlineForm.value)
      )
    }))
  )
  const reviewSelectedOtherCategory = computed(() => {
    const presetLabels = REVIEW_CATEGORY_PRESET_OPTIONS.filter((item) => !item.is_other).map((item) => item.label)
    return presetLabels.includes(reviewInlineForm.value.expense_type) ? '' : reviewInlineForm.value.expense_type
  })
  const reviewInlineDirty = computed(
    () =>
      buildInlineReviewChangedLines(
        reviewInlineBaseForm.value,
        reviewInlineForm.value,
        reviewInlinePendingFiles.value
      ).length > 0
  )
  const reviewPanelConfidence = computed(() => buildReviewPanelConfidence(activeReviewPayload.value, reviewInlineForm.value))
  const reviewRiskSummary = computed(() => buildReviewRiskSummary(activeReviewPayload.value))
  const reviewRiskItems = computed(() => buildReviewRiskItems(activeReviewPayload.value))
  const reviewRiskEmpty = computed(() => !reviewRiskItems.value.length)
  const reviewDocumentCount = computed(() => reviewDocumentDrafts.value.length)
  const normalizedReviewPanelScope = computed(() => {
    const scope = String(activeReviewPanelScope?.value || '').trim()
    return ['overview', 'documents', 'risk'].includes(scope) ? scope : ''
  })
  const reviewOverviewDrawerAvailable = computed(() => normalizedReviewPanelScope.value === 'overview')
  const reviewDocumentDrawerAvailable = computed(() => reviewDocumentCount.value > 0)
  const reviewRiskDrawerAvailable = computed(() => !reviewRiskEmpty.value)
  const reviewFlowDrawerAvailable = computed(() => flowSteps.value.length > 0)
  const recognizedNarratives = computed(() => buildReviewRecognizedLines(activeReviewPayload.value))
  const reviewRecognitionNotes = computed(() => buildReviewRecognitionNotes(activeReviewPayload.value))
  const reviewDocumentSummaries = computed(() => buildReviewDocumentSummaries(activeReviewPayload.value))
  const isReviewDocumentDrawer = computed(() => reviewDrawerMode.value === REVIEW_DRAWER_MODE_DOCUMENTS)
  const isReviewRiskDrawer = computed(() => reviewDrawerMode.value === REVIEW_DRAWER_MODE_RISK)
  const isReviewFlowDrawer = computed(() => reviewDrawerMode.value === REVIEW_DRAWER_MODE_FLOW)
  const reviewDrawerTitle = computed(() => (
    isReviewDocumentDrawer.value
      ? '票据识别结果'
      : isReviewRiskDrawer.value
        ? '风险提示'
        : isReviewFlowDrawer.value
          ? '执行流程'
          : '报销识别核对'
  ))
  const reviewDocumentDrawerLabel = computed(() => (
    '单据识别'
  ))
  const reviewDocumentDrawerIcon = computed(() => (
    isReviewDocumentDrawer.value
      ? 'mdi mdi-file-document-multiple'
      : 'mdi mdi-file-document-multiple-outline'
  ))
  const reviewRiskDrawerLabel = computed(() => (
    '显示风险'
  ))
  const reviewRiskDrawerIcon = computed(() => (
    isReviewRiskDrawer.value
      ? 'mdi mdi-shield-alert'
      : 'mdi mdi-shield-alert-outline'
  ))
  const reviewFlowDrawerLabel = computed(() => (
    '执行流程'
  ))
  const reviewFlowDrawerIcon = computed(() => (
    isReviewFlowDrawer.value
      ? 'mdi mdi-timeline-clock'
      : 'mdi mdi-timeline-clock-outline'
  ))
  const activeReviewDocument = computed(() => reviewDocumentDrafts.value[activeReviewDocumentIndex.value] ?? null)
  const activeReviewDocumentPreview = computed(() => {
    const document = activeReviewDocument.value
    if (!document) return null

    const matchedPreview = resolveDocumentPreview(activeReviewFilePreviews.value, document.filename)
    if (matchedPreview?.url) {
      return matchedPreview
    }

    const inlineUrl = String(document.preview_url || document.preview_data_url || '').trim()
    if (!inlineUrl) {
      return null
    }
    const explicitKind = String(document.preview_kind || '').trim()
    const inferredKind = inlineUrl.startsWith('data:image/') ? 'image' : explicitKind
    if (inferredKind !== 'image') {
      return null
    }

    return {
      filename: document.filename,
      kind: 'image',
      url: inlineUrl
    }
  })
  const canPreviewActiveReviewDocument = computed(() => Boolean(activeReviewDocumentPreview.value?.url))
  const reviewDocumentDirty = computed(() => {
    const baseValue = JSON.stringify(reviewDocumentBaseDrafts.value.map(normalizeReviewDocumentComparableValue))
    const nextValue = JSON.stringify(reviewDocumentDrafts.value.map(normalizeReviewDocumentComparableValue))
    return baseValue !== nextValue
  })
  const reviewHasUnsavedChanges = computed(() => reviewInlineDirty.value || reviewDocumentDirty.value)

  function resetReviewDrawerFromPayload(payload) {
    const normalizedInlineState = buildInlineReviewState(payload)
    reviewInlineForm.value = { ...normalizedInlineState }
    reviewInlineBaseForm.value = { ...normalizedInlineState }
    reviewInlineBaseFields.value = cloneReviewEditFields(payload?.edit_fields)
    const nextDocumentDrafts = buildReviewDocumentDrafts(payload)
    reviewDocumentDrafts.value = cloneReviewDocumentDrafts(nextDocumentDrafts)
    reviewDocumentBaseDrafts.value = cloneReviewDocumentDrafts(nextDocumentDrafts)
    activeReviewDocumentIndex.value = nextDocumentDrafts.length
      ? Math.min(activeReviewDocumentIndex.value, nextDocumentDrafts.length - 1)
      : 0
    const hasDocuments = nextDocumentDrafts.length > 0
    const hasRisks = resolveReviewRiskBriefs(payload).length > 0
    const scope = normalizedReviewPanelScope.value
    if (scope === 'documents' && hasDocuments) {
      reviewDrawerMode.value = REVIEW_DRAWER_MODE_DOCUMENTS
    } else if (scope === 'risk' && hasRisks) {
      reviewDrawerMode.value = REVIEW_DRAWER_MODE_RISK
    } else if (scope === 'overview') {
      reviewDrawerMode.value = REVIEW_DRAWER_MODE_REVIEW
    } else if (hasDocuments) {
      reviewDrawerMode.value = REVIEW_DRAWER_MODE_DOCUMENTS
    } else if (hasRisks) {
      reviewDrawerMode.value = REVIEW_DRAWER_MODE_RISK
    } else {
      reviewDrawerMode.value = REVIEW_DRAWER_MODE_REVIEW
    }
    reviewInlinePendingFiles.value = []
    reviewInlineEditorKey.value = ''
    reviewInlineErrors.value = {}
    reviewOtherCategoryOpen.value = false
  }

  function setInlineReviewFieldError(key, message) {
    reviewInlineErrors.value = {
      ...reviewInlineErrors.value,
      [key]: String(message || '').trim()
    }
  }

  function clearInlineReviewFieldError(key) {
    if (!reviewInlineErrors.value[key]) {
      return
    }

    const nextErrors = { ...reviewInlineErrors.value }
    delete nextErrors[key]
    reviewInlineErrors.value = nextErrors
  }

  function openInlineReviewEditor(key) {
    if (!activeReviewPayload.value || submitting.value || reviewActionBusy.value) return
    if (key === 'attachments') {
      triggerFileUpload('inline-review')
      return
    }

    if (reviewInlineEditorKey.value && reviewInlineEditorKey.value !== key && !commitInlineReviewEditor()) {
      return
    }

    if (reviewInlineEditorKey.value === key) {
      commitInlineReviewEditor()
      return
    }

    if (key === 'amount') {
      reviewInlineForm.value = {
        ...reviewInlineForm.value,
        amount: extractAmountInputValue(reviewInlineForm.value.amount)
      }
    }

    clearInlineReviewFieldError(key)
    reviewInlineEditorKey.value = key
    if (key !== 'expense_type') {
      reviewOtherCategoryOpen.value = false
    }
  }

  function closeInlineReviewEditor() {
    reviewInlineEditorKey.value = ''
    reviewOtherCategoryOpen.value = false
  }

  function commitInlineReviewEditor() {
    const activeEditorKey = reviewInlineEditorKey.value
    const nextForm = {
      ...reviewInlineForm.value,
      occurred_date: String(reviewInlineForm.value.occurred_date || '').trim(),
      amount: String(reviewInlineForm.value.amount || '').trim(),
      transport_type: String(reviewInlineForm.value.transport_type || '').trim(),
      customer_name: String(reviewInlineForm.value.customer_name || '').trim(),
      location: String(reviewInlineForm.value.location || '').trim(),
      merchant_name: String(reviewInlineForm.value.merchant_name || '').trim(),
      participants: String(reviewInlineForm.value.participants || '').trim(),
      scene_label: String(reviewInlineForm.value.scene_label || '').trim(),
      reason_value: String(reviewInlineForm.value.reason_value || reviewInlineForm.value.scene_label || '').trim(),
      expense_type: String(reviewInlineForm.value.expense_type || '').trim()
    }

    if (
      activeEditorKey === 'scene' &&
      nextForm.scene_label === REVIEW_SCENE_OTHER_OPTION
    ) {
      nextForm.reason_value = String(reviewInlineForm.value.reason_value || '').trim()
      if (!nextForm.reason_value) {
        setInlineReviewFieldError('scene', '请选择“其他场景”后，请补充具体事由')
        reviewInlineForm.value = nextForm
        return false
      }
    } else if (activeEditorKey === 'scene') {
      nextForm.reason_value = nextForm.scene_label
    }

    if (activeEditorKey === 'occurred_date' && nextForm.occurred_date && !isValidIsoDateString(nextForm.occurred_date)) {
      setInlineReviewFieldError('occurred_date', `请输入正确的时间格式：${DATE_INPUT_FORMAT}`)
      return false
    }

    if (activeEditorKey === 'amount' && nextForm.amount) {
      const normalizedAmount = normalizeAmountValue(nextForm.amount)
      if (!normalizedAmount) {
        setInlineReviewFieldError('amount', '请输入正确的数字金额，例如 200 或 200.50')
        return false
      }
      nextForm.amount = normalizedAmount
    }

    if (activeEditorKey) {
      clearInlineReviewFieldError(activeEditorKey)
    }

    reviewInlineForm.value = nextForm
    reviewInlineEditorKey.value = ''
    return true
  }

  function selectInlineScene(scene) {
    const normalizedScene = String(scene || '').trim()
    reviewInlineForm.value = {
      ...reviewInlineForm.value,
      scene_label: normalizedScene,
      reason_value:
        normalizedScene === REVIEW_SCENE_OTHER_OPTION
          ? ''
          : normalizedScene
    }
    clearInlineReviewFieldError('scene')
    if (normalizedScene !== REVIEW_SCENE_OTHER_OPTION) {
      reviewInlineEditorKey.value = ''
    }
  }

  function selectReviewCategory(option) {
    if (!option) return
    if (option.is_other) {
      reviewOtherCategoryOpen.value = !reviewOtherCategoryOpen.value
      return
    }

    reviewInlineForm.value = {
      ...reviewInlineForm.value,
      expense_type: option.label
    }
    reviewOtherCategoryOpen.value = false
  }

  function selectReviewOtherCategory(option) {
    if (!option) return
    reviewInlineForm.value = {
      ...reviewInlineForm.value,
      expense_type: option.label
    }
    reviewOtherCategoryOpen.value = false
  }

  function goReviewDocument(direction) {
    const total = reviewDocumentCount.value
    if (!total) return
    const nextIndex = activeReviewDocumentIndex.value + Number(direction || 0)
    activeReviewDocumentIndex.value = Math.max(0, Math.min(total - 1, nextIndex))
  }

  function openActiveReviewDocumentPreview() {
    if (!activeReviewDocument.value || !activeReviewDocumentPreview.value?.url) return
    documentPreviewDialog.value = {
      open: true,
      filename: activeReviewDocument.value.filename,
      kind: activeReviewDocumentPreview.value.kind,
      url: activeReviewDocumentPreview.value.url,
      renderKey: [
        activeReviewDocument.value.filename,
        activeReviewDocumentPreview.value.kind,
        Date.now()
      ].join('__')
    }
  }

  function closeDocumentPreview() {
    documentPreviewDialog.value = {
      ...documentPreviewDialog.value,
      open: false
    }
  }

  function enforceReviewDrawerAvailability() {
    if (!reviewOverviewDrawerAvailable.value && reviewDrawerMode.value === REVIEW_DRAWER_MODE_REVIEW) {
      if (reviewDocumentDrawerAvailable.value) {
        reviewDrawerMode.value = REVIEW_DRAWER_MODE_DOCUMENTS
      } else if (reviewRiskDrawerAvailable.value) {
        reviewDrawerMode.value = REVIEW_DRAWER_MODE_RISK
      }
    }
    if (!reviewDocumentDrawerAvailable.value && reviewDrawerMode.value === REVIEW_DRAWER_MODE_DOCUMENTS) {
      reviewDrawerMode.value = reviewOverviewDrawerAvailable.value
        ? REVIEW_DRAWER_MODE_REVIEW
        : REVIEW_DRAWER_MODE_RISK
    }
    if (!reviewRiskDrawerAvailable.value && reviewDrawerMode.value === REVIEW_DRAWER_MODE_RISK) {
      reviewDrawerMode.value = reviewOverviewDrawerAvailable.value
        ? REVIEW_DRAWER_MODE_REVIEW
        : REVIEW_DRAWER_MODE_DOCUMENTS
    }
    if (!reviewFlowDrawerAvailable.value && reviewDrawerMode.value === REVIEW_DRAWER_MODE_FLOW) {
      reviewDrawerMode.value = reviewOverviewDrawerAvailable.value
        ? REVIEW_DRAWER_MODE_REVIEW
        : (reviewDocumentDrawerAvailable.value ? REVIEW_DRAWER_MODE_DOCUMENTS : REVIEW_DRAWER_MODE_RISK)
    }
  }

  return {
    reviewInlineForm,
    reviewInlineBaseForm,
    reviewInlineBaseFields,
    reviewInlinePendingFiles,
    reviewInlineEditorKey,
    reviewInlineErrors,
    reviewOtherCategoryOpen,
    reviewDocumentDrafts,
    reviewDocumentBaseDrafts,
    activeReviewDocumentIndex,
    reviewDrawerMode,
    documentPreviewDialog,
    activeReviewFilePreviews,
    reviewIntentText,
    reviewFactCards,
    reviewCategoryOptions,
    reviewOtherCategoryOptions,
    reviewSelectedOtherCategory,
    reviewInlineDirty,
    reviewPanelConfidence,
    reviewRiskSummary,
    reviewRiskItems,
    reviewRiskEmpty,
    reviewDocumentDrawerAvailable,
    reviewRiskDrawerAvailable,
    reviewFlowDrawerAvailable,
    recognizedNarratives,
    reviewRecognitionNotes,
    reviewDocumentSummaries,
    reviewDocumentCount,
    reviewOverviewDrawerAvailable,
    isReviewDocumentDrawer,
    isReviewRiskDrawer,
    isReviewFlowDrawer,
    reviewDrawerTitle,
    reviewDocumentDrawerLabel,
    reviewDocumentDrawerIcon,
    reviewRiskDrawerLabel,
    reviewRiskDrawerIcon,
    reviewFlowDrawerLabel,
    reviewFlowDrawerIcon,
    activeReviewDocument,
    activeReviewDocumentPreview,
    canPreviewActiveReviewDocument,
    reviewDocumentDirty,
    reviewHasUnsavedChanges,
    setInlineReviewFieldError,
    clearInlineReviewFieldError,
    resetReviewDrawerFromPayload,
    openInlineReviewEditor,
    closeInlineReviewEditor,
    commitInlineReviewEditor,
    selectInlineScene,
    selectReviewCategory,
    selectReviewOtherCategory,
    goReviewDocument,
    openActiveReviewDocumentPreview,
    closeDocumentPreview,
    enforceReviewDrawerAvailability
  }
}
