import { onScopeDispose, ref, unref, watch } from 'vue'

import { fetchExpenseCaseTimeline } from '../../services/expenseCases.js'
import {
  buildExpenseCaseTimelineViewModel,
  isExpenseCaseNotAvailableError
} from '../../utils/expenseCaseTimeline.js'

export function useExpenseCaseTimeline({
  claimId,
  refreshKey,
  fetchTimeline = fetchExpenseCaseTimeline
}) {
  const timeline = ref(null)
  const loading = ref(false)
  const errorMessage = ref('')
  const notAvailable = ref(false)
  let loadSequence = 0
  let disposed = false

  function resetTimelineState() {
    timeline.value = null
    loading.value = false
    errorMessage.value = ''
    notAvailable.value = false
  }

  async function loadTimeline() {
    const normalizedClaimId = String(unref(claimId) || '').trim()
    const sequence = ++loadSequence

    if (!normalizedClaimId) {
      resetTimelineState()
      return
    }

    timeline.value = null
    loading.value = true
    errorMessage.value = ''
    notAvailable.value = false

    try {
      const payload = await fetchTimeline(normalizedClaimId, {
        timeoutMs: 10000,
        timeoutMessage: '费用事件加载超时，请稍后重试。'
      })
      if (disposed || sequence !== loadSequence) {
        return
      }
      timeline.value = buildExpenseCaseTimelineViewModel(payload || {})
    } catch (error) {
      if (disposed || sequence !== loadSequence) {
        return
      }

      timeline.value = null
      if (isExpenseCaseNotAvailableError(error)) {
        notAvailable.value = true
        return
      }

      errorMessage.value = '费用事件暂时加载失败，上方进度与单据操作不受影响。'
    } finally {
      if (!disposed && sequence === loadSequence) {
        loading.value = false
      }
    }
  }

  watch(
    [
      () => String(unref(claimId) || '').trim(),
      () => String(unref(refreshKey) || '')
    ],
    loadTimeline,
    { immediate: true }
  )

  onScopeDispose(() => {
    disposed = true
    loadSequence += 1
  })

  return {
    timeline,
    loading,
    errorMessage,
    notAvailable,
    refreshExpenseCaseTimeline: loadTimeline
  }
}
