import { nextTick, onBeforeUnmount, onMounted, watch } from 'vue'
import {
  buildLocalApplicationPreviewMessage,
  normalizeApplicationPreview
} from '../../utils/expenseApplicationPreview.js'
import {
  MAX_ATTACHMENTS,
  VISIBLE_ATTACHMENT_CHIPS,
  buildReviewFilePreviewsFromReviewPayload
} from './travelReimbursementAttachmentModel.js'
import {
  SESSION_TYPE_EXPENSE,
  createMessage,
  buildWelcomeInsight
} from './travelReimbursementConversationModel.js'

export function useTravelReimbursementCreateViewLifecycle({
  activeFlowSteps,
  activeReviewPanelScope,
  activeReviewPayload,
  activeSessionType,
  adjustComposerTextareaHeight,
  attachedFiles,
  clearExpenseSessionForDeletedClaim,
  clearStewardThinkingTimers,
  closeAfterBusy,
  composerDraft,
  composerFilesExpanded,
  composerUploadIntent,
  conversationId,
  currentInsight,
  currentUser,
  draftClaimId,
  guidedFlowState,
  handleComposerDatePickerOutside,
  hasInsightPanelContent,
  insightPanelCollapsed,
  linkedRequest,
  maybeFinalizeDeferredClose,
  mergeFilesWithLimit,
  messages,
  persistSessionState,
  props,
  rememberFilePreviews,
  resetReviewDrawerFromPayload,
  resolveActiveClaimId,
  restorePersistedDraftAttachmentPreviews,
  reviewActionBusy,
  reviewDocumentDrawerAvailable,
  reviewDrawerMode,
  reviewFilePreviews,
  reviewFlowDrawerAvailable,
  reviewRiskDrawerAvailable,
  scrollToBottom,
  startFlowTick,
  stewardState,
  stopAttachmentRuntime,
  stopFlowRuntime,
  submitComposer,
  submitting,
  sessionSwitchBusy,
  toast,
  workbenchVisible,
  REVIEW_DRAWER_MODE_DOCUMENTS,
  REVIEW_DRAWER_MODE_FLOW,
  REVIEW_DRAWER_MODE_REVIEW,
  REVIEW_DRAWER_MODE_RISK,
  SESSION_TYPE_EXPENSE: sessionTypeExpense = SESSION_TYPE_EXPENSE
}) {
  watch(
    () => [activeReviewPayload.value, activeReviewPanelScope.value],
    ([payload]) => {
      rememberFilePreviews(buildReviewFilePreviewsFromReviewPayload(payload))
      const shouldKeepFlowDrawer = reviewDrawerMode.value === REVIEW_DRAWER_MODE_FLOW && activeFlowSteps.value.length > 0
      resetReviewDrawerFromPayload(payload)
      if (shouldKeepFlowDrawer) {
        reviewDrawerMode.value = REVIEW_DRAWER_MODE_FLOW
      }
    },
    { immediate: true }
  )

  watch(
    () => hasInsightPanelContent.value,
    (available) => {
      if (!available) {
        insightPanelCollapsed.value = false
      }
    }
  )

  watch(
    () => reviewDocumentDrawerAvailable.value,
    (available) => {
      if (!available && reviewDrawerMode.value === REVIEW_DRAWER_MODE_DOCUMENTS) {
        reviewDrawerMode.value = REVIEW_DRAWER_MODE_REVIEW
      }
    }
  )

  watch(
    () => reviewRiskDrawerAvailable.value,
    (available) => {
      if (!available && reviewDrawerMode.value === REVIEW_DRAWER_MODE_RISK) {
        reviewDrawerMode.value = REVIEW_DRAWER_MODE_REVIEW
      }
    }
  )

  watch(
    () => reviewFlowDrawerAvailable.value,
    (available) => {
      if (!available && reviewDrawerMode.value === REVIEW_DRAWER_MODE_FLOW) {
        reviewDrawerMode.value = REVIEW_DRAWER_MODE_REVIEW
      }
    }
  )

  watch(
    () => [activeSessionType.value, activeFlowSteps.value.length],
    ([, activeCount], [, previousActiveCount] = []) => {
      if (activeCount <= 0 || previousActiveCount > 0) {
        return
      }
      reviewDrawerMode.value = REVIEW_DRAWER_MODE_FLOW
      insightPanelCollapsed.value = false
    }
  )

  watch(
    () => composerDraft.value,
    () => {
      nextTick(adjustComposerTextareaHeight)
    }
  )

  watch(
    () => ({
      sessionType: activeSessionType.value,
      conversationId: conversationId.value,
      stewardState: stewardState.value,
      draftClaimId: draftClaimId.value,
      messages: messages.value,
      currentInsight: currentInsight.value,
      reviewFilePreviews: reviewFilePreviews.value,
      composerDraft: composerDraft.value,
      composerUploadIntent: composerUploadIntent.value,
      guidedFlowState: guidedFlowState.value,
      insightPanelCollapsed: insightPanelCollapsed.value
    }),
    () => {
      persistSessionState()
    },
    { deep: true }
  )

  watch(
    () => [activeSessionType.value, resolveActiveClaimId()],
    ([sessionType, claimId]) => {
      if (sessionType !== sessionTypeExpense || !claimId) {
        return
      }
      void restorePersistedDraftAttachmentPreviews(claimId)
    },
    { immediate: true }
  )

  watch(
    () => props.invalidatedDraftClaimId,
    (claimId) => {
      clearExpenseSessionForDeletedClaim(claimId)
    },
    { immediate: true }
  )

  watch(
    () => workbenchVisible.value,
    (visible) => {
      if (visible) {
        scrollToBottom()
      } else {
        maybeFinalizeDeferredClose()
      }
    }
  )

  watch(
    () => [submitting.value, reviewActionBusy.value, sessionSwitchBusy.value, workbenchVisible.value],
    () => {
      maybeFinalizeDeferredClose()
    }
  )

  watch(
    () => props.reopenToken,
    (token, previousToken) => {
      if (token === previousToken) {
        return
      }
      closeAfterBusy.value = false
      workbenchVisible.value = true
      nextTick(() => {
        adjustComposerTextareaHeight()
        scrollToBottom()
      })
    }
  )

  onMounted(() => {
    document.addEventListener('click', handleComposerDatePickerOutside)
    startFlowTick()
    nextTick(() => {
      workbenchVisible.value = true
      nextTick(() => {
        adjustComposerTextareaHeight()
        scrollToBottom()
      })
    })
    currentInsight.value =
      currentInsight.value
      || buildWelcomeInsight(props.entrySource, linkedRequest.value, activeSessionType.value, currentUser.value)
    if (props.initialApplicationPreview && typeof props.initialApplicationPreview === 'object') {
      const applicationPreview = normalizeApplicationPreview(props.initialApplicationPreview)
      const draftPayload = props.initialDraftPayload && typeof props.initialDraftPayload === 'object'
        ? props.initialDraftPayload
        : null
      messages.value.push(createMessage('assistant', buildLocalApplicationPreviewMessage(applicationPreview), [], {
        meta: ['修改申请'],
        applicationPreview,
        draftPayload
      }))
      persistSessionState()
    }
    if (props.initialPrompt?.trim() || props.initialFiles.length) {
      const initialMerge = mergeFilesWithLimit([], Array.from(props.initialFiles), MAX_ATTACHMENTS)
      composerDraft.value = props.initialPrompt.trim()
      attachedFiles.value = initialMerge.files
      composerFilesExpanded.value = initialMerge.files.length > VISIBLE_ATTACHMENT_CHIPS
      if (initialMerge.overflowCount > 0) {
        toast(`一次最多上传 ${MAX_ATTACHMENTS} 份附件，已保留前 ${MAX_ATTACHMENTS} 份。`)
      }
      nextTick(() => {
        adjustComposerTextareaHeight()
      })
      if (props.initialPromptAutoSubmit !== false) {
        submitComposer()
      }
    }
  })

  onBeforeUnmount(() => {
    document.removeEventListener('click', handleComposerDatePickerOutside)
    clearStewardThinkingTimers()
    stopFlowRuntime()
    stopAttachmentRuntime()
  })
}
