import { Button } from '@langgenius/dify-ui/button'
import { cn } from '@langgenius/dify-ui/cn'
import { toast } from '@langgenius/dify-ui/toast'
import { RiHistoryLine } from '@remixicon/react'
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'
import { useAtomValue } from 'jotai'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { PlanUpgradeModal } from '@/app/components/billing/plan-upgrade-modal'
import { getWorkflowVersionName } from '@/app/components/workflow/utils/version'
import { userProfileQueryOptions } from '@/features/account-profile/client'
import { deploymentEditionAtom } from '@/features/system-features/state'
import useTheme from '@/hooks/use-theme'
import { consoleQuery } from '@/service/client'
import {
  useInvalidAllLastRun,
  useResetWorkflowVersionHistory,
  useRestoreWorkflow,
} from '@/service/use-workflow'
import { FlowType } from '@/types/common'
import { useHooksStore } from '../hooks-store'
import { useWorkflowRefreshDraft } from '../hooks/use-workflow-refresh-draft'
import { useWorkflowRun } from '../hooks/use-workflow-run'
import { useStore, useWorkflowStore } from '../store'
import { WorkflowVersion } from '../types'
import RestoringTitle from './restoring-title'

export type HeaderInRestoringProps = {
  onRestoreSettled?: () => void
}
const HeaderInRestoring = ({ onRestoreSettled }: HeaderInRestoringProps) => {
  const { t } = useTranslation()
  const { theme } = useTheme()
  const [isRestorePlanUpgradeModalOpen, setIsRestorePlanUpgradeModalOpen] = useState(false)
  const deploymentEdition = useAtomValue(deploymentEditionAtom)
  const { data: plan } = useQuery(
    consoleQuery.features.get.queryOptions({
      enabled: deploymentEdition === 'CLOUD',
      select: (data) => data.billing.subscription.plan,
    }),
  )
  const workflowStore = useWorkflowStore()
  const { data: userProfile } = useSuspenseQuery({
    ...userProfileQueryOptions(),
    select: (data) => data.profile,
  })
  const configsMap = useHooksStore((s) => s.configsMap)
  const invalidAllLastRun = useInvalidAllLastRun(configsMap?.flowType, configsMap?.flowId)
  const { deleteAllInspectVars } = workflowStore.getState()
  const currentVersion = useStore((s) => s.currentVersion)
  const setShowWorkflowVersionHistoryPanel = useStore((s) => s.setShowWorkflowVersionHistoryPanel)

  const { handleLoadBackupDraft } = useWorkflowRun()
  const { handleRefreshWorkflowDraft } = useWorkflowRefreshDraft()
  const { mutateAsync: restoreWorkflow } = useRestoreWorkflow()
  const resetWorkflowVersionHistory = useResetWorkflowVersionHistory()
  const canRestore =
    !!currentVersion?.id && !!configsMap?.flowId && currentVersion.version !== WorkflowVersion.Draft
  const isPlanUnavailable = deploymentEdition === 'CLOUD' && plan === undefined
  const canEmitCollaborationEvents = configsMap?.flowType === FlowType.appFlow

  const handleCancelRestore = useCallback(() => {
    handleLoadBackupDraft()
    workflowStore.setState({ isRestoring: false })
    setShowWorkflowVersionHistoryPanel(false)
  }, [workflowStore, handleLoadBackupDraft, setShowWorkflowVersionHistoryPanel])

  const restoreVersionUrl = useCallback(
    (versionId: string) => {
      if (!configsMap?.flowId) return ''
      if (configsMap.flowType === FlowType.ragPipeline)
        return `/rag/pipelines/${configsMap.flowId}/workflows/${versionId}/restore`
      if (configsMap.flowType === FlowType.snippet)
        return `/snippets/${configsMap.flowId}/workflows/${versionId}/restore`
      return `/apps/${configsMap.flowId}/workflows/${versionId}/restore`
    },
    [configsMap?.flowId, configsMap?.flowType],
  )

  const emitRestoreIntent = useCallback(async () => {
    if (!currentVersion || !canEmitCollaborationEvents) return
    try {
      const { collaborationManager } = await import('../collaboration/core/collaboration-manager')
      collaborationManager.emitRestoreIntent({
        versionId: currentVersion.id,
        versionName: getWorkflowVersionName(
          currentVersion,
          t(($) => $['versionHistory.defaultName'], { ns: 'workflow' }),
        ),
        initiatorUserId: userProfile.id,
        initiatorName: userProfile.name,
      })
    } catch (error) {
      console.error('Failed to emit restore intent:', error)
    }
  }, [canEmitCollaborationEvents, currentVersion, t, userProfile.id, userProfile.name])

  const emitRestoreComplete = useCallback(
    async (success: boolean, errorMessage?: string) => {
      if (!currentVersion || !canEmitCollaborationEvents) return
      try {
        const { collaborationManager } = await import('../collaboration/core/collaboration-manager')
        collaborationManager.emitRestoreComplete({
          versionId: currentVersion.id,
          success,
          ...(errorMessage ? { error: errorMessage } : {}),
        })
      } catch (error) {
        console.error('Failed to emit restore complete:', error)
      }
    },
    [canEmitCollaborationEvents, currentVersion],
  )

  const emitWorkflowUpdate = useCallback(async () => {
    if (!configsMap?.flowId || !canEmitCollaborationEvents) return
    try {
      const { collaborationManager } = await import('../collaboration/core/collaboration-manager')
      collaborationManager.emitWorkflowUpdate(configsMap.flowId)
    } catch (error) {
      console.error('Failed to emit workflow update:', error)
    }
  }, [canEmitCollaborationEvents, configsMap?.flowId])

  const handleRestore = useCallback(async () => {
    if (isPlanUnavailable || !canRestore || !currentVersion) return

    if (deploymentEdition === 'CLOUD' && plan === 'sandbox') {
      setIsRestorePlanUpgradeModalOpen(true)
      return
    }

    setShowWorkflowVersionHistoryPanel(false)
    await emitRestoreIntent()

    try {
      await restoreWorkflow(restoreVersionUrl(currentVersion.id))
      workflowStore.setState({ isRestoring: false })
      workflowStore.setState({ backupDraft: undefined })
      handleRefreshWorkflowDraft()
      toast.success(t(($) => $['versionHistory.action.restoreSuccess'], { ns: 'workflow' }))
      deleteAllInspectVars()
      invalidAllLastRun()
      await emitRestoreComplete(true)
      await emitWorkflowUpdate()
    } catch {
      toast.error(t(($) => $['versionHistory.action.restoreFailure'], { ns: 'workflow' }))
      await emitRestoreComplete(false, 'restore failed')
    } finally {
      resetWorkflowVersionHistory()
      onRestoreSettled?.()
    }
  }, [
    isPlanUnavailable,
    canRestore,
    currentVersion,
    deploymentEdition,
    plan,
    setShowWorkflowVersionHistoryPanel,
    emitRestoreIntent,
    restoreWorkflow,
    restoreVersionUrl,
    workflowStore,
    handleRefreshWorkflowDraft,
    t,
    deleteAllInspectVars,
    invalidAllLastRun,
    emitRestoreComplete,
    emitWorkflowUpdate,
    resetWorkflowVersionHistory,
    onRestoreSettled,
  ])

  return (
    <>
      <div>
        <RestoringTitle />
      </div>
      <div className="flex items-center justify-end gap-x-2">
        <Button
          onClick={handleRestore}
          disabled={isPlanUnavailable || !canRestore}
          variant="primary"
          className={cn(
            'rounded-lg inset-ring-1 inset-ring-transparent',
            theme === 'dark' && 'bg-white/10 inset-ring-black/5 backdrop-blur-xs',
          )}
        >
          {t(($) => $['common.restore'], { ns: 'workflow' })}
        </Button>
        <Button
          onClick={handleCancelRestore}
          className={cn(
            'rounded-lg text-components-button-secondary-accent-text inset-ring-1 inset-ring-transparent',
            theme === 'dark' && 'bg-white/10 inset-ring-black/5 backdrop-blur-xs',
          )}
        >
          <div className="flex items-center gap-x-0.5">
            <RiHistoryLine className="size-4" />
            <span className="px-0.5">{t(($) => $['common.exitVersions'], { ns: 'workflow' })}</span>
          </div>
        </Button>
      </div>
      {isRestorePlanUpgradeModalOpen && (
        <PlanUpgradeModal
          show
          onClose={() => setIsRestorePlanUpgradeModalOpen(false)}
          title={t(($) => $['upgrade.workflowRestore.title'], { ns: 'billing' })!}
          description={t(($) => $['upgrade.workflowRestore.description'], { ns: 'billing' })!}
        />
      )}
    </>
  )
}

export default HeaderInRestoring
