'use client'

import type { PluginDetail } from '../../../types'
import type { ModalStates, VersionTarget } from './use-detail-header-state'
import { toast } from '@langgenius/dify-ui/toast'
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { trackEvent } from '@/app/components/base/amplitude'
import useRefreshPluginList from '@/app/components/plugins/install-plugin/hooks/use-refresh-plugin-list'
import { useModalContext } from '@/context/modal-context'
import { uninstallPlugin } from '@/service/plugins'
import { useInvalidateCheckInstalled } from '@/service/use-plugins'
import { checkForUpdates, fetchReleases } from '../../../install-plugin/hooks'
import { PluginSource } from '../../../types'

type UsePluginOperationsParams = {
  canDeletePlugin?: boolean
  canUpdatePlugin?: boolean
  detail: PluginDetail
  modalStates: ModalStates
  versionPicker: {
    setTargetVersion: (version: VersionTarget) => void
    setIsDowngrade: (downgrade: boolean) => void
  }
  isFromMarketplace: boolean
  onUpdate?: (isDelete?: boolean) => void
}

type UsePluginOperationsReturn = {
  handleUpdate: (isDowngrade?: boolean) => Promise<void>
  handleUpdatedFromMarketplace: () => void
  handleDelete: () => Promise<void>
}

export const usePluginOperations = ({
  canDeletePlugin = true,
  canUpdatePlugin = true,
  detail,
  modalStates,
  versionPicker,
  isFromMarketplace,
  onUpdate,
}: UsePluginOperationsParams): UsePluginOperationsReturn => {
  const { t } = useTranslation()
  const { setShowUpdatePluginModal } = useModalContext()
  const { refreshPluginList } = useRefreshPluginList()
  const invalidateCheckInstalled = useInvalidateCheckInstalled()

  const { id, meta, plugin_id } = detail
  const { author, category, name } = detail.declaration || detail
  const handlePluginUpdated = useCallback(
    (isDelete?: boolean) => {
      invalidateCheckInstalled()
      onUpdate?.(isDelete)
    },
    [invalidateCheckInstalled, onUpdate],
  )

  const handleUpdate = useCallback(
    async (isDowngrade?: boolean) => {
      if (!canUpdatePlugin) return

      if (isFromMarketplace) {
        versionPicker.setIsDowngrade(!!isDowngrade)
        modalStates.showUpdateModal()
        return
      }

      if (!meta?.repo || !meta?.version || !meta?.package) {
        toast.error('Missing plugin metadata for GitHub update')
        return
      }

      const owner = meta.repo.split('/')[0] || author
      const repo = meta.repo.split('/')[1] || name
      const fetchedReleases = await fetchReleases(owner, repo)
      if (fetchedReleases.length === 0) return

      const { needUpdate, toastProps } = checkForUpdates(fetchedReleases, meta.version)
      toast(toastProps.message, { type: toastProps.type })

      if (needUpdate) {
        setShowUpdatePluginModal({
          onSaveCallback: () => {
            handlePluginUpdated()
          },
          payload: {
            type: PluginSource.github,
            category,
            github: {
              originalPackageInfo: {
                id: detail.plugin_unique_identifier,
                repo: meta.repo,
                version: meta.version,
                package: meta.package,
                releases: fetchedReleases,
              },
            },
          },
        })
      }
    },
    [
      canUpdatePlugin,
      isFromMarketplace,
      meta,
      author,
      name,
      setShowUpdatePluginModal,
      detail,
      handlePluginUpdated,
      modalStates,
      versionPicker,
    ],
  )

  const handleUpdatedFromMarketplace = useCallback(() => {
    handlePluginUpdated()
    modalStates.hideUpdateModal()
  }, [handlePluginUpdated, modalStates])

  const handleDelete = useCallback(async () => {
    if (!canDeletePlugin) return

    modalStates.showDeleting()
    const res = await uninstallPlugin(id)
    modalStates.hideDeleting()

    if (res.success) {
      modalStates.hideDeleteConfirm()
      toast.success(t(($) => $['action.deleteSuccess'], { ns: 'plugin' }))
      handlePluginUpdated(true)
      refreshPluginList({ category })

      trackEvent('plugin_uninstalled', { plugin_id, plugin_name: name })
    }
  }, [
    canDeletePlugin,
    id,
    category,
    plugin_id,
    name,
    modalStates,
    handlePluginUpdated,
    refreshPluginList,
  ])

  return {
    handleUpdate,
    handleUpdatedFromMarketplace,
    handleDelete,
  }
}
